diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java index e749e482e9e..a9b5463c5d6 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java @@ -24,12 +24,12 @@ import org.eclipse.dd.dsf.concurrent.MultiRequestMonitor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactoryAdapter; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactoryAdapter; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; import org.eclipse.jface.viewers.TreePath; @@ -344,7 +344,17 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { update.done(); } - public static class AbstractVMContext implements IVMContext { + /** + * Implementation of basic View Model Context node functionality. The main + * purpose of the VMC wrapper is to re-direct adapter queries to the IVMAdapter + * and the layout node that the given context was created by. + *

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

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

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

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

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

- * Note: there should be only one instance of ServiceContext per service, so there - * is no need to implement the equals() methods. */ public class ServiceDMContext extends AbstractDMContext { String fServiceDMID; @@ -29,4 +27,14 @@ public class ServiceDMContext extends AbstractDMContext @Override public String toString() { return baseToString() + fServiceDMID; } + @Override + public boolean equals(Object obj) { + return obj instanceof ServiceDMContext && fServiceDMID.equals(((ServiceDMContext)obj).fServiceDMID); + } + + @Override + public int hashCode() { + return fServiceDMID.hashCode(); + } + }