mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-08 18:26:01 +02:00
[306982] - [concurrent] DsfRunnable.finalize() method increases the cost of garbage collecting 10x
This commit is contained in:
parent
79c61294f9
commit
04709d2876
14 changed files with 1978 additions and 4 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue