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 extends IDMContext> fDMCClassType;
+
+ /**
+ * Constructor initializes instance data, except for the child nodes.
+ * Child nodes must be initialized by calling setChildNodes()
+ * @param session
+ * @param dmcClassType
+ * @see #setChildNodes(IVMLayoutNode[])
+ */
+ public DMContextVMLayoutNode(DsfSession session, Class extends IDMContext> dmcClassType) {
+ super(session.getExecutor());
+ fServices = new DsfServicesTracker(DsfUIPlugin.getBundleContext(), session.getId());
+ fDMCClassType = dmcClassType;
+ }
+
+
+
+ /**
+ * Returns the services tracker for sub-class use.
+ */
+ protected DsfServicesTracker getServicesTracker() {
+ return fServices;
+ }
+
+ @Override
+ public boolean hasDeltaFlags(Object e) {
+ if (e instanceof IDMEvent) {
+ return hasDeltaFlagsForDMEvent((IDMEvent)e);
+ } else {
+ return super.hasDeltaFlags(e);
+ }
+ }
+
+ /**
+ * DMC-specific version of {@link IVMLayoutNode#hasDeltaFlags(Object)}.
+ * By default, it falls back on the super-class implementation.
+ */
+ protected boolean hasDeltaFlagsForDMEvent(IDMEvent e) {
+ return super.hasDeltaFlags(e);
+ }
+
+ @Override
+ public void buildDelta(Object e, VMDelta parent, Done done) {
+ if (e instanceof IDMEvent) {
+ buildDeltaForDMEvent((IDMEvent)e, parent, done);
+ } else {
+ super.buildDelta(e, parent, done);
+ }
+ }
+
+ /**
+ * Adds an optimization (over the AbstractViewModelLayoutNode) which
+ * narrows down the list of children based on the DMC within the event.
+ */
+ public void buildDeltaForDMEvent(final IDMEvent e, final VMDelta parent, final Done done) {
+ /*
+ * Take the IDMContext (DMC) that the event is based on, and
+ * search its ancestors. Look for the DMC class typs that this schema
+ * node is based on. If its found, then only one IModelDelta needs to
+ * be generated for this schema node. Otherwise, resort to the default
+ * behavior and generate a IModelDelta for every element in this schema
+ * node.
+ */
+ IDMContext dmc = DMContexts.getAncestorOfType(e.getDMContext(), fDMCClassType);
+ if (dmc != null) {
+ IVMLayoutNode[] childNodes = getChildNodesWithDeltas(e);
+ if (childNodes.length == 0) {
+ // There are no child nodes with deltas, just return to parent.
+ getExecutor().execute(done);
+ return;
+ }
+
+ /*
+ * This execution for this node is not done until all the child nodes
+ * are done. Use the tracker to wait for all children to complete.
+ */
+ DoneCollector childDoneTracker = new DoneCollector(getExecutor()) {
+ public void run() {
+ getExecutor().execute(done);
+ }
+ };
+ for (final IVMLayoutNode childNode : getChildLayoutNodes()) {
+ /*
+ * Create a delta corresponding to the DMC from the event and pass
+ * it as parent VMC to the child node. The child node will build
+ * its delta on top of this delta.
+ */
+ childNode.buildDelta(
+ e,
+ parent.addNode(new DMContextVMContext(parent.getVMC(), dmc), IModelDelta.NO_CHANGE),
+ childDoneTracker.addNoActionDone());
+ }
+ } else {
+ super.buildDelta(e, parent, done);
+ }
+ }
+
+ /**
+ * Utility method that takes an array of DMC object and creates a
+ * corresponding array of IVMContext elements base on that.
+ * @param parent The parent for generated IVMContext elements.
+ * @param dmcs Array of DMC objects to build return array on.
+ * @return Array of IVMContext objects.
+ */
+ protected IVMContext[] dmcs2vmcs(IVMContext parent, IDMContext[] dmcs) {
+ IVMContext[] vmContexts = new IVMContext[dmcs.length];
+ for (int i = 0; i < dmcs.length; i++) {
+ vmContexts[i] = new DMContextVMContext(parent, dmcs[i]);
+ }
+ return vmContexts;
+ }
+
+ /**
+ * Searches for a DMC of given type in the tree patch contained in given
+ * VMC. VMCs keep a reference to the parent node that contain them in the
+ * tree. This method recursively looks compares the parent until root is
+ * reached, or the DMC is found. If the root is reached, and the root's
+ * input is also a VMC (which comes from another view), then the hierarchy
+ * of the input object will be searched as well.
+ * @param 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) {