diff options
author | Pawel Piech | 2010-03-24 18:43:58 +0000 |
---|---|---|
committer | Pawel Piech | 2010-03-24 18:43:58 +0000 |
commit | 04709d28763d09409474ce654fab8db9a1ab09d9 (patch) | |
tree | 6f0ac4961bba009712aa03488e0fdde26b63ea90 /dsf | |
parent | 79c61294f9f19b0e931465d940a8fd4ba71fcca3 (diff) | |
download | org.eclipse.cdt-04709d28763d09409474ce654fab8db9a1ab09d9.tar.gz org.eclipse.cdt-04709d28763d09409474ce654fab8db9a1ab09d9.tar.xz org.eclipse.cdt-04709d28763d09409474ce654fab8db9a1ab09d9.zip |
[306982] - [concurrent] DsfRunnable.finalize() method increases the cost of garbage collecting 10x
Diffstat (limited to 'dsf')
14 files changed, 1978 insertions, 4 deletions
diff --git a/dsf/org.eclipse.cdt.tests.dsf/.settings/org.eclipse.jdt.core.prefs b/dsf/org.eclipse.cdt.tests.dsf/.settings/org.eclipse.jdt.core.prefs index 8f1321e3841..cc70a3b2f7c 100644 --- a/dsf/org.eclipse.cdt.tests.dsf/.settings/org.eclipse.jdt.core.prefs +++ b/dsf/org.eclipse.cdt.tests.dsf/.settings/org.eclipse.jdt.core.prefs @@ -1,4 +1,4 @@ -#Thu Sep 25 17:12:53 PDT 2008 +#Wed Mar 10 12:16:35 PST 2010 eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 @@ -10,10 +10,12 @@ org.eclipse.jdt.core.compiler.debug.sourceFile=generate org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning +org.eclipse.jdt.core.compiler.problem.deadCode=warning org.eclipse.jdt.core.compiler.problem.deprecation=warning org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled -org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.discouragedReference=ignore org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning @@ -29,8 +31,11 @@ org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning +org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning +org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore @@ -60,6 +65,7 @@ org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverridin org.eclipse.jdt.core.compiler.problem.unusedImport=error org.eclipse.jdt.core.compiler.problem.unusedLabel=warning org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled diff --git a/dsf/org.eclipse.cdt.tests.dsf/META-INF/MANIFEST.MF b/dsf/org.eclipse.cdt.tests.dsf/META-INF/MANIFEST.MF index 2f93d176480..75a63b8abfe 100644 --- a/dsf/org.eclipse.cdt.tests.dsf/META-INF/MANIFEST.MF +++ b/dsf/org.eclipse.cdt.tests.dsf/META-INF/MANIFEST.MF @@ -11,9 +11,10 @@ Require-Bundle: org.eclipse.core.runtime, org.eclipse.debug.core, org.eclipse.debug.ui, org.eclipse.cdt.dsf, - org.junit4, org.eclipse.ui, org.eclipse.cdt.dsf.ui, org.eclipse.cdt.examples.dsf.pda;bundle-version="2.0.0", - org.eclipse.cdt.core;bundle-version="5.2.0" + org.eclipse.cdt.core;bundle-version="5.2.0", + org.eclipse.test.performance;bundle-version="3.6.0", + org.junit;bundle-version="3.8.2" Bundle-RequiredExecutionEnvironment: J2SE-1.5 diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/concurrent/RmPerformanceTests.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/concurrent/RmPerformanceTests.java new file mode 100644 index 00000000000..ca91c3c9f61 --- /dev/null +++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/concurrent/RmPerformanceTests.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright (c) 2009 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.tests.dsf.concurrent; + +import junit.framework.TestCase; + +import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor; +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.test.performance.Performance; +import org.eclipse.test.performance.PerformanceMeter; + +/** + * Tests to measure the performance of the viewer updates. + */ +public class RmPerformanceTests extends TestCase { + + public RmPerformanceTests(String name) { + super(name); + } + + public void testCreateAndGcObject() { + Performance perf = Performance.getDefault(); + PerformanceMeter meter = perf.createPerformanceMeter(perf.getDefaultScenarioId(this)); + try { + for (int x = 0; x < 100; x++) { + System.gc(); + meter.start(); + for (int i = 0; i < 10000; i++) { + new Object(); + } + meter.stop(); + System.gc(); + } + meter.commit(); + perf.assertPerformance(meter); + } finally { + meter.dispose(); + } + } + + public void testCreateAndGcRm() { + Performance perf = Performance.getDefault(); + PerformanceMeter meter = perf.createPerformanceMeter(perf.getDefaultScenarioId(this)); + try { + for (int x = 0; x < 100; x++) { + System.gc(); + meter.start(); + for (int i = 0; i < 10000; i++) { + RequestMonitor rm = new RequestMonitor(ImmediateExecutor.getInstance(), null); + rm.done(); + } + meter.stop(); + System.gc(); + } + meter.commit(); + perf.assertPerformance(meter); + } finally { + meter.dispose(); + } + } + + public void testCreateAndGcRmWithParent() { + Performance perf = Performance.getDefault(); + PerformanceMeter meter = perf.createPerformanceMeter(perf.getDefaultScenarioId(this)); + RequestMonitor parentRm = new RequestMonitor(ImmediateExecutor.getInstance(), null); + try { + for (int x = 0; x < 100; x++) { + System.gc(); + meter.start(); + for (int i = 0; i < 10000; i++) { + RequestMonitor rm = new RequestMonitor(ImmediateExecutor.getInstance(), parentRm) { + @Override + protected void handleCompleted() { + // do not call parent so it can be reused + }; + }; + rm.done(); + } + meter.stop(); + System.gc(); + } + meter.commit(); + perf.assertPerformance(meter); + } finally { + meter.dispose(); + } + } +} diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/ITestModelUpdatesListenerConstants.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/ITestModelUpdatesListenerConstants.java new file mode 100644 index 00000000000..c1b1893e9cf --- /dev/null +++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/ITestModelUpdatesListenerConstants.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2009 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.tests.dsf.vm; + +/** + * Convenience interface with constants used by the test model update listener. + * + * @since 3.6 + */ +public interface ITestModelUpdatesListenerConstants { + + public static final int LABEL_UPDATES_COMPLETE = 0X0001; + public static final int CONTENT_UPDATES_COMPLETE = 0X0002; + public static final int LABEL_UPDATES = 0X0004; + public static final int HAS_CHILDREN_UPDATES = 0X0008; + public static final int CHILDREN_COUNT_UPDATES = 0X0010; + public static final int CHILDREN_UPDATES = 0X0020; + public static final int MODEL_CHANGED_COMPLETE = 0X0040; + public static final int MODEL_PROXIES_INSTALLED = 0X0080; + public static final int STATE_SAVE_COMPLETE = 0X0100; + public static final int STATE_RESTORE_COMPLETE = 0X0200; + public static final int STATE_UPDATES = 0X0400; + + public static final int VIEWER_UPDATES_RUNNING = 0X0800; + public static final int LABEL_UPDATES_RUNNING = 0X1000; + + public static final int LABEL_COMPLETE = LABEL_UPDATES_COMPLETE | LABEL_UPDATES; + public static final int CONTENT_COMPLETE = + CONTENT_UPDATES_COMPLETE | HAS_CHILDREN_UPDATES | CHILDREN_COUNT_UPDATES | CHILDREN_UPDATES; + + public static final int ALL_UPDATES_COMPLETE = LABEL_COMPLETE | CONTENT_COMPLETE | LABEL_UPDATES_RUNNING | VIEWER_UPDATES_RUNNING; +} diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/JFaceViewerPerformanceTests.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/JFaceViewerPerformanceTests.java new file mode 100644 index 00000000000..854b1683bc8 --- /dev/null +++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/JFaceViewerPerformanceTests.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2009 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.tests.dsf.vm; + +import org.eclipse.debug.internal.ui.viewers.model.ITreeModelContentProviderTarget; +import org.eclipse.debug.internal.ui.viewers.model.provisional.PresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +/** + * @since 3.6 + */ +public class JFaceViewerPerformanceTests extends PerformanceTests { + + public JFaceViewerPerformanceTests(String name) { + super(name); + } + + @Override + protected ITreeModelContentProviderTarget createViewer(Display display, Shell shell) { + return new TreeModelViewer(fShell, SWT.VIRTUAL, new PresentationContext("TestViewer")); + } + + @Override + protected int getTestModelDepth() { + return 5; + } +} diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/PerformanceTests.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/PerformanceTests.java new file mode 100644 index 00000000000..9c4eb4141a1 --- /dev/null +++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/PerformanceTests.java @@ -0,0 +1,222 @@ +/******************************************************************************* + * Copyright (c) 2009 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.tests.dsf.vm; + +import junit.framework.TestCase; + +import org.eclipse.cdt.tests.dsf.vm.TestModel.TestElement; +import org.eclipse.debug.internal.ui.viewers.model.ITreeModelContentProviderTarget; +import org.eclipse.debug.internal.ui.viewers.model.ITreeModelViewer; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; +import org.eclipse.jface.viewers.TreePath; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.test.performance.Performance; +import org.eclipse.test.performance.PerformanceMeter; +import org.eclipse.ui.PlatformUI; + +/** + * Tests to measure the performance of the viewer updates. + */ +abstract public class PerformanceTests extends TestCase implements ITestModelUpdatesListenerConstants { + Display fDisplay; + Shell fShell; + ITreeModelViewer fViewer; + TestModelUpdatesListener fListener; + TestModel fModel; + TestModelVMAdapter fVMAdapter; + TestModelVMProvider fVMProvider; + + public PerformanceTests(String name) { + super(name); + } + + /** + * @throws java.lang.Exception + */ + @Override + protected void setUp() throws Exception { + fDisplay = PlatformUI.getWorkbench().getDisplay(); + fShell = new Shell(fDisplay/*, SWT.ON_TOP | SWT.SHELL_TRIM*/); + fShell.setMaximized(true); + fShell.setLayout(new FillLayout()); + + fViewer = createViewer(fDisplay, fShell); + + fListener = new TestModelUpdatesListener(false, false); + fViewer.addViewerUpdateListener(fListener); + fViewer.addLabelUpdateListener(fListener); + fViewer.addModelChangedListener(fListener); + + fModel = new TestModel(); + fModel.setRoot( new TestElement(fModel, "root", new TestElement[0] ) ); + fModel.setElementChildren(TreePath.EMPTY, makeModelElements(fModel, getTestModelDepth(), "model")); + fVMAdapter = new TestModelVMAdapter(); + fVMProvider = fVMAdapter.getTestModelProvider(fViewer.getPresentationContext()); + + fShell.open (); + } + + abstract protected ITreeModelContentProviderTarget createViewer(Display display, Shell shell); + + /** + * @throws java.lang.Exception + */ + @Override + protected void tearDown() throws Exception { + fVMAdapter.dispose(); + + fViewer.removeLabelUpdateListener(fListener); + fViewer.removeViewerUpdateListener(fListener); + fViewer.removeModelChangedListener(fListener); + fViewer.getPresentationContext().dispose(); + // Close the shell and exit. + fShell.close(); + while (!fShell.isDisposed()) if (!fDisplay.readAndDispatch ()) fDisplay.sleep (); + } + + /** + * Depth (size) of the test model to be used in the tests. This number allows + * the jface based tests to use a small enough model to fit on the screen, and + * for the virtual viewer to exercise the content provider to a greater extent. + */ + abstract protected int getTestModelDepth(); + + public void testRefreshStruct() { + fViewer.setAutoExpandLevel(-1); + + TestElementVMContext rootVMC = fVMProvider.getElementVMContext(fViewer.getPresentationContext(), fModel.getRootElement()); + + // Create the listener + fListener.reset(TreePath.EMPTY, rootVMC.getElement(), -1, true, false); + + // Set the input into the view and update the view. + fViewer.setInput(rootVMC); + while (!fListener.isFinished(ALL_UPDATES_COMPLETE)) + if (!fDisplay.readAndDispatch ()) fDisplay.sleep (); + //fModel.validateData(fViewer, TreePath.EMPTY); + + Performance perf = Performance.getDefault(); + PerformanceMeter meter = perf.createPerformanceMeter(perf.getDefaultScenarioId(this)); + try { + for (int i = 0; i < 100; i++) { + // Update the model + fModel.setAllAppendix(" - pass " + i); + + fListener.reset(TreePath.EMPTY, rootVMC.getElement(), -1, false, false); + + System.gc(); + meter.start(); + fVMProvider.postDelta(new ModelDelta(rootVMC.getElement(), IModelDelta.CONTENT)); + while (!fListener.isFinished(ALL_UPDATES_COMPLETE | MODEL_CHANGED_COMPLETE)) + if (!fDisplay.readAndDispatch ()) fDisplay.sleep (); + meter.stop(); + System.gc(); + } + + meter.commit(); + perf.assertPerformance(meter); + } finally { + meter.dispose(); + } + } + + public void _x_testRefreshStructOnePass() { + fViewer.setAutoExpandLevel(-1); + + TestElementVMContext rootVMC = fVMProvider.getElementVMContext(fViewer.getPresentationContext(), fModel.getRootElement()); + + // Create the listener + fListener.reset(TreePath.EMPTY, rootVMC.getElement(), -1, true, false); + + // Set the input into the view and update the view. + fViewer.setInput(rootVMC); + while (!fListener.isFinished(ALL_UPDATES_COMPLETE)) + if (!fDisplay.readAndDispatch ()) fDisplay.sleep (); + //fModel.validateData(fViewer, TreePath.EMPTY); + + Performance perf = Performance.getDefault(); + PerformanceMeter meter = perf.createPerformanceMeter(perf.getDefaultScenarioId(this)); + try { + System.gc(); + meter.start(); + for (int i = 0; i < 1000; i++) { + // Update the model + fModel.setAllAppendix(" - pass " + i); + + fListener.reset(TreePath.EMPTY, rootVMC.getElement(), -1, false, false); + + fVMProvider.postDelta(new ModelDelta(rootVMC.getElement(), IModelDelta.CONTENT)); + while (!fListener.isFinished(ALL_UPDATES_COMPLETE | MODEL_CHANGED_COMPLETE)) + if (!fDisplay.readAndDispatch ()) fDisplay.sleep (); + } + System.gc(); + meter.stop(); + + meter.commit(); + perf.assertPerformance(meter); + } finally { + meter.dispose(); + } + } + + public void _x_testRefreshStructReplaceElements() { + TestModel model = new TestModel(); + model.setRoot( new TestElement(model, "root", new TestElement[0] ) ); + model.setElementChildren(TreePath.EMPTY, makeModelElements(model, getTestModelDepth(), "model")); + + fViewer.setAutoExpandLevel(-1); + + // Create the listener + fListener.reset(TreePath.EMPTY, model.getRootElement(), -1, true, false); + + // Set the input into the view and update the view. + fViewer.setInput(model.getRootElement()); + while (!fListener.isFinished()) if (!fDisplay.readAndDispatch ()) fDisplay.sleep (); + model.validateData(fViewer, TreePath.EMPTY); + + Performance perf = Performance.getDefault(); + PerformanceMeter meter = perf.createPerformanceMeter(perf.getDefaultScenarioId(this)); + try { + for (int i = 0; i < 2000; i++) { + // Update the model + model.setElementChildren(TreePath.EMPTY, makeModelElements(model, getTestModelDepth(), "pass " + i)); + + TestElement element = model.getRootElement(); + fListener.reset(TreePath.EMPTY, element, -1, false, false); + + meter.start(); + model.postDelta(new ModelDelta(element, IModelDelta.CONTENT)); + while (!fListener.isFinished(ALL_UPDATES_COMPLETE | MODEL_CHANGED_COMPLETE)) + if (!fDisplay.readAndDispatch ()) fDisplay.sleep (); + //model.validateData(fViewer, TreePath.EMPTY); + meter.stop(); + System.gc(); + } + + meter.commit(); + perf.assertPerformance(meter); + } finally { + meter.dispose(); + } + } + + private TestElement[] makeModelElements(TestModel model, int depth, String prefix) { + TestElement[] elements = new TestElement[depth]; + for (int i = 0; i < depth; i++) { + String name = prefix + "." + i; + elements[i] = new TestElement(model, name, makeModelElements(model, i, name)); + } + return elements; + } +} diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestDsfVMPlugin.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestDsfVMPlugin.java new file mode 100644 index 00000000000..6c3d3e09751 --- /dev/null +++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestDsfVMPlugin.java @@ -0,0 +1,52 @@ +package org.eclipse.cdt.tests.dsf.vm; + +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + */ +public class TestDsfVMPlugin extends AbstractUIPlugin { + + // The plug-in ID + public static final String PLUGIN_ID = "org.eclipse.cdt.tests.dsf.vm"; //$NON-NLS-1$ + + // The shared instance + private static TestDsfVMPlugin plugin; + + /** + * The constructor + */ + public TestDsfVMPlugin() { + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) + */ + @Override + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) + */ + @Override + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static TestDsfVMPlugin getDefault() { + return plugin; + } + +} diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestElementVMContext.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestElementVMContext.java new file mode 100644 index 00000000000..86a99768dc3 --- /dev/null +++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestElementVMContext.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.tests.dsf.vm; + +import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMContext; +import org.eclipse.cdt.tests.dsf.vm.TestModel.TestElement; + +/** + * + */ +public class TestElementVMContext extends AbstractVMContext { + + final private TestElement fElement; + + public TestElementVMContext(TestModelVMNode node, TestElement element) { + super(node); + fElement = element; + } + + @Override + public boolean equals(Object obj) { + return obj instanceof TestElementVMContext && ((TestElementVMContext)obj).fElement.equals(fElement); + } + + @Override + public int hashCode() { + return fElement.hashCode(); + } + + public TestElement getElement() { + return fElement; + } + +} diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestModel.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestModel.java new file mode 100644 index 00000000000..4875f378e1f --- /dev/null +++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestModel.java @@ -0,0 +1,669 @@ +/******************************************************************************* + * Copyright (c) 2009 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.tests.dsf.vm; + +import java.util.Arrays; + +import junit.framework.Assert; + +import org.eclipse.core.runtime.PlatformObject; +import org.eclipse.debug.internal.ui.viewers.model.ITreeModelCheckProviderTarget; +import org.eclipse.debug.internal.ui.viewers.model.ITreeModelContentProviderTarget; +import org.eclipse.debug.internal.ui.viewers.model.ITreeModelViewer; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ICheckUpdate; +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.IElementCompareRequest; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoRequest; +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.IModelProxy; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; +import org.eclipse.debug.internal.ui.viewers.provisional.AbstractModelProxy; +import org.eclipse.jface.viewers.TreePath; +import org.eclipse.jface.viewers.Viewer; + +/** + * Test model for the use in unit tests. This test model contains a set of + * elements in a tree structure. It contains utility methods for modifying the + * model and for verifying that the viewer content matches the model. + * + * @since 3.6 + */ +public class TestModel { + + public static class TestElement extends PlatformObject { + private final TestModel fModel; + private final String fID; + TestElement[] fChildren; + String fLabelAppendix = ""; + boolean fExpanded; + boolean fChecked; + boolean fGrayed; + + public TestElement(TestModel model, String text, TestElement[] children) { + this (model, text, false, false, children); + } + + public TestElement(TestModel model, String text, boolean checked, boolean grayed, TestElement[] children) { + fModel = model; + fID = text; + fChildren = children; + fChecked = checked; + fGrayed = grayed; + } + + public TestModel getModel() { + return fModel; + } + + @SuppressWarnings("rawtypes") + @Override + public Object getAdapter(Class adapter) { + if (adapter.isInstance(fModel)) { + return fModel; + } + return null; + } + + public String getID() { + return fID; + } + + public void setLabelAppendix(String appendix) { + fLabelAppendix = appendix; + } + + public String getLabel() { + return fID + fLabelAppendix; + } + + public TestElement[] getChildren() { + return fChildren; + } + + public boolean isExpanded() { + return fExpanded; + } + + public boolean getGrayed() { + return fGrayed; + } + + public boolean getChecked() { + return fChecked; + } + + public void setChecked(boolean checked, boolean grayed) { + fChecked = checked; + fGrayed = grayed; + } + + @Override + public boolean equals(Object obj) { + return obj instanceof TestElement && fID.equals(((TestElement)obj).fID); + } + + @Override + public int hashCode() { + return fID.hashCode(); + } + + @Override + public String toString() { + return getLabel(); + } + + public int indexOf(TestElement child) { + return Arrays.asList(fChildren).indexOf(child); + } + } + + private class ModelProxy extends AbstractModelProxy { + @Override + public void installed(Viewer viewer) { + super.installed(viewer); + ModelDelta rootDelta = TestModel.this.getBaseDelta(new ModelDelta(fInput, IModelDelta.NO_CHANGE)); + installSubModelProxies(fRootPath, rootDelta); + fireModelChanged(rootDelta); + } + + private void installSubModelProxies(TreePath path, ModelDelta delta) { + TestElement element = getElement(path); + if (element.fModel != TestModel.this) { + // Found an element from a different model. Install its proxy and return. + delta.setFlags(delta.getFlags() | IModelDelta.INSTALL); + } else { + TestElement[] children = element.getChildren(); + + for (int i = 0; i < children.length; i++) { + installSubModelProxies(path.createChildPath(children[i]), delta.addNode(children[i], IModelDelta.NO_CHANGE)); + } + } + } + } + + private TestElement fRoot; + private Object fInput = null; + private TreePath fRootPath = TreePath.EMPTY; + private ModelProxy fModelProxy; + + /** + * Constructor private. Use static factory methods instead. + */ + public TestModel() {} + + public TestElement getRootElement() { + return fRoot; + } + + public ModelDelta getBaseDelta(ModelDelta rootDelta) { + ModelDelta delta = rootDelta; + for (int i = 0; i < fRootPath.getSegmentCount(); i++) { + ModelDelta subDelta = delta.getChildDelta(fRootPath.getSegment(i)); + if (subDelta == null) { + subDelta = delta.addNode(fRootPath.getSegment(i), IModelDelta.NO_CHANGE); + } + delta = subDelta; + } + delta.setChildCount(getRootElement().getChildren().length); + return delta; + } + + public int getModelDepth() { + return getDepth(getRootElement(), 0); + } + + private int getDepth(TestElement element, int atDepth) { + TestElement[] children = element.getChildren(); + if (children.length == 0) { + return atDepth; + } + int depth = atDepth + 1; + for (int i = 0; i < children.length; i++) { + depth = Math.max(depth, getDepth(children[i], atDepth + 1)); + } + + return depth; + } + + public void update(IHasChildrenUpdate[] updates) { + for (int i = 0; i < updates.length; i++) { + TestElement element = (TestElement)updates[i].getElement(); + updates[i].setHasChilren(element.getChildren().length > 0); + updates[i].done(); + } + } + + public void update(IChildrenCountUpdate[] updates) { + for (int i = 0; i < updates.length; i++) { + TestElement element = (TestElement)updates[i].getElement(); + updates[i].setChildCount(element.getChildren().length); + updates[i].done(); + } + } + + public void update(IChildrenUpdate[] updates) { + for (int i = 0; i < updates.length; i++) { + TestElement element = (TestElement)updates[i].getElement(); + int endOffset = updates[i].getOffset() + updates[i].getLength(); + for (int j = updates[i].getOffset(); j < endOffset; j++) { + if (j < element.getChildren().length) { + updates[i].setChild(element.getChildren()[j], j); + } + } + updates[i].done(); + } + } + + public void update(ILabelUpdate[] updates) { + for (int i = 0; i < updates.length; i++) { + TestElement element = (TestElement)updates[i].getElement(); + updates[i].setLabel(element.fID, 0); + if (updates[i] instanceof ICheckUpdate && + Boolean.TRUE.equals(updates[i].getPresentationContext().getProperty(ICheckUpdate.PROP_CHECK))) + { + ((ICheckUpdate)updates[i]).setChecked(element.getChecked(), element.getGrayed()); + } + updates[i].done(); + } + } + + public final static String ELEMENT_MEMENTO_ID = "id"; + + public void compareElements(IElementCompareRequest[] updates) { + for (int i = 0; i < updates.length; i++) { + String elementID = ((TestElement)updates[i].getElement()).getID(); + String mementoID = updates[i].getMemento().getString(ELEMENT_MEMENTO_ID); + updates[i].setEqual( elementID.equals(mementoID) ); + updates[i].done(); + } + + } + + public void encodeElements(IElementMementoRequest[] updates) { + for (int i = 0; i < updates.length; i++) { + String elementID = ((TestElement)updates[i].getElement()).getID(); + updates[i].getMemento().putString(ELEMENT_MEMENTO_ID, elementID); + updates[i].done(); + } + } + + + public void elementChecked(IPresentationContext context, Object viewerInput, TreePath path, boolean checked) { + TestElement element = getElement(path); + Assert.assertFalse(element.getGrayed()); + element.setChecked(checked, false); + } + + public IModelProxy createTreeModelProxy(Object input, TreePath path, IPresentationContext context) { + fModelProxy = new ModelProxy(); + fInput = input; + fRootPath = path; + return fModelProxy; + } + + public IModelProxy getModelProxy() { + return fModelProxy; + } + + public TestElement getElement(TreePath path) { + if (path.getSegmentCount() == 0) { + return getRootElement(); + } else { + if (path.getLastSegment() instanceof TestElement) { + return (TestElement)path.getLastSegment(); + } else if (path.getLastSegment() instanceof TestElementVMContext) { + return ((TestElementVMContext)path.getLastSegment()).getElement(); + } + return null; + } + } + + public void setAllExpanded() { + doSetExpanded(fRoot); + } + + private void doSetExpanded(TestElement element) { + element.fExpanded = true; + for (int i = 0; i < element.fChildren.length; i++) { + doSetExpanded(element.fChildren[i]); + } + } + + public void setAllAppendix(String appendix) { + doSetAllAppendix(fRoot, appendix); + } + + private void doSetAllAppendix(TestElement element, String appendix) { + element.setLabelAppendix(appendix); + for (int i = 0; i < element.fChildren.length; i++) { + doSetAllAppendix(element.fChildren[i], appendix); + } + } + + public void validateData(ITreeModelViewer viewer, TreePath path) { + + validateData(viewer, path, false); + } + + public void validateData(ITreeModelViewer _viewer, TreePath path, boolean expandedElementsOnly) { + ITreeModelContentProviderTarget viewer = (ITreeModelContentProviderTarget)_viewer; + TestElement element = getElement(path); + if ( Boolean.TRUE.equals(_viewer.getPresentationContext().getProperty(ICheckUpdate.PROP_CHECK)) ) { + ITreeModelCheckProviderTarget checkTarget = (ITreeModelCheckProviderTarget)_viewer; + Assert.assertEquals(element.getChecked(), checkTarget.getElementChecked(path)); + Assert.assertEquals(element.getGrayed(), checkTarget.getElementGrayed(path)); + } + + if (!expandedElementsOnly || path.getSegmentCount() == 0 || viewer.getExpandedState(path) ) { + TestElement[] children = element.getChildren(); + Assert.assertEquals(children.length, viewer.getChildCount(path)); + + for (int i = 0; i < children.length; i++) { + Assert.assertEquals(children[i], viewer.getChildElement(path, i)); + validateData(viewer, path.createChildPath(children[i]), expandedElementsOnly); + } + } else if (!viewer.getExpandedState(path)) { + // If element not expanded, verify the plus sign. + Assert.assertEquals(viewer.getHasChildren(path), element.getChildren().length > 0); + } + } + + public void setRoot(TestElement root) { + fRoot = root; + } + + public void postDelta(IModelDelta delta) { + fModelProxy.fireModelChanged(delta); + } + + /** Create or retrieve delta for given path + * @param combine if then new deltas for the given path are created. If false existing ones are reused. + */ + public ModelDelta getElementDelta(ModelDelta baseDelta, TreePath path, boolean combine) { + TestElement element = getRootElement(); + ModelDelta delta = baseDelta; + + for (int i = 0; i < path.getSegmentCount(); i++) { + TestElement[] children = element.getChildren(); + delta.setChildCount(children.length); + Object segment = path.getSegment(i); + int j; + for (j = 0; j < children.length; j++) { + if (segment.equals(children[j])) { + element = children[j]; + ModelDelta nextDelta = null; + if (combine) { + nextDelta = delta.getChildDelta(element); + } + if (nextDelta == null) { + nextDelta = delta.addNode(element, j, IModelDelta.NO_CHANGE, element.getChildren().length); + } + delta = nextDelta; + break; + } + } + if (j == children.length) { + throw new IllegalArgumentException("Invalid path"); + } + } + return delta; + + } + + private TreePath getRelativePath(TreePath path) { + Object[] segments = new Object[path.getSegmentCount() - fRootPath.getSegmentCount()]; + for (int i = fRootPath.getSegmentCount(), _i = 0; i < path.getSegmentCount(); i++, _i++) { + segments[_i] = path.getSegment(i); + } + return new TreePath(segments); + } + + public ModelDelta appendElementLabel(TreePath path, String labelAppendix) { + Assert.assertTrue(path.startsWith(fRootPath, null)); + ModelDelta rootDelta = new ModelDelta(fInput, IModelDelta.NO_CHANGE); + ModelDelta baseDelta = getBaseDelta(rootDelta); + TreePath relativePath = getRelativePath(path); + TestElement element = getElement(relativePath); + ModelDelta delta = getElementDelta(baseDelta, relativePath, false); + element.setLabelAppendix(labelAppendix); + delta.setFlags(delta.getFlags() | IModelDelta.STATE); + + return rootDelta; + } + + public ModelDelta setElementChecked(TreePath path, boolean checked, boolean grayed) { + Assert.assertTrue(path.startsWith(fRootPath, null)); + ModelDelta rootDelta = new ModelDelta(fInput, IModelDelta.NO_CHANGE); + ModelDelta baseDelta = getBaseDelta(rootDelta); + TreePath relativePath = getRelativePath(path); + TestElement element = getElement(relativePath); + ModelDelta delta = getElementDelta(baseDelta, relativePath, false); + element.setChecked(checked, grayed); + delta.setFlags(delta.getFlags() | IModelDelta.STATE); + + return rootDelta; + } + + public ModelDelta setElementChildren(TreePath path, TestElement[] children) { + Assert.assertTrue(path.startsWith(fRootPath, null)); + ModelDelta rootDelta = new ModelDelta(fInput, IModelDelta.NO_CHANGE); + ModelDelta baseDelta = getBaseDelta(rootDelta); + TreePath relativePath = getRelativePath(path); + + // Find the parent element and generate the delta node for it. + TestElement element = getElement(relativePath); + ModelDelta delta = getElementDelta(baseDelta, relativePath, false); + + // Set the new children array + element.fChildren = children; + + // Add the delta flag and update the child count in the parent delta. + delta.setFlags(delta.getFlags() | IModelDelta.CONTENT); + delta.setChildCount(children.length); + + return rootDelta; + } + + public ModelDelta replaceElementChild(TreePath parentPath, int index, TestElement child) { + ModelDelta rootDelta = new ModelDelta(fInput, IModelDelta.NO_CHANGE); + ModelDelta baseDelta = getBaseDelta(rootDelta); + TreePath relativePath = getRelativePath(parentPath); + + TestElement element = getElement(relativePath); + ModelDelta delta= getElementDelta(baseDelta, relativePath, false); + TestElement oldChild = element.fChildren[index]; + element.fChildren[index] = child; + delta.addNode(oldChild, child, IModelDelta.REPLACED); + // TODO: set replacement index!?! + + return rootDelta; + } + + public ModelDelta addElementChild(TreePath parentPath, int index, TestElement newChild) { + ModelDelta rootDelta = new ModelDelta(fInput, IModelDelta.NO_CHANGE); + ModelDelta baseDelta = getBaseDelta(rootDelta); + TreePath relativePath = getRelativePath(parentPath); + + // Find the parent element and generate the delta node for it. + TestElement element = getElement(relativePath); + ModelDelta delta= getElementDelta(baseDelta, relativePath, false); + + // Add the new element + element.fChildren = doInsertElementInArray(element.fChildren, index, newChild); + + // Add the delta flag and update the child count in the parent delta. + delta.setChildCount(element.getChildren().length); + delta.addNode(newChild, IModelDelta.ADDED); + + return rootDelta; + } + + public ModelDelta insertElementChild(TreePath parentPath, int index, TestElement newChild) { + return insertElementChild(null, parentPath, index, newChild); + } + + public ModelDelta insertElementChild(ModelDelta rootDelta, TreePath parentPath, int index, TestElement newChild) { + if (rootDelta == null) { + rootDelta = new ModelDelta(fInput, IModelDelta.NO_CHANGE); + } + ModelDelta baseDelta = getBaseDelta(rootDelta); + TreePath relativePath = getRelativePath(parentPath); + + // Find the parent element and generate the delta node for it. + TestElement element = getElement(relativePath); + ModelDelta delta= getElementDelta(baseDelta, relativePath, false); + + // Add the new element + element.fChildren = doInsertElementInArray(element.fChildren, index, newChild); + + // Add the delta flag and update the child count in the parent delta. + delta.setChildCount(element.getChildren().length); + delta.addNode(newChild, index, IModelDelta.INSERTED); + + return rootDelta; + } + + private TestElement[] doInsertElementInArray(TestElement[] children, int index, TestElement newChild) { + // Create the new children array add the element to it and set it to + // the parent. + TestElement[] newChildren = new TestElement[children.length + 1]; + System.arraycopy(children, 0, newChildren, 0, index); + newChildren[index] = newChild; + System.arraycopy(children, index, newChildren, index + 1, children.length - index); + return newChildren; + } + + public ModelDelta removeElementChild(TreePath parentPath, int index) { + ModelDelta rootDelta = new ModelDelta(fInput, IModelDelta.NO_CHANGE); + ModelDelta baseDelta = getBaseDelta(rootDelta); + + // Find the parent element and generate the delta node for it. + TestElement element = getElement(parentPath); + ModelDelta delta= getElementDelta(baseDelta, parentPath, false); + + // Create a new child array with the element removed + TestElement[] children = element.getChildren(); + TestElement childToRemove = children[index]; + TestElement[] newChildren = new TestElement[children.length - 1]; + System.arraycopy(children, 0, newChildren, 0, index); + System.arraycopy(children, index + 1, newChildren, index, children.length - index - 1); + element.fChildren = newChildren; + + // Add the delta flag and update the child count in the parent delta. + delta.setChildCount(element.getChildren().length); + delta.addNode(childToRemove, index, IModelDelta.REMOVED); + + return rootDelta; + } + + public ModelDelta makeElementDelta(TreePath path, int flags) { + ModelDelta rootDelta = new ModelDelta(fInput, IModelDelta.NO_CHANGE); + ModelDelta baseDelta = getBaseDelta(rootDelta); + + // Find the element and generate the delta node for it. + ModelDelta delta= getElementDelta(baseDelta, path, false); + + delta.setFlags(flags); + return rootDelta; + } + + public TreePath findElement(String label) { + return findElement(TreePath.EMPTY, label); + } + + public TreePath findElement(TreePath startPath, String label) { + TestElement element = getElement(startPath); + for (int i = 0; i < element.getChildren().length; i++) { + TestElement child = element.getChildren()[i]; + TreePath path = startPath.createChildPath(child); + if ( label.equals(child.getLabel()) ) { + return path; + } else { + TreePath subPath = findElement(path, label); + if (subPath != null) { + return subPath; + } + } + } + return null; + } + + @Override + public String toString() { + return getElementString(fRoot, ""); + } + + public String getElementString(TestElement element, String indent) { + StringBuffer builder = new StringBuffer(); + builder.append(indent); + builder.append(element.toString()); + builder.append('\n'); + TestElement[] children = element.getChildren(); + for (int i = 0; i < children.length; i++) { + builder.append(getElementString(children[i], indent + " ")); + } + return builder.toString(); + } + + public static TestModel simpleSingleLevel() { + TestModel model = new TestModel(); + model.setRoot( new TestElement(model, "root", new TestElement[] { + new TestElement(model, "1", true, true, new TestElement[0]), + new TestElement(model, "2", true, false, new TestElement[0]), + new TestElement(model, "3", false, true, new TestElement[0]), + new TestElement(model, "4", false, false, new TestElement[0]), + new TestElement(model, "5", new TestElement[0]), + new TestElement(model, "6", new TestElement[0]) + }) ); + return model; + } + + public static TestModel simpleMultiLevel() { + TestModel model = new TestModel(); + model.setRoot( new TestElement(model, "root", new TestElement[] { + new TestElement(model, "1", new TestElement[0]), + new TestElement(model, "2", true, false, new TestElement[] { + new TestElement(model, "2.1", true, true, new TestElement[0]), + new TestElement(model, "2.2", false, true, new TestElement[0]), + new TestElement(model, "2.3", true, false, new TestElement[0]), + }), + new TestElement(model, "3", new TestElement[] { + new TestElement(model, "3.1", new TestElement[] { + new TestElement(model, "3.1.1", new TestElement[0]), + new TestElement(model, "3.1.2", new TestElement[0]), + new TestElement(model, "3.1.3", new TestElement[0]), + }), + new TestElement(model, "3.2", new TestElement[] { + new TestElement(model, "3.2.1", new TestElement[0]), + new TestElement(model, "3.2.2", new TestElement[0]), + new TestElement(model, "3.2.3", new TestElement[0]), + }), + new TestElement(model, "3.3", new TestElement[] { + new TestElement(model, "3.3.1", new TestElement[0]), + new TestElement(model, "3.3.2", new TestElement[0]), + new TestElement(model, "3.3.3", new TestElement[0]), + }), + }) + }) ); + return model; + } + + public static TestModel compositeMultiLevel() { + TestModel m2 = new TestModel(); + m2.setRoot( new TestElement(m2, "m2.root", new TestElement[] { + new TestElement(m2, "m2.1", new TestElement[0]), + new TestElement(m2, "m2.2", true, false, new TestElement[] { + new TestElement(m2, "m2.2.1", true, true, new TestElement[0]), + new TestElement(m2, "m2.2.2", false, true, new TestElement[0]), + new TestElement(m2, "m2.2.3", true, false, new TestElement[0]), + }), + }) ); + + TestModel m3 = new TestModel(); + m3.setRoot( new TestElement(m3, "m3.root", new TestElement[] { + new TestElement(m3, "m3.1", new TestElement[0]), + new TestElement(m3, "m3.2", true, false, new TestElement[] { + new TestElement(m3, "m3.2.1", true, true, new TestElement[0]), + new TestElement(m3, "m3.2.2", false, true, new TestElement[0]), + new TestElement(m3, "m3.2.3", true, false, new TestElement[0]), + }), + }) ); + + TestModel m4 = new TestModel(); + m4.setRoot( new TestElement(m4, "m4.root", new TestElement[] { + new TestElement(m4, "m4.1", new TestElement[0]), + new TestElement(m4, "m4.2", true, false, new TestElement[] { + new TestElement(m4, "m4.2.1", true, true, new TestElement[0]), + new TestElement(m4, "m4.2.2", false, true, new TestElement[0]), + new TestElement(m4, "m4.2.3", true, false, new TestElement[0]), + }), + }) ); + + TestModel m1 = new TestModel(); + m1.setRoot( new TestElement(m1, "m1.root", new TestElement[] { + new TestElement(m1, "m1.1", new TestElement[0]), + new TestElement(m1, "m1.2", true, false, new TestElement[] { + m2.fRoot, + m3.fRoot, + m4.fRoot, + }), + }) ); + + + return m1; + } + + +} diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestModelUpdatesListener.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestModelUpdatesListener.java new file mode 100644 index 00000000000..090c264f78c --- /dev/null +++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestModelUpdatesListener.java @@ -0,0 +1,568 @@ +/******************************************************************************* + * Copyright (c) 2009 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.tests.dsf.vm; + +import java.util.Comparator; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; + +import junit.framework.Assert; + +import org.eclipse.cdt.tests.dsf.vm.TestModel.TestElement; +import org.eclipse.debug.internal.ui.viewers.model.ILabelUpdateListener; +import org.eclipse.debug.internal.ui.viewers.model.ITreeModelContentProviderTarget; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelChangedListener; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IStateUpdateListener; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdateListener; +import org.eclipse.jface.viewers.TreePath; + +public class TestModelUpdatesListener + implements IViewerUpdateListener, ILabelUpdateListener, IModelChangedListener, ITestModelUpdatesListenerConstants, + IStateUpdateListener +{ + + private final static Comparator<String> fStringComparator = new Comparator<String>() { + + public int compare(String s1, String s2) { + int l1 = s1.length(); + int l2 = s2.length(); + int lmin = l1; + int result = 0; + if (l1 < l2) { + result = -1; + } else if (l1 > l2) { + result = 1; + lmin = l2; + } + + char c1 = 0; + char c2 = 0; + int i = 0; + for (; i < lmin; i++) { + c1 = s1.charAt(i); + c2 = s2.charAt(i); + if (c1 != c2) { + break; + } + } + + if (i == lmin) { + return result; + } + return c1 - c2; + }; + }; + + private final static Comparator<TreePath> fTestElementVMCComparator = new Comparator<TreePath>() { + public int compare(TreePath p1, TreePath p2) { + int l1 = p1.getSegmentCount(); + int l2 = p2.getSegmentCount(); + int lmin = l1; + int result = 0; + if (l1 < l2) { + result = -1; + } else if (l1 > l2) { + result = 1; + lmin = l2; + } + + TestElement e1 = null; + TestElement e2 = null; + int i = 0; + for (; i < lmin; i++) { + e1 = getTestElement(p1.getSegment(i)); + e2 = getTestElement(p2.getSegment(i)); + if ((e1 == null && e2 != null) || (e1 != null && !e1.equals(e2))) { + break; + } + } + + if (i == lmin) { + return result; + } + String id1 = e1 == null ? "" : e1.getID(); + String id2 = e2 == null ? "" : e2.getID(); + return fStringComparator.compare(id1, id2); + } + + private TestElement getTestElement(Object o) { + if (o instanceof TestElement) { + return (TestElement)o; + } else if (o instanceof TestElementVMContext) { + return ((TestElementVMContext)o).getElement(); + } + return null; + } + + }; + + private boolean fFailOnRedundantUpdates; + private boolean fFailOnMultipleModelUpdateSequences; + private boolean fFailOnMultipleLabelUpdateSequences; + + private Set<TreePath> fHasChildrenUpdates = new TreeSet<TreePath>(fTestElementVMCComparator); + private Map<TreePath, Set<Integer>> fChildrenUpdates = new TreeMap<TreePath, Set<Integer>>(fTestElementVMCComparator); + private Set<TreePath> fChildCountUpdates = new TreeSet<TreePath>(fTestElementVMCComparator); + private Set<TreePath> fLabelUpdates = new TreeSet<TreePath>(fTestElementVMCComparator); + private Set<TestModel> fProxyModels = new HashSet<TestModel>(); + private Set<TreePath> fStateUpdates = new TreeSet<TreePath>(fTestElementVMCComparator); + private boolean fViewerUpdatesComplete; + private boolean fLabelUpdatesComplete; + private boolean fModelChangedComplete; + private boolean fStateSaveComplete; + private boolean fStateRestoreComplete; + private int fViewerUpdatesRunning; + private int fLabelUpdatesRunning; + private int fTimeoutInterval = 60000; + private long fTimeoutTime; + + + public TestModelUpdatesListener(boolean failOnRedundantUpdates, boolean failOnMultipleModelUpdateSequences) { + setFailOnRedundantUpdates(failOnRedundantUpdates); + setFailOnMultipleModelUpdateSequences(failOnMultipleModelUpdateSequences); + } + + public void setFailOnRedundantUpdates(boolean failOnRedundantUpdates) { + fFailOnRedundantUpdates = failOnRedundantUpdates; + } + + public void setFailOnMultipleModelUpdateSequences(boolean failOnMultipleLabelUpdateSequences) { + fFailOnMultipleModelUpdateSequences = failOnMultipleLabelUpdateSequences; + } + + public void setFailOnMultipleLabelUpdateSequences(boolean failOnMultipleLabelUpdateSequences) { + fFailOnMultipleLabelUpdateSequences = failOnMultipleLabelUpdateSequences; + } + + /** + * Sets the the maximum amount of time (in milliseconds) that the update listener + * is going to wait. If set to -1, the listener will wait indefinitely. + */ + public void setTimeoutInterval(int milis) { + fTimeoutInterval = milis; + } + + public void reset(TreePath path, TestElement element, int levels, boolean failOnRedundantUpdates, boolean failOnMultipleUpdateSequences) { + reset(); + addUpdates(path, element, levels); + addProxies(element); + setFailOnRedundantUpdates(failOnRedundantUpdates); + setFailOnMultipleModelUpdateSequences(failOnMultipleUpdateSequences); + setFailOnMultipleLabelUpdateSequences(false); + } + + public void reset(boolean failOnRedundantUpdates, boolean failOnMultipleUpdateSequences) { + reset(); + setFailOnRedundantUpdates(failOnRedundantUpdates); + setFailOnMultipleModelUpdateSequences(failOnMultipleUpdateSequences); + setFailOnMultipleLabelUpdateSequences(false); + } + + public void reset() { + fHasChildrenUpdates.clear(); + fChildrenUpdates.clear(); + fChildCountUpdates.clear(); + fLabelUpdates.clear(); + fProxyModels.clear(); + fViewerUpdatesComplete = false; + fLabelUpdatesComplete = false; + fStateSaveComplete = false; + fStateRestoreComplete = false; + fTimeoutTime = System.currentTimeMillis() + fTimeoutInterval; + resetModelChanged(); + } + + public void resetModelChanged() { + fModelChangedComplete = false; + } + + public void addHasChildrenUpdate(TreePath path) { + fHasChildrenUpdates.add(path); + } + + public void removeHasChildrenUpdate(TreePath path) { + fHasChildrenUpdates.remove(path); + } + + public void addChildreCountUpdate(TreePath path) { + fChildCountUpdates.add(path); + } + + public void removeChildreCountUpdate(TreePath path) { + fChildCountUpdates.remove(path); + } + + public void addChildreUpdate(TreePath path, int index) { + Set<Integer> childrenIndexes = fChildrenUpdates.get(path); + if (childrenIndexes == null) { + childrenIndexes = new TreeSet<Integer>(); + fChildrenUpdates.put(path, childrenIndexes); + } + childrenIndexes.add(new Integer(index)); + } + + public void removeChildrenUpdate(TreePath path, int index) { + Set<Integer> childrenIndexes = fChildrenUpdates.get(path); + if (childrenIndexes != null) { + childrenIndexes.remove(new Integer(index)); + if (childrenIndexes.isEmpty()) { + fChildrenUpdates.remove(path); + } + } + } + + public void addLabelUpdate(TreePath path) { + fLabelUpdates.add(path); + } + + public void removeLabelUpdate(TreePath path) { + fLabelUpdates.remove(path); + } + + public void addUpdates(TreePath path, TestElement element, int levels) { + addUpdates(path, element, levels, ALL_UPDATES_COMPLETE); + } + + public void addStateUpdates(ITreeModelContentProviderTarget viewer, TreePath path, TestElement element) { + addUpdates(viewer, path, element, -1, STATE_UPDATES); + } + + public void addUpdates(TreePath path, TestElement element, int levels, int flags) { + addUpdates(null, path, element, levels, flags); + } + + public void addUpdates(ITreeModelContentProviderTarget viewer, TreePath path, TestElement element, int levels, int flags) { + if (!path.equals(TreePath.EMPTY)) { + if ((flags & LABEL_UPDATES) != 0) { + fLabelUpdates.add(path); + } + if ((flags & HAS_CHILDREN_UPDATES) != 0) { + fHasChildrenUpdates.add(path); + } + } + + if (levels-- != 0) { + TestElement[] children = element.getChildren(); + if (children.length > 0 && (viewer == null || path.getSegmentCount() == 0 || viewer.getExpandedState(path))) { + if ((flags & CHILDREN_COUNT_UPDATES) != 0) { + fChildCountUpdates.add(path); + } + if ((flags & CHILDREN_UPDATES) != 0) { + Set<Integer> childrenIndexes = new HashSet<Integer>(); + for (int i = 0; i < children.length; i++) { + childrenIndexes.add(new Integer(i)); + } + fChildrenUpdates.put(path, childrenIndexes); + } + + if ((flags & STATE_UPDATES) != 0 && viewer != null) { + fStateUpdates.add(path); + } + + for (int i = 0; i < children.length; i++) { + addUpdates(viewer, path.createChildPath(children[i]), children[i], levels, flags); + } + } + + } + } + + private void addProxies(TestElement element) { + TestModel model = element.getModel(); + if (model.getModelProxy() == null) { + fProxyModels.add(element.getModel()); + } + TestElement[] children = element.getChildren(); + for (int i = 0; i < children.length; i++) { + addProxies(children[i]); + } + } + + public boolean isFinished() { + return isFinished(ALL_UPDATES_COMPLETE); + } + + public boolean isFinished(int flags) { + if (fTimeoutInterval > 0 && fTimeoutTime < System.currentTimeMillis()) { + throw new RuntimeException("Timed Out: " + toString(flags)); + } + + if ( (flags & LABEL_UPDATES_COMPLETE) != 0) { + if (!fLabelUpdatesComplete) return false; + } + if ( (flags & LABEL_UPDATES) != 0) { + if (!fLabelUpdates.isEmpty()) return false; + } + if ( (flags & CONTENT_UPDATES_COMPLETE) != 0) { + if (!fViewerUpdatesComplete) return false; + } + if ( (flags & HAS_CHILDREN_UPDATES) != 0) { + if (!fHasChildrenUpdates.isEmpty()) return false; + } + if ( (flags & CHILDREN_COUNT_UPDATES) != 0) { + if (!fChildCountUpdates.isEmpty()) return false; + } + if ( (flags & CHILDREN_UPDATES) != 0) { + if (!fChildrenUpdates.isEmpty()) return false; + } + if ( (flags & MODEL_CHANGED_COMPLETE) != 0) { + if (!fModelChangedComplete) return false; + } + if ( (flags & STATE_SAVE_COMPLETE) != 0) { + if (!fStateSaveComplete) return false; + } + if ( (flags & STATE_RESTORE_COMPLETE) != 0) { + if (!fStateRestoreComplete) return false; + } + if ( (flags & MODEL_PROXIES_INSTALLED) != 0) { + if (fProxyModels.size() != 0) return false; + } + if ( (flags & VIEWER_UPDATES_RUNNING) != 0) { + if (fViewerUpdatesRunning != 0) { + return false; + } + } + if ( (flags & LABEL_UPDATES_RUNNING) != 0) { + if (fLabelUpdatesRunning != 0) { + return false; + } + } + + return true; + } + + public void updateStarted(IViewerUpdate update) { + synchronized (this) { + fViewerUpdatesRunning++; + } + } + + public void updateComplete(IViewerUpdate update) { + synchronized (this) { + fViewerUpdatesRunning--; + } + + if (!update.isCanceled()) { + if (update instanceof IHasChildrenUpdate) { + if (!fHasChildrenUpdates.remove(update.getElementPath()) && fFailOnRedundantUpdates) { + Assert.fail("Redundant update: " + update); + } + } if (update instanceof IChildrenCountUpdate) { + if (!fChildCountUpdates.remove(update.getElementPath()) && fFailOnRedundantUpdates) { + Assert.fail("Redundant update: " + update); + } + } else if (update instanceof IChildrenUpdate) { + int start = ((IChildrenUpdate)update).getOffset(); + int end = start + ((IChildrenUpdate)update).getLength(); + + Set<Integer> childrenIndexes = fChildrenUpdates.get(update.getElementPath()); + if (childrenIndexes != null) { + for (int i = start; i < end; i++) { + childrenIndexes.remove(new Integer(i)); + } + if (childrenIndexes.isEmpty()) { + fChildrenUpdates.remove(update.getElementPath()); + } + } else if (fFailOnRedundantUpdates) { + Assert.fail("Redundant update: " + update); + } + } + } + } + + public void viewerUpdatesBegin() { + + } + + public void viewerUpdatesComplete() { + if (fFailOnMultipleModelUpdateSequences && fViewerUpdatesComplete) { + Assert.fail("Multiple viewer update sequences detected"); + } + fViewerUpdatesComplete = true; + } + + public void labelUpdateComplete(ILabelUpdate update) { + synchronized (this) { + fLabelUpdatesRunning--; + } + if (!fLabelUpdates.remove(update.getElementPath()) && fFailOnRedundantUpdates) { + Assert.fail("Redundant update: " + update); + } + } + + public void labelUpdateStarted(ILabelUpdate update) { + synchronized (this) { + fLabelUpdatesRunning++; + } + } + + public void labelUpdatesBegin() { + } + + public void labelUpdatesComplete() { + if (fFailOnMultipleLabelUpdateSequences && fLabelUpdatesComplete) { + Assert.fail("Multiple label update sequences detected"); + } + fLabelUpdatesComplete = true; + } + + public void modelChanged(IModelDelta delta, IModelProxy proxy) { + fModelChangedComplete = true; + + for (Iterator<TestModel> itr = fProxyModels.iterator(); itr.hasNext();) { + TestModel model = itr.next(); + if (model.getModelProxy() == proxy) { + itr.remove(); + break; + } + } + } + + public void stateRestoreUpdatesBegin(Object input) { + } + + public void stateRestoreUpdatesComplete(Object input) { + fStateRestoreComplete = true; + } + + public void stateSaveUpdatesBegin(Object input) { + } + + public void stateSaveUpdatesComplete(Object input) { + fStateSaveComplete = true; + } + + public void stateUpdateComplete(Object input, IViewerUpdate update) { + } + + public void stateUpdateStarted(Object input, IViewerUpdate update) { + } + + private String toString(int flags) { + StringBuffer buf = new StringBuffer("Viewer Update Listener"); + + if ( (flags & LABEL_UPDATES_COMPLETE) != 0) { + buf.append("\n\t"); + buf.append("fLabelUpdatesComplete = " + fLabelUpdatesComplete); + } + if ( (flags & LABEL_UPDATES_RUNNING) != 0) { + buf.append("\n\t"); + buf.append("fLabelUpdatesRunning = " + fLabelUpdatesRunning); + } + if ( (flags & LABEL_UPDATES) != 0) { + buf.append("\n\t"); + buf.append("fLabelUpdates = "); + buf.append( toString(fLabelUpdates) ); + } + if ( (flags & CONTENT_UPDATES_COMPLETE) != 0) { + buf.append("\n\t"); + buf.append("fViewerUpdatesComplete = " + fViewerUpdatesComplete); + } + if ( (flags & VIEWER_UPDATES_RUNNING) != 0) { + buf.append("\n\t"); + buf.append("fViewerUpdatesRunning = " + fViewerUpdatesRunning); + } + if ( (flags & HAS_CHILDREN_UPDATES) != 0) { + buf.append("\n\t"); + buf.append("fHasChildrenUpdates = "); + buf.append( toString(fHasChildrenUpdates) ); + } + if ( (flags & CHILDREN_COUNT_UPDATES) != 0) { + buf.append("\n\t"); + buf.append("fChildCountUpdates = "); + buf.append( toString(fChildCountUpdates) ); + } + if ( (flags & CHILDREN_UPDATES) != 0) { + buf.append("\n\t"); + buf.append("fChildrenUpdates = "); + buf.append( toString(fChildrenUpdates) ); + } + if ( (flags & MODEL_CHANGED_COMPLETE) != 0) { + buf.append("\n\t"); + buf.append("fModelChangedComplete = " + fModelChangedComplete); + } + if ( (flags & STATE_SAVE_COMPLETE) != 0) { + buf.append("\n\t"); + buf.append("fStateSaveComplete = " + fStateSaveComplete); + } + if ( (flags & STATE_RESTORE_COMPLETE) != 0) { + buf.append("\n\t"); + buf.append("fStateRestoreComplete = " + fStateRestoreComplete); + } + if ( (flags & MODEL_PROXIES_INSTALLED) != 0) { + buf.append("\n\t"); + buf.append("fProxyModels = " + fProxyModels); + } + if (fTimeoutInterval > 0) { + buf.append("\n\t"); + buf.append("fTimeoutInterval = " + fTimeoutInterval); + } + return buf.toString(); + } + + private String toString(Set<TreePath> set) { + if (set.isEmpty()) { + return "(EMPTY)"; + } + StringBuffer buf = new StringBuffer(); + for (Iterator<TreePath> itr = set.iterator(); itr.hasNext(); ) { + buf.append("\n\t\t"); + buf.append(toString(itr.next())); + } + return buf.toString(); + } + + private String toString(Map<TreePath, Set<Integer>> map) { + if (map.isEmpty()) { + return "(EMPTY)"; + } + StringBuffer buf = new StringBuffer(); + for (Iterator<TreePath> itr = map.keySet().iterator(); itr.hasNext(); ) { + buf.append("\n\t\t"); + TreePath path = itr.next(); + buf.append(toString(path)); + Set<?> updates = map.get(path); + buf.append(" = "); + buf.append(updates.toString()); + } + return buf.toString(); + } + + private String toString(TreePath path) { + if (path.getSegmentCount() == 0) { + return "/"; + } + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < path.getSegmentCount(); i++) { + buf.append("/"); + buf.append(path.getSegment(i)); + } + return buf.toString(); + } + + @Override + public String toString() { + return toString(ALL_UPDATES_COMPLETE | MODEL_CHANGED_COMPLETE | STATE_RESTORE_COMPLETE); + } +} + + diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestModelVMAdapter.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestModelVMAdapter.java new file mode 100644 index 00000000000..97e83b37a23 --- /dev/null +++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestModelVMAdapter.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.tests.dsf.vm; + +import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMAdapter; +import org.eclipse.cdt.dsf.ui.viewmodel.IVMProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; + +/** + * + */ +public class TestModelVMAdapter extends AbstractVMAdapter { + + @Override + protected IVMProvider createViewModelProvider(IPresentationContext context) { + return new TestModelVMProvider(this, context); + } + + public TestModelVMProvider getTestModelProvider(IPresentationContext context) { + return (TestModelVMProvider)getVMProvider(context); + } +} diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestModelVMNode.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestModelVMNode.java new file mode 100644 index 00000000000..52dc0dcced2 --- /dev/null +++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestModelVMNode.java @@ -0,0 +1,131 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.tests.dsf.vm; + +import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; +import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants; +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMNode; +import org.eclipse.cdt.dsf.ui.viewmodel.IRootVMNode; +import org.eclipse.cdt.dsf.ui.viewmodel.IVMProvider; +import org.eclipse.cdt.dsf.ui.viewmodel.VMDelta; +import org.eclipse.cdt.dsf.ui.viewmodel.properties.IElementPropertiesProvider; +import org.eclipse.cdt.dsf.ui.viewmodel.properties.IPropertiesUpdate; +import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelAttribute; +import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelColumnInfo; +import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelText; +import org.eclipse.cdt.dsf.ui.viewmodel.properties.PropertiesBasedLabelProvider; +import org.eclipse.cdt.tests.dsf.vm.TestModel.TestElement; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; + +/** + * + */ +public class TestModelVMNode extends AbstractVMNode implements IRootVMNode, IElementLabelProvider, IElementPropertiesProvider { + + final private static String PROP_TEST_ELEMENT_LABEL = "PROP_TEST_ELEMENT_LABEL"; + + final private static PropertiesBasedLabelProvider fLabelProvider = new PropertiesBasedLabelProvider(); + { + fLabelProvider.setColumnInfo( + PropertiesBasedLabelProvider.ID_COLUMN_NO_COLUMNS, + new LabelColumnInfo(new LabelAttribute[] { + new LabelText("{0}", new String[] { PROP_TEST_ELEMENT_LABEL }) + })); + } + + public void update(final ILabelUpdate[] updates) { + fLabelProvider.update(updates); + } + + public TestModelVMNode(IVMProvider provider) { + super(provider); + } + + public void update(IHasChildrenUpdate[] updates) { + for (IHasChildrenUpdate update : updates) { + if (update.getElement() instanceof TestElementVMContext) { + TestElement element = ((TestElementVMContext)update.getElement()).getElement(); + update.setHasChilren(element.getChildren().length != 0); + } + update.done(); + } + } + + public void update(IChildrenCountUpdate[] updates) { + for (IChildrenCountUpdate update : updates) { + if (update.getElement() instanceof TestElementVMContext) { + TestElement element = ((TestElementVMContext)update.getElement()).getElement(); + update.setChildCount(element.getChildren().length); + } + update.done(); + } + } + + public void update(IChildrenUpdate[] updates) { + for (IChildrenUpdate update : updates) { + if (update.getElement() instanceof TestElementVMContext) { + TestElement element = ((TestElementVMContext)update.getElement()).getElement(); + fillUpdateWithTestElements(update, element.getChildren()); + } + update.done(); + } + } + + public void update(IPropertiesUpdate[] updates) { + for (IPropertiesUpdate update : updates) { + if (update.getElement() instanceof TestElementVMContext) { + TestElement element = ((TestElementVMContext)update.getElement()).getElement(); + update.setProperty(PROP_TEST_ELEMENT_LABEL, element.getLabel()); + } + update.done(); + } + } + + private void fillUpdateWithTestElements(IChildrenUpdate update, TestElement[] elements) { + int updateIdx = update.getOffset() != -1 ? update.getOffset() : 0; + int endIdx = updateIdx + (update.getLength() != -1 ? update.getLength() : elements.length); + while (updateIdx < endIdx && updateIdx < elements.length) { + update.setChild(createVMContext(elements[updateIdx]), updateIdx); + updateIdx++; + } + } + + public TestElementVMContext createVMContext(TestElement element) { + return new TestElementVMContext(this, element); + } + + public int getDeltaFlags(Object event) { + return 0; + } + + public void buildDelta(Object event, VMDelta parent, int nodeOffset, RequestMonitor rm) { + rm.done(); + } + + + public boolean isDeltaEvent(Object rootObject, Object event) { + return false; + } + + public void createRootDelta(Object rootObject, Object event, DataRequestMonitor<VMDelta> rm) { + rm.setStatus(new Status(IStatus.ERROR, TestDsfVMPlugin.PLUGIN_ID, IDsfStatusConstants.NOT_SUPPORTED, "Not implemented", null)); + rm.done(); + } + + +} diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestModelVMProvider.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestModelVMProvider.java new file mode 100644 index 00000000000..42cbe47bf88 --- /dev/null +++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestModelVMProvider.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.tests.dsf.vm; + +import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMAdapter; +import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMProvider; +import org.eclipse.cdt.dsf.ui.viewmodel.IVMModelProxy; +import org.eclipse.cdt.dsf.ui.viewmodel.IVMNode; +import org.eclipse.cdt.tests.dsf.vm.TestModel.TestElement; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; + +/** + * + */ +public class TestModelVMProvider extends AbstractVMProvider { + public TestModelVMProvider(AbstractVMAdapter adapter, IPresentationContext context) { + super(adapter, context); + + setRootNode(new TestModelVMNode(this)); + addChildNodes(getRootVMNode(), new IVMNode[] { getRootVMNode() }); + } + + + public TestElementVMContext getElementVMContext(IPresentationContext context, TestElement element) { + return ((TestModelVMNode)getRootVMNode()).createVMContext(element); + } + + public void postDelta(IModelDelta delta) { + for (IVMModelProxy proxy : getActiveModelProxies()) { + proxy.fireModelChanged(delta); + } + } +} diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/VirtualViewerPerformanceTests.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/VirtualViewerPerformanceTests.java new file mode 100644 index 00000000000..4dbdc8bd6fc --- /dev/null +++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/VirtualViewerPerformanceTests.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2009 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.tests.dsf.vm; + +import org.eclipse.debug.internal.ui.viewers.model.ITreeModelContentProviderTarget; +import org.eclipse.debug.internal.ui.viewers.model.provisional.PresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.VirtualTreeModelViewer; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +/** + * @since 3.6 + */ +public class VirtualViewerPerformanceTests extends PerformanceTests { + + public VirtualViewerPerformanceTests(String name) { + super(name); + } + + @Override + protected ITreeModelContentProviderTarget createViewer(Display display, Shell shell) { + return new VirtualTreeModelViewer(fDisplay, 0, new PresentationContext("TestViewer")); + } + + @Override + protected int getTestModelDepth() { + return 7; + } +} |