diff --git a/dsf/org.eclipse.cdt.dsf.ui/plugin.xml b/dsf/org.eclipse.cdt.dsf.ui/plugin.xml
index f812e3d5da5..acaf81f9678 100644
--- a/dsf/org.eclipse.cdt.dsf.ui/plugin.xml
+++ b/dsf/org.eclipse.cdt.dsf.ui/plugin.xml
@@ -156,6 +156,20 @@
+
+
+
+
+
+
+
+
+
@@ -342,6 +384,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
actions = new ArrayList(FORMATS.size());
+ for (String formatId : FORMATS) {
+ actions.add(new SelectFormatAction((IElementFormatProvider) provider,
+ context, nodes, viewerInput, elementPaths, formatId));
+ }
+ CountingRequestMonitor crm = new CountingRequestMonitor(SimpleDisplayExecutor.getSimpleDisplayExecutor(Display.getDefault()), null) {
+ @Override
+ protected void handleCompleted() {
+ String activeFormat = null;
+ for (int i = 0; i < formats.length; i++) {
+ if (i == 0) {
+ activeFormat = formats[i];
+ } else if (activeFormat != null
+ && activeFormat.equals(formats[i]) == false) {
+ activeFormat = null;
+ }
+ }
+ if (activeFormat != null) {
+ for (int i = 0; i < actions.size(); i++) {
+ if (activeFormat.equals(actions.get(i).fFormatId)) {
+ actions.get(i).setChecked(true);
+ }
+ }
+ }
+ }
+ };
+ for (int i = 0; i < elementPaths.length; i++) {
+ Object segment = elementPaths[i].getLastSegment();
+ if (segment instanceof IVMContext) {
+ nodes[i] = ((IVMContext) segment).getVMNode();
+ } else {
+ nodes[i] = null;
+ }
+ final int index = i;
+ ((IElementFormatProvider) provider).getActiveFormat(context, nodes[i], viewerInput, elementPaths[i],
+ new DataRequestMonitor(ImmediateExecutor.getInstance(), crm) {
+ @Override
+ protected void handleSuccess() {
+ formats[index] = this.getData();
+ super.handleSuccess();
+ }
+ });
+ }
+ crm.setDoneCount(elementPaths.length);
+ int count = actions.size();
+ IContributionItem[] items = new IContributionItem[count + 2];
+ for (int i = 0; i < actions.size(); i++) {
+ items[i] = new ActionContributionItem(actions.get(i));
+ }
+ items[count] = new Separator();
+ items[count + 1] = new ActionContributionItem(new SelectFormatAction(
+ (IElementFormatProvider) provider, context, nodes, viewerInput, elementPaths, null));
+ return items;
+ }
+}
diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/numberformat/FormattedValueRetriever.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/numberformat/FormattedValueRetriever.java
index f9f389c6885..25d161a364a 100644
--- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/numberformat/FormattedValueRetriever.java
+++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/numberformat/FormattedValueRetriever.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2009, 2010 Wind River Systems and others.
+ * Copyright (c) 2009, 2011 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,6 +7,7 @@
*
* Contributors:
* Wind River Systems - initial API and implementation
+ * Winnie Lai (Texas Instruments) - Individual Element Number Format (Bug 202556)
*******************************************************************************/
package org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat;
@@ -14,6 +15,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -37,6 +39,7 @@ import org.eclipse.cdt.dsf.service.DsfServices;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.dsf.ui.concurrent.ViewerDataRequestMonitor;
import org.eclipse.cdt.dsf.ui.viewmodel.IVMNode;
+import org.eclipse.cdt.dsf.ui.viewmodel.IVMProvider;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.IPropertiesUpdate;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.PropertiesUpdateStatus;
@@ -70,6 +73,7 @@ public class FormattedValueRetriever {
private final IVMNode fNode;
private final ICachingVMProviderExtension2 fCache;
+ private final IElementFormatProvider fElementFormatProvider;
private final ServiceTracker fServiceTracker;
private final Class extends IFormattedDataDMContext> fDmcType;
private final String fPropertyPrefix;
@@ -90,6 +94,8 @@ public class FormattedValueRetriever {
public FormattedValueRetriever(IVMNode node, Filter filter, Class extends IFormattedDataDMContext> dmcType, String propertyPrefix) {
fNode = node;
fCache = (ICachingVMProviderExtension2)node.getVMProvider();
+ IVMProvider vmprovider = fNode.getVMProvider();
+ fElementFormatProvider = vmprovider instanceof IElementFormatProvider ? (IElementFormatProvider) vmprovider : null;
fServiceTracker = new ServiceTracker(DsfUIPlugin.getBundleContext(), filter, null);
fServiceTracker.open();
fDmcType = dmcType;
@@ -152,45 +158,112 @@ public class FormattedValueRetriever {
@ConfinedToDsfExecutor("node.getExecutor()")
public void update(final IPropertiesUpdate updates[], final RequestMonitor rm)
{
- final Map cachedAvailableFormatsMap = calcCachedAvailableFormatsMap(updates);
- if (cachedAvailableFormatsMap != null && cachedAvailableFormatsMap.size() == updates.length) {
- // All updates were satisfied by the cache.
- doUpdateWithAvailableFormats(updates, cachedAvailableFormatsMap, rm);
- } else {
- final IFormattedValues service = (IFormattedValues)fServiceTracker.getService();
- if (service == null) {
- rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.REQUEST_FAILED, "Service not available " + fServiceTracker, null)); //$NON-NLS-1$
- rm.done();
- return;
+ retreiveElementActiveFormat(updates, new DataRequestMonitor
+
+
+
-->
diff --git a/dsf/org.eclipse.cdt.examples.dsf.pda.ui/src/org/eclipse/cdt/examples/dsf/pda/ui/viewmodel/PDAExpressionVMProvider.java b/dsf/org.eclipse.cdt.examples.dsf.pda.ui/src/org/eclipse/cdt/examples/dsf/pda/ui/viewmodel/PDAExpressionVMProvider.java
new file mode 100644
index 00000000000..e3a7340d3fb
--- /dev/null
+++ b/dsf/org.eclipse.cdt.examples.dsf.pda.ui/src/org/eclipse/cdt/examples/dsf/pda/ui/viewmodel/PDAExpressionVMProvider.java
@@ -0,0 +1,115 @@
+/*****************************************************************
+ * Copyright (c) 2011 Texas Instruments and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Winnie Lai (Texas Instruments) - Individual Element Number Format example (Bug 202556)
+ *****************************************************************/
+package org.eclipse.cdt.examples.dsf.pda.ui.viewmodel;
+
+import java.util.ArrayList;
+
+import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
+import org.eclipse.cdt.dsf.datamodel.DMContexts;
+import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext;
+import org.eclipse.cdt.dsf.debug.ui.viewmodel.expression.ExpressionVMProvider;
+import org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat.IElementFormatProvider;
+import org.eclipse.cdt.dsf.debug.ui.viewmodel.variable.VariableVMNode;
+import org.eclipse.cdt.dsf.service.DsfSession;
+import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMAdapter;
+import org.eclipse.cdt.dsf.ui.viewmodel.IVMContext;
+import org.eclipse.cdt.dsf.ui.viewmodel.IVMNode;
+import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
+import org.eclipse.debug.core.model.IExpression;
+import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
+import org.eclipse.jface.viewers.TreePath;
+
+/**
+ * PDA View Model provider for the expression view.
+ */
+@SuppressWarnings("restriction")
+public class PDAExpressionVMProvider extends ExpressionVMProvider implements IElementFormatProvider {
+
+ static String myPersistId = "org.eclipse.cdt.examples.dsf.pda.ui.variablePersistable";
+
+ public PDAExpressionVMProvider(AbstractVMAdapter adapter, IPresentationContext context, DsfSession session) {
+ super(adapter, context, session);
+ }
+
+ public void getActiveFormat(IPresentationContext context, IVMNode node, Object viewerInput, TreePath elementPath,
+ DataRequestMonitor rm) {
+ Object p = context.getProperty(myPersistId);
+ if (p instanceof VariablePersistable == false) {
+ rm.setData(null);
+ rm.done();
+ return;
+ }
+ VariablePersistable persistable = (VariablePersistable) p;
+ Object x = elementPath.getLastSegment();
+ if (x instanceof VariableVMNode.VariableExpressionVMC) {
+ IExpressionDMContext ctx = DMContexts.getAncestorOfType(((VariableVMNode.VariableExpressionVMC) x).getDMContext(), IExpressionDMContext.class);
+ if (ctx == null) {
+ rm.setData(null);
+ } else {
+ rm.setData(persistable.getFormat(ctx.getExpression()));
+ }
+ rm.done();
+ return;
+ } else if (x instanceof IDMVMContext) {
+ // register and bit field context are covered here.
+ // When these show up in expression view, the register/bit field vm node's associateExpression has called
+ // RegisterVMC/BitFieldVMC's setExpression
+ IExpression y = (IExpression) ((IVMContext) x).getAdapter(IExpression.class);
+ if (y == null) {
+ rm.setData(null);
+ } else {
+ rm.setData(persistable.getFormat(y.getExpressionText()));
+ }
+ rm.done();
+ return;
+ }
+ rm.setData(null);
+ rm.done();
+ return;
+ }
+
+ public void setActiveFormat(IPresentationContext context, IVMNode[] node, Object viewerInput, TreePath[] elementPath, String format) {
+ Object p = context.getProperty(myPersistId);
+ VariablePersistable persistable = null;
+ if (p instanceof VariablePersistable) {
+ persistable = (VariablePersistable) p;
+ } else {
+ persistable = new VariablePersistable();
+ context.setProperty(myPersistId, persistable);
+ }
+ ArrayList changed = new ArrayList(elementPath.length);
+ for (int i = 0; i < elementPath.length; i++) {
+ Object x = elementPath[i].getLastSegment();
+ if (x instanceof VariableVMNode.VariableExpressionVMC) {
+ IExpressionDMContext ctx = DMContexts.getAncestorOfType(((VariableVMNode.VariableExpressionVMC) x).getDMContext(), IExpressionDMContext.class);
+ if (ctx == null)
+ continue;
+ persistable.setFormat(ctx.getExpression(), format);
+ changed.add((IDMVMContext) x);
+ } else if (x instanceof IDMVMContext) {
+ IExpression y = (IExpression) ((IVMContext) x).getAdapter(IExpression.class);
+ if (y == null)
+ continue;
+ persistable.setFormat(y.getExpressionText(), format);
+ }
+ }
+ if (changed.size() > 0) {
+ refresh();
+ }
+ }
+
+ public boolean supportFormat(IVMContext context) {
+ if (context instanceof VariableVMNode.VariableExpressionVMC) {
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/dsf/org.eclipse.cdt.examples.dsf.pda.ui/src/org/eclipse/cdt/examples/dsf/pda/ui/viewmodel/PDAVMAdapter.java b/dsf/org.eclipse.cdt.examples.dsf.pda.ui/src/org/eclipse/cdt/examples/dsf/pda/ui/viewmodel/PDAVMAdapter.java
index 530e2a35385..93e12289e65 100644
--- a/dsf/org.eclipse.cdt.examples.dsf.pda.ui/src/org/eclipse/cdt/examples/dsf/pda/ui/viewmodel/PDAVMAdapter.java
+++ b/dsf/org.eclipse.cdt.examples.dsf.pda.ui/src/org/eclipse/cdt/examples/dsf/pda/ui/viewmodel/PDAVMAdapter.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2009 Wind River Systems and others.
+ * Copyright (c) 2006, 2011 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,13 +7,14 @@
*
* Contributors:
* Wind River Systems - initial API and implementation
+ * Winnie Lai (Texas Instruments) - Individual Element Number Format example (Bug 202556)
*******************************************************************************/
package org.eclipse.cdt.examples.dsf.pda.ui.viewmodel;
import org.eclipse.cdt.dsf.concurrent.ThreadSafe;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.AbstractDebugVMAdapter;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.SteppingController;
-import org.eclipse.cdt.dsf.debug.ui.viewmodel.expression.ExpressionVMProvider;
+//import org.eclipse.cdt.dsf.debug.ui.viewmodel.expression.ExpressionVMProvider;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.register.RegisterVMProvider;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.variable.VariableVMProvider;
import org.eclipse.cdt.dsf.service.DsfSession;
@@ -45,7 +46,7 @@ public class PDAVMAdapter extends AbstractDebugVMAdapter
} else if (IDebugUIConstants.ID_VARIABLE_VIEW.equals(context.getId()) ) {
return new VariableVMProvider(this, context, getSession());
} else if (IDebugUIConstants.ID_EXPRESSION_VIEW.equals(context.getId()) ) {
- return new ExpressionVMProvider(this, context, getSession());
+ return new PDAExpressionVMProvider(this, context, getSession());
} else if (IDebugUIConstants.ID_REGISTER_VIEW.equals(context.getId()) ) {
return new RegisterVMProvider(this, context, getSession());
}
diff --git a/dsf/org.eclipse.cdt.examples.dsf.pda.ui/src/org/eclipse/cdt/examples/dsf/pda/ui/viewmodel/VariablePersistable.java b/dsf/org.eclipse.cdt.examples.dsf.pda.ui/src/org/eclipse/cdt/examples/dsf/pda/ui/viewmodel/VariablePersistable.java
new file mode 100644
index 00000000000..e723b106548
--- /dev/null
+++ b/dsf/org.eclipse.cdt.examples.dsf.pda.ui/src/org/eclipse/cdt/examples/dsf/pda/ui/viewmodel/VariablePersistable.java
@@ -0,0 +1,81 @@
+/*****************************************************************
+ * Copyright (c) 2011 Texas Instruments and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Winnie Lai (Texas Instruments) - Individual Element Number Format example (Bug 202556)
+ *****************************************************************/
+package org.eclipse.cdt.examples.dsf.pda.ui.viewmodel;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map.Entry;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.IPersistableElement;
+
+/**
+ * Variable persistable for variable settings
+ */
+class VariablePersistable implements IPersistableElement, IAdaptable {
+
+ HashMap map = new HashMap();
+
+ public void saveState(IMemento memento) {
+ HashMap clone = null;
+ synchronized (map) {
+ clone = new HashMap(map);
+ }
+ Iterator > it = clone.entrySet().iterator();
+ while (it.hasNext()) {
+ Entry entry = it.next();
+ IMemento value = memento.createChild("variable", entry.getKey());
+ value.putString("format", entry.getValue());
+ }
+ }
+
+ void restore(IMemento memento) {
+ IMemento[] list = memento.getChildren("variable");
+ HashMap clone = new HashMap();
+ for (int i = 0; i < list.length; i++) {
+ clone.put(list[i].getID(), list[i].getString("format"));
+ }
+ synchronized(map) {
+ map.clear();
+ map.putAll(clone);
+ }
+ }
+
+ String getFormat(String key) {
+ if (key == null)
+ return null;
+ synchronized (map) {
+ return map.get(key);
+ }
+ }
+
+ void setFormat(String key, String format) {
+ synchronized (map) {
+ if (format == null) {
+ map.remove(key);
+ } else {
+ map.put(key, format);
+ }
+ }
+ }
+
+ public String getFactoryId() {
+ return VariablePersistableFactory.getFactoryId();
+ }
+
+ public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) {
+ if (adapter.isInstance(this)) {
+ return this;
+ }
+ return null;
+ }
+}
diff --git a/dsf/org.eclipse.cdt.examples.dsf.pda.ui/src/org/eclipse/cdt/examples/dsf/pda/ui/viewmodel/VariablePersistableFactory.java b/dsf/org.eclipse.cdt.examples.dsf.pda.ui/src/org/eclipse/cdt/examples/dsf/pda/ui/viewmodel/VariablePersistableFactory.java
new file mode 100644
index 00000000000..914fd8c6056
--- /dev/null
+++ b/dsf/org.eclipse.cdt.examples.dsf.pda.ui/src/org/eclipse/cdt/examples/dsf/pda/ui/viewmodel/VariablePersistableFactory.java
@@ -0,0 +1,32 @@
+/*****************************************************************
+ * Copyright (c) 2011 Texas Instruments and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Winnie Lai (Texas Instruments) - Individual Element Number Format example (Bug 202556)
+ *****************************************************************/
+package org.eclipse.cdt.examples.dsf.pda.ui.viewmodel;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.ui.IElementFactory;
+import org.eclipse.ui.IMemento;
+
+/**
+ * Variable persistable factory for VariablePersistable
+ */
+public class VariablePersistableFactory implements IElementFactory {
+
+ public static String getFactoryId() {
+ return "org.eclipse.cdt.examples.dsf.pda.ui.variablePersitableFactory";
+ }
+
+ public IAdaptable createElement(IMemento memento) {
+ VariablePersistable x = new VariablePersistable();
+ x.restore(memento);
+ return x;
+ }
+
+}
diff --git a/dsf/org.eclipse.cdt.tests.dsf/plugin.xml b/dsf/org.eclipse.cdt.tests.dsf/plugin.xml
index 4b4d7a573fc..43c8fe3c95d 100644
--- a/dsf/org.eclipse.cdt.tests.dsf/plugin.xml
+++ b/dsf/org.eclipse.cdt.tests.dsf/plugin.xml
@@ -32,5 +32,12 @@
markerType="markerType.breakpoint"
id="org.eclipse.cdt.tests.dsf.breakpoint"/>
+
+
+
+
diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/FormattedValueTests.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/FormattedValueTests.java
index e7abbd8ba42..d6a473cc30c 100644
--- a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/FormattedValueTests.java
+++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/FormattedValueTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2009, 2010 Wind River Systems and others.
+ * Copyright (c) 2009, 2011 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,9 +7,12 @@
*
* Contributors:
* Wind River Systems - initial API and implementation
+ * Winnie Lai (Texas Instruments) - Individual Element Number Format test cases (Bug 202556)
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.vm;
+import java.util.ArrayList;
+import java.util.HashMap;
import java.util.concurrent.ExecutionException;
import junit.framework.Assert;
@@ -24,9 +27,11 @@ import org.eclipse.cdt.dsf.concurrent.Query;
import org.eclipse.cdt.dsf.debug.service.IFormattedValues;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.IDebugVMConstants;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat.FormattedValueVMUtil;
+import org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat.IElementFormatProvider;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.dsf.service.IDsfService;
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMAdapter;
+import org.eclipse.cdt.dsf.ui.viewmodel.IVMNode;
import org.eclipse.cdt.dsf.ui.viewmodel.IVMProvider;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.IPropertiesUpdate;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.PropertiesUpdateStatus;
@@ -40,12 +45,14 @@ import org.eclipse.debug.internal.ui.viewers.model.ITreeModelContentProviderTarg
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.IPresentationContext;
+import org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewer;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.ViewerLabel;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.XMLMemento;
/**
* Tests to verify the operation of FormattedValuesVMUtil
@@ -65,6 +72,7 @@ abstract public class FormattedValueTests extends TestCase implements IViewerUpd
DummyFormattedValueService fDummyValuesService;
AbstractVMAdapter fVMAdapter;
TestModelCachingVMProvider fVMProvider;
+ int vmListenerLevel = -1;
public FormattedValueTests(String name) {
super(name);
@@ -114,6 +122,63 @@ abstract public class FormattedValueTests extends TestCase implements IViewerUpd
fShell.open ();
}
+ /**
+ * helper to create view model and viewer
+ * @param vmOnly true to create view model only and do not create viewer
+ */
+ void createViewer(boolean vmOnly) {
+ if (vmOnly == false) {
+ 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);
+ fViewerListener = new TestModelUpdatesListener(fViewer, true, false);
+ }
+ fVMProvider = new TestElementFormatVMProvider(fVMAdapter, fViewer.getPresentationContext(), fDsfSession);
+ fVMListener = new TestModelUpdatesListener();
+ fVMProvider.getNode().setVMUpdateListener(fVMListener);
+ fVMProvider.getNode().getLabelProvider().addPropertiesUpdateListener(fViewerListener);
+ fVMProvider.getNode().setFormattedValuesListener(fFormattedValuesListener);
+ if (vmOnly == false) {
+ fShell.open();
+ }
+ }
+
+ /**
+ * helper to destory view model and viewer
+ * @param vmOnly true to destory view model only and do not destroy viewer
+ */
+ void destroyViewer(boolean vmOnly) {
+ fVMProvider.getNode().setFormattedValuesListener(null);
+ fVMProvider.getNode().getLabelProvider().removePropertiesUpdateListener(fViewerListener);
+ fVMProvider.getNode().setVMUpdateListener(null);
+ fVMListener.dispose();
+ if (vmOnly == false) {
+ fViewerListener.dispose();
+ fViewer.getPresentationContext().dispose();
+ // Close the shell
+ fShell.close();
+ while (!fShell.isDisposed()) if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
+ }
+ }
+
+ /**
+ * helper to recreate view model only
+ */
+ void recreateViewModel() {
+ destroyViewer(true);
+ createViewer(true);
+ }
+
+ /**
+ * helper to recreate viewer (and view model)
+ */
+ void recreateViewer() {
+ destroyViewer(false);
+ createViewer(false);
+ }
+
private void initializeService(final IDsfService service) throws InterruptedException, ExecutionException {
Query initQuery = new Query() {
@Override
@@ -239,6 +304,389 @@ abstract public class FormattedValueTests extends TestCase implements IViewerUpd
" (" + DummyFormattedValueService.DUMMY_FORMAT + ")");
}
+ /**
+ * Test that each element can have its own format
+ */
+ public void testValidateElement() {
+ recreateViewModel();
+ String preferenceFormat = IFormattedValues.NATURAL_FORMAT;
+ setInput(preferenceFormat);
+ // set each element to the same element format different than the preference format, and verify
+ HashMap map = new HashMap();
+ String[] format = { IFormattedValues.HEX_FORMAT };
+ makeElementFormatSetting(fViewer, TreePath.EMPTY, format, -1, 0, map);
+ ArrayList elementFormats = new ArrayList(map.values());
+ setFormatAndValidate(preferenceFormat, elementFormats, elementFormats, true, false, false);
+ // element of same level use the same format and different levels have different formats, and verify
+ map.clear();
+ format = new String[] { IFormattedValues.HEX_FORMAT, IFormattedValues.DECIMAL_FORMAT,
+ IFormattedValues.OCTAL_FORMAT, IFormattedValues.BINARY_FORMAT,
+ IFormattedValues.NATURAL_FORMAT };
+ makeElementFormatSetting(fViewer, TreePath.EMPTY, format, -1, 0, map);
+ elementFormats = new ArrayList(map.values());
+ setFormatAndValidate(preferenceFormat, elementFormats, elementFormats, false, false, false);
+ }
+
+ /**
+ * Test that each element can change to a format and then restore to preference format
+ */
+ public void testChangeElementFormat() {
+ recreateViewModel();
+ String preferenceFormat = IFormattedValues.HEX_FORMAT;
+ setInput(IFormattedValues.NATURAL_FORMAT);
+ setFormatAndValidate(preferenceFormat, false, false, false);
+ // set each element to a format, and verify
+ HashMap map = new HashMap();
+ String[] format = { IFormattedValues.HEX_FORMAT, IFormattedValues.DECIMAL_FORMAT,
+ IFormattedValues.OCTAL_FORMAT, IFormattedValues.BINARY_FORMAT,
+ IFormattedValues.NATURAL_FORMAT };
+ makeElementFormatSetting(fViewer, TreePath.EMPTY, format, -1, 0, map);
+ ArrayList elementFormats = new ArrayList(map.values());
+ setFormatAndValidate(preferenceFormat, elementFormats, elementFormats, false, false, false);
+ // Restore each element to preference format, and verify
+ for (ElementFormatSetting e : elementFormats) {
+ e.formatId = null;
+ }
+ setFormatAndValidate(preferenceFormat, elementFormats, elementFormats, false, false, false);
+ }
+
+ /**
+ * Test changing element to a format and then restore to preference format,
+ * using a view model provider that applies a format to child elements
+ * of a certain level of depth.
+ */
+ public void testChangeElementFormatApplyDepth() {
+ recreateViewModel();
+ if (fVMProvider instanceof TestElementFormatVMProvider == false) {
+ return;
+ }
+ TestElementFormatVMProvider myVM = (TestElementFormatVMProvider) fVMProvider;
+ String preferenceFormat = IFormattedValues.HEX_FORMAT;
+ setInput(IFormattedValues.NATURAL_FORMAT);
+ setFormatAndValidate(preferenceFormat, false, false, false);
+ int[] myDepths = new int[] { -1, 2 };
+ for (int depth : myDepths) {
+ myVM.elementFormatApplyDepth = depth;
+ // set top level element to a format, and verify top and child elements
+ // at certain levels have the correct format.
+ String[] format = { IFormattedValues.DECIMAL_FORMAT };
+ HashMap map = new HashMap();
+ makeElementFormatSetting(fViewer, TreePath.EMPTY, format, 1, 0, map);
+ ArrayList setElementFormats = new ArrayList(map.values());
+ HashMap expMap = new HashMap();
+ makeElementFormatSetting(fViewer, TreePath.EMPTY, format, depth, 0, expMap);
+ ArrayList expectElementFormats = new ArrayList(expMap.values());
+ setFormatAndValidate(preferenceFormat, setElementFormats, expectElementFormats, false, false, false);
+ // Restore top level element to preference format, and verify.
+ for (ElementFormatSetting e : setElementFormats) {
+ e.formatId = null;
+ }
+ for (ElementFormatSetting e : expectElementFormats) {
+ e.formatId = null;
+ }
+ setFormatAndValidate(preferenceFormat, setElementFormats, expectElementFormats, false, false, false);
+ }
+ }
+
+ /**
+ * Test changing format of each element under manual update policy.
+ * Formatted values should be retrieved from cache if available.
+ * Changing to a format whose formatted value is not in cache should get a cache miss error.
+ */
+ public void testChangeElementFormatManualUpdateMode() {
+ recreateViewModel();
+ String preferenceFormat = IFormattedValues.NATURAL_FORMAT;
+ setInput(IFormattedValues.NATURAL_FORMAT);
+ setUpdatePolicy(ManualUpdatePolicy.MANUAL_UPDATE_POLICY_ID);
+
+ // Change to a new format, this does not cause the cache entries to be
+ // set to dirty. Retrieving new format values should happen from the service.
+ HashMap map1 = new HashMap();
+ String[] format1 = { IFormattedValues.HEX_FORMAT };
+ makeElementFormatSetting(fViewer, TreePath.EMPTY, format1, -1, 0, map1);
+ ArrayList elementFormats1 = new ArrayList(map1.values());
+ setFormatAndValidate(preferenceFormat, elementFormats1, elementFormats1, true, false, false);
+
+ // Remove element format and so restore back to preference - natural format. Values should be retrieved from cache.
+ HashMap map2 = new HashMap();
+ String[] format2 = { null };
+ makeElementFormatSetting(fViewer, TreePath.EMPTY, format2, -1, 0, map2);
+ ArrayList elementFormats2 = new ArrayList(map2.values());
+ setFormatAndValidate(preferenceFormat, elementFormats2, elementFormats2, true, true, false);
+
+ // Generate an event which will cause all cache entries to be marked dirty.
+ postEventInManualUpdateMode();
+
+ // Change back again to hex format. Values should be retrieved from cache.
+ setFormatAndValidate(preferenceFormat, elementFormats1, elementFormats1, true, true, false);
+
+ // Change to a decimal, which is not cached, values should come with an error.
+ HashMap map3 = new HashMap();
+ String[] format3 = { IFormattedValues.DECIMAL_FORMAT };
+ makeElementFormatSetting(fViewer, TreePath.EMPTY, format3, -1, 0, map3);
+ ArrayList elementFormats3 = new ArrayList(map3.values());
+ setFormatAndValidate(preferenceFormat, elementFormats3, elementFormats3, true, true, true);
+ }
+
+ /**
+ * Test changing element format under manual update policy,
+ * using a view model provider that applies a format to child elements
+ * of a certain level of depth.
+ */
+ public void testChangeElementFormatApplyDepthManualUpdateMode() {
+ int[] myDepths = new int[] { -1, 2 };
+ for (int depth : myDepths) {
+ recreateViewer();
+ if (fVMProvider instanceof TestElementFormatVMProvider == false) {
+ return;
+ }
+ TestElementFormatVMProvider myVM = (TestElementFormatVMProvider) fVMProvider;
+ String preferenceFormat = IFormattedValues.NATURAL_FORMAT;
+ setInput(IFormattedValues.NATURAL_FORMAT);
+ setUpdatePolicy(ManualUpdatePolicy.MANUAL_UPDATE_POLICY_ID);
+ myVM.elementFormatApplyDepth = depth;
+ // Change top level to a new format, this does not cause the cache entries to be
+ // set to dirty. Retrieving new format values should happen from the service.
+ String[] format1 = { IFormattedValues.HEX_FORMAT };
+ HashMap map1 = new HashMap();
+ makeElementFormatSetting(fViewer, TreePath.EMPTY, format1, 1, 0, map1);
+ ArrayList elementFormats1 = new ArrayList(map1.values());
+ HashMap expMap1 = new HashMap();
+ makeElementFormatSetting(fViewer, TreePath.EMPTY, format1, depth, 0, expMap1);
+ ArrayList expectElementFormats1 = new ArrayList(expMap1.values());
+ vmListenerLevel = depth;
+ setFormatAndValidate(preferenceFormat, elementFormats1, expectElementFormats1, true, false, false);
+
+ // Remove element format and so restore back to preference format - natural. Values should be retrieved from cache.
+ String[] format2 = { null };
+ HashMap map2 = new HashMap();
+ makeElementFormatSetting(fViewer, TreePath.EMPTY, format2, 1, 0, map2);
+ ArrayList elementFormats2 = new ArrayList(map2.values());
+ HashMap expMap2 = new HashMap();
+ makeElementFormatSetting(fViewer, TreePath.EMPTY, format2, depth, 0, expMap2);
+ ArrayList expectElementFormats2 = new ArrayList(expMap2.values());
+ setFormatAndValidate(preferenceFormat, elementFormats2, expectElementFormats2, true, true, false);
+
+ // Generate an event which will cause all cache entries to be marked dirty.
+ postEventInManualUpdateMode();
+
+ // Change back again to hex format. Values should be retrieved from cache.
+ setFormatAndValidate(preferenceFormat, elementFormats1, expectElementFormats1, true, true, false);
+
+ // Change to a decimal, which is not cached, values should come with an error.
+ String[] format3 = { IFormattedValues.DECIMAL_FORMAT };
+ HashMap map3 = new HashMap();
+ makeElementFormatSetting(fViewer, TreePath.EMPTY, format3, 1, 0, map3);
+ ArrayList elementFormats3 = new ArrayList(map3.values());
+ HashMap expMap3 = new HashMap();
+ makeElementFormatSetting(fViewer, TreePath.EMPTY, format3, depth, 0, expMap3);
+ ArrayList expectElementFormats3 = new ArrayList(expMap3.values());
+ setFormatAndValidate(preferenceFormat, elementFormats3, expectElementFormats3, true, true, true);
+ }
+ }
+
+ /**
+ * Test that when the preference format is invalid, each element can still change to a format.
+ * Also, each element can restore to the invalid preference format such that
+ * the element uses first available format from service.
+ */
+ public void testChangeElementFormatWithInvalidPreference() {
+ recreateViewModel();
+ String preferenceFormat = IFormattedValues.NATURAL_FORMAT;
+ setInput(preferenceFormat);
+ // set preference format to an invalid format and verify
+ setInvalidPreferenceAndVerify();
+ // set each element to a format, and verify
+ HashMap map = new HashMap();
+ String[] format = { IFormattedValues.HEX_FORMAT, IFormattedValues.DECIMAL_FORMAT,
+ IFormattedValues.OCTAL_FORMAT, IFormattedValues.BINARY_FORMAT,
+ IFormattedValues.NATURAL_FORMAT };
+ makeElementFormatSetting(fViewer, TreePath.EMPTY, format, -1, 0, map);
+ ArrayList elementFormats = new ArrayList(map.values());
+ setFormatAndValidate("invalid format", elementFormats, elementFormats, false, false, false);
+ // Restore each element to preference format which is an invalid format
+ for (ElementFormatSetting e : elementFormats) {
+ e.formatId = null;
+ }
+ fViewerListener.reset();
+ fViewerListener.addUpdates(TreePath.EMPTY, ((TestElementVMContext)fViewer.getInput()).getElement(), -1, ALL_UPDATES_COMPLETE | PROPERTY_UPDATES);
+ fVMListener.reset();
+ fVMListener.addUpdates(TreePath.EMPTY, fModel.getRootElement(), -1, ALL_UPDATES_COMPLETE | PROPERTY_UPDATES);
+ if (fVMProvider instanceof IElementFormatProvider) {
+ IElementFormatProvider ep = ((IElementFormatProvider) fVMProvider);
+ for (ElementFormatSetting es : elementFormats) {
+ ep.setActiveFormat(fViewer.getPresentationContext(),
+ es.nodes.toArray(new IVMNode[es.nodes.size()]), fViewer.getInput(),
+ es.elementPaths.toArray(new TreePath[es.elementPaths.size()]), es.formatId);
+ }
+ }
+ while (!fViewerListener.isFinished(ALL_UPDATES_COMPLETE | PROPERTY_UPDATES) || !fVMListener.isFinished(CONTENT_UPDATES | PROPERTY_UPDATES)) {
+ if (!fDisplay.readAndDispatch ()) {
+ fDisplay.sleep ();
+ }
+ }
+ // verify service's first available format is used
+ validateModel(IFormattedValues.HEX_FORMAT, " (" + FormattedValueVMUtil.getFormatLabel(IFormattedValues.HEX_FORMAT) + ")",
+ DummyFormattedValueService.DUMMY_FORMAT, " (" + DummyFormattedValueService.DUMMY_FORMAT + ")");
+ }
+
+ /**
+ * Test that when an element is set to to an invalid format, the element uses preference format.
+ */
+ public void testInvalidElementFormat() {
+ recreateViewModel();
+ String preferenceFormat = IFormattedValues.NATURAL_FORMAT;
+ setInput(preferenceFormat);
+ // set each element to an invalid format
+ setElementInvalidFormat();
+ // verify preference format is used when element format is invalid
+ validateModel(preferenceFormat, "");
+ }
+
+ /**
+ * Test that when an element is set to to an invalid format and the preference format is invalid,
+ * the element uses first available format from service.
+ */
+ public void testInvalidElementFormatWithInvalidPreference() {
+ recreateViewModel();
+ String preferenceFormat = IFormattedValues.NATURAL_FORMAT;
+ setInput(preferenceFormat);
+ // set preference format to an invalid format and verify
+ setInvalidPreferenceAndVerify();
+ // set each element to an invalid format
+ setElementInvalidFormat();
+ // verify service's first available format is used when element format and preference format are invalid
+ validateModel(IFormattedValues.HEX_FORMAT, " (" + FormattedValueVMUtil.getFormatLabel(IFormattedValues.HEX_FORMAT) + ")",
+ DummyFormattedValueService.DUMMY_FORMAT, " (" + DummyFormattedValueService.DUMMY_FORMAT + ")");
+ }
+
+ /**
+ * Test that element format can be persisted in memento and viewer
+ * can restore to the persisted settings.
+ */
+ public void testPersistElementFormat() {
+ recreateViewModel();
+ String preferenceFormat = IFormattedValues.HEX_FORMAT;
+ setInput(IFormattedValues.NATURAL_FORMAT);
+ setFormatAndValidate(preferenceFormat, false, false, false);
+ // set each element to a format, and verify
+ HashMap map = new HashMap();
+ String[] format = { IFormattedValues.HEX_FORMAT, IFormattedValues.DECIMAL_FORMAT,
+ IFormattedValues.OCTAL_FORMAT, IFormattedValues.BINARY_FORMAT,
+ IFormattedValues.NATURAL_FORMAT };
+ makeElementFormatSetting(fViewer, TreePath.EMPTY, format, -1, 0, map);
+ ArrayList elementFormats = new ArrayList(map.values());
+ setFormatAndValidate(preferenceFormat, elementFormats, elementFormats, false, false, false);
+ // save settings
+ XMLMemento memento = XMLMemento.createWriteRoot("TEST");
+ if (fViewer instanceof TreeModelViewer == false)
+ return;
+ ((TreeModelViewer) fViewer).saveState(memento);
+ // throw away any settings inside the viewer and create a new viewer
+ // with memento settings, this is the same effect resulted from closing
+ // and opening workspace again.
+ recreateViewer();
+ if (fViewer instanceof TreeModelViewer == false)
+ return;
+ ((TreeModelViewer) fViewer).initState(memento);
+ setInput(IFormattedValues.NATURAL_FORMAT);
+ preferenceFormat = (String) fViewer.getPresentationContext().getProperty(PROP_FORMATTED_VALUE_FORMAT_PREFERENCE);
+ validateModel(elementFormats, preferenceFormat, "", preferenceFormat, "");
+ }
+
+ /**
+ * helper class that stores some element paths and nodes using a certain format
+ */
+ class ElementFormatSetting {
+ ArrayList nodes;
+ ArrayList elementPaths;
+ String formatId;
+ }
+
+ /**
+ * helper to create element format settings for all children paths of a given element path.
+ * Tree paths at the same level will use the same format. Tree paths at different
+ * levels will use different formats.
+ * @param _viewer tree viewer
+ * @param path given element path
+ * @param formats formats to rotate for different levels of children tree paths
+ * @param levelStop depth to stop recursively walk down the children.
+ * @param levelIndex index to a format for a level of children
+ * @param result store the created element format settings
+ */
+ void makeElementFormatSetting(ITreeModelViewer _viewer, TreePath path, String[] formats,
+ int levelStop, int levelIndex, HashMap result) {
+ if (levelStop >= 0 && levelIndex >= levelStop)
+ return;
+ ITreeModelContentProviderTarget viewer = (ITreeModelContentProviderTarget)_viewer;
+ int childCount = viewer.getChildCount(path);
+ if (childCount == 0)
+ return;
+ String fmt = formats[levelIndex % formats.length];
+ ElementFormatSetting setting = result.get(fmt);
+ if (setting == null) {
+ setting = new ElementFormatSetting();
+ setting.nodes = new ArrayList(childCount);
+ setting.elementPaths = new ArrayList(childCount);
+ setting.formatId = fmt;
+ result.put(fmt, setting);
+ }
+ for (int i = 0; i < childCount; i++) {
+ Object viewerObject = viewer.getChildElement(path, i);
+ if (viewerObject instanceof TestElementVMContext) {
+ TreePath childPath = path.createChildPath(viewerObject);
+ setting.nodes.add(((TestElementVMContext)viewerObject).getVMNode());
+ setting.elementPaths.add(childPath);
+ makeElementFormatSetting(viewer, childPath, formats, levelStop, levelIndex + 1, result);
+ }
+ }
+ }
+
+ /**
+ * helper to set element to an invalid format
+ */
+ void setElementInvalidFormat() {
+ fViewerListener.reset();
+ fViewerListener.addUpdates(TreePath.EMPTY, ((TestElementVMContext)fViewer.getInput()).getElement(), -1, ALL_UPDATES_COMPLETE | PROPERTY_UPDATES);
+ fVMListener.reset();
+ fVMListener.addUpdates(TreePath.EMPTY, fModel.getRootElement(), -1, ALL_UPDATES_COMPLETE | PROPERTY_UPDATES);
+ HashMap map = new HashMap();
+ String[] format = { "invalid element format" };
+ makeElementFormatSetting(fViewer, TreePath.EMPTY, format, -1, 0, map);
+ ArrayList elementFormats = new ArrayList(map.values());
+ if (fVMProvider instanceof IElementFormatProvider) {
+ IElementFormatProvider ep = ((IElementFormatProvider) fVMProvider);
+ for (ElementFormatSetting es : elementFormats) {
+ ep.setActiveFormat(fViewer.getPresentationContext(),
+ es.nodes.toArray(new IVMNode[es.nodes.size()]), fViewer.getInput(),
+ es.elementPaths.toArray(new TreePath[es.elementPaths.size()]), es.formatId);
+ }
+ }
+ while (!fViewerListener.isFinished(ALL_UPDATES_COMPLETE | PROPERTY_UPDATES) || !fVMListener.isFinished(CONTENT_UPDATES | PROPERTY_UPDATES)) {
+ if (!fDisplay.readAndDispatch ()) {
+ fDisplay.sleep ();
+ }
+ }
+ }
+
+ /**
+ * helper to set preference to an invalid format and verify.
+ */
+ void setInvalidPreferenceAndVerify() {
+ fViewerListener.reset();
+ fViewerListener.addUpdates(TreePath.EMPTY, ((TestElementVMContext)fViewer.getInput()).getElement(), -1, ALL_UPDATES_COMPLETE | PROPERTY_UPDATES);
+ fVMListener.reset();
+ fVMListener.addUpdates(TreePath.EMPTY, fModel.getRootElement(), -1, ALL_UPDATES_COMPLETE | PROPERTY_UPDATES);
+ fViewer.getPresentationContext().setProperty(PROP_FORMATTED_VALUE_FORMAT_PREFERENCE, "invalid format");
+ while (!fViewerListener.isFinished(ALL_UPDATES_COMPLETE | PROPERTY_UPDATES) || !fVMListener.isFinished(CONTENT_UPDATES | PROPERTY_UPDATES)) {
+ if (!fDisplay.readAndDispatch ()) {
+ fDisplay.sleep ();
+ }
+ }
+ validateModel(IFormattedValues.HEX_FORMAT, " (" + FormattedValueVMUtil.getFormatLabel(IFormattedValues.HEX_FORMAT) + ")",
+ DummyFormattedValueService.DUMMY_FORMAT, " (" + DummyFormattedValueService.DUMMY_FORMAT + ")");
+ }
+
/**
* Initial format is NATURAL.
*/
@@ -287,7 +735,17 @@ abstract public class FormattedValueTests extends TestCase implements IViewerUpd
}
private void setFormatAndValidate(
- String formatId,
+ String formatId,
+ boolean expectContentCached,
+ boolean expectFormattedValuesCached,
+ boolean expectCacheMissError) {
+ setFormatAndValidate(formatId, null, null, expectContentCached, expectFormattedValuesCached, expectCacheMissError);
+ }
+
+ private void setFormatAndValidate(
+ String formatId,
+ ArrayList setElementFormats,
+ ArrayList expectElementFormats,
boolean expectContentCached,
boolean expectFormattedValuesCached,
boolean expectCacheMissError)
@@ -300,29 +758,39 @@ abstract public class FormattedValueTests extends TestCase implements IViewerUpd
if (!expectContentCached) {
vmUpdateFlags |= ALL_UPDATES_COMPLETE;
}
- fVMListener.addUpdates(TreePath.EMPTY, fModel.getRootElement(), -1, vmUpdateFlags);
+ fVMListener.addUpdates(TreePath.EMPTY, fModel.getRootElement(), vmListenerLevel, vmUpdateFlags);
fFormattedValuesListener.reset();
if (expectFormattedValuesCached && !expectCacheMissError) {
fFormattedValuesListener.setCachedFormats(new String[] {formatId} );
}
+
+ if (fVMProvider instanceof IElementFormatProvider && setElementFormats != null) {
+ IElementFormatProvider ep = ((IElementFormatProvider) fVMProvider);
+ for (ElementFormatSetting es : setElementFormats) {
+ ep.setActiveFormat(fViewer.getPresentationContext(),
+ es.nodes.toArray(new IVMNode[es.nodes.size()]), fViewer.getInput(),
+ es.elementPaths.toArray(new TreePath[es.elementPaths.size()]), es.formatId);
+ }
+ } else {
+ // Set the new number format to the viewer.
+ fViewer.getPresentationContext().setProperty(PROP_FORMATTED_VALUE_FORMAT_PREFERENCE, formatId);
+ }
- // Set the new number format to the viewer.
- fViewer.getPresentationContext().setProperty(PROP_FORMATTED_VALUE_FORMAT_PREFERENCE, formatId);
while (!fViewerListener.isFinished(ALL_UPDATES_COMPLETE | PROPERTY_UPDATES) || !fVMListener.isFinished(CONTENT_UPDATES | PROPERTY_UPDATES))
if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
if (expectCacheMissError) {
try {
- validateModel(formatId, "");
+ validateModel(expectElementFormats, formatId, "", formatId, "");
throw new RuntimeException("Expected validateModel to fail");
}
catch(AssertionFailedError e) {
// expected
}
} else {
- validateModel(formatId, "");
+ validateModel(expectElementFormats, formatId, "", formatId, "");
}
if (expectCacheMissError) {
@@ -332,8 +800,23 @@ abstract public class FormattedValueTests extends TestCase implements IViewerUpd
Assert.assertFalse(fFormattedValuesListener.getPropertiesUpdates().isEmpty());
for (IPropertiesUpdate update : fFormattedValuesListener.getPropertiesUpdates()) {
PropertiesUpdateStatus status = (PropertiesUpdateStatus)update.getStatus();
- assertEquals(IDsfStatusConstants.INVALID_STATE, status.getCode());
- assertEquals("Cache contains stale data. Refresh view.", status.getStatus(formatProperty).getMessage());
+ assertEquals(IDsfStatusConstants.INVALID_STATE, status.getCode());
+ ElementFormatSetting elementFormat = null;
+ if (expectElementFormats != null) {
+ TreePath viewerPath = update.getElementPath();
+ for (ElementFormatSetting es : expectElementFormats) {
+ if (es.elementPaths.indexOf(viewerPath) >= 0) {
+ elementFormat = es;
+ break;
+ }
+ }
+ }
+ if (elementFormat != null) {
+ assertEquals("Cache contains stale data. Refresh view.", status.getStatus(
+ FormattedValueVMUtil.getPropertyForFormatId(elementFormat.formatId)).getMessage());
+ } else {
+ assertEquals("Cache contains stale data. Refresh view.", status.getStatus(formatProperty).getMessage());
+ }
assertEquals(
"Cache contains stale data. Refresh view.",
status.getStatus(PROP_FORMATTED_VALUE_ACTIVE_FORMAT_VALUE).getMessage());
@@ -352,18 +835,43 @@ abstract public class FormattedValueTests extends TestCase implements IViewerUpd
}
private void validateModel(final String formatId, final String suffix, final String dummyFormatId, final String dummySuffix) {
+ validateModel(null, formatId, suffix, dummyFormatId, dummySuffix);
+ }
+
+ private void validateModel(final ArrayList elementFormats,
+ final String formatId, final String suffix, final String dummyFormatId, final String dummySuffix) {
fModel.validateData(
fViewer, TreePath.EMPTY,
new TestElementValidator() {
public void validate(TestElement modelElement, TestElement viewerElement, TreePath viewerPath) {
ViewerLabel label = fViewer.getElementLabel(viewerPath, TestModelCachingVMProvider.COLUMN_ID);
assertEquals(modelElement.getID(), label.getText());
-
+ ElementFormatSetting elementFormat = null;
+ if (elementFormats != null) {
+ for (ElementFormatSetting es : elementFormats) {
+ if (es.elementPaths.indexOf(viewerPath) >= 0) {
+ elementFormat = es;
+ break;
+ }
+ }
+ }
label = fViewer.getElementLabel(viewerPath, TestModelCachingVMProvider.COLUMN_FORMATTED_VALUE);
- assertEquals(fModel.getFormattedValueText(modelElement, formatId) + suffix, label.getText());
+ if (elementFormat == null || elementFormat.formatId == null) {
+ assertEquals(fModel.getFormattedValueText(modelElement, formatId) + suffix, label.getText());
+ } else {
+ String suffix = elementFormat.formatId.equals(formatId) ? "" :
+ " (" + FormattedValueVMUtil.getFormatLabel(elementFormat.formatId) + ")";
+ assertEquals(fModel.getFormattedValueText(modelElement, elementFormat.formatId) + suffix , label.getText());
+ }
label = fViewer.getElementLabel(viewerPath, TestModelCachingVMProvider.COLUMN_DUMMY_VALUE);
- assertEquals(dummyFormatId + dummySuffix, label.getText());
+ if (elementFormat == null || elementFormat.formatId == null) {
+ assertEquals(dummyFormatId + dummySuffix, label.getText());
+ } else {
+ String suffix = elementFormat.formatId.equals(formatId) ? "" :
+ " (" + FormattedValueVMUtil.getFormatLabel(elementFormat.formatId) + ")";
+ assertEquals(elementFormat.formatId + suffix, label.getText());
+ }
}
});
}
diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestElementFormatVMProvider.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestElementFormatVMProvider.java
new file mode 100644
index 00000000000..79b1aa202ec
--- /dev/null
+++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestElementFormatVMProvider.java
@@ -0,0 +1,101 @@
+/*****************************************************************
+ * Copyright (c) 2011 Texas Instruments and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Winnie Lai (Texas Instruments) - Individual Element Number Format (Bug 202556)
+ *****************************************************************/
+package org.eclipse.cdt.tests.dsf.vm;
+
+import java.util.HashSet;
+
+import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
+import org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat.IElementFormatProvider;
+import org.eclipse.cdt.dsf.debug.ui.viewmodel.update.ElementFormatEvent;
+import org.eclipse.cdt.dsf.service.DsfSession;
+import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMAdapter;
+import org.eclipse.cdt.dsf.ui.viewmodel.IVMContext;
+import org.eclipse.cdt.dsf.ui.viewmodel.IVMNode;
+import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
+import org.eclipse.jface.viewers.TreePath;
+
+/**
+ * Test view model provider that supports element format provider interface.
+ * This class is used in test cases and can be extended to support other
+ * optional interfaces
+ */
+class TestElementFormatVMProvider extends TestModelCachingVMProvider implements IElementFormatProvider {
+ public int elementFormatApplyDepth = 1;
+ String myPersistId = "org.eclipse.cdt.tests.dsf.vm.testElementFormatVMProvider";
+
+ public TestElementFormatVMProvider(AbstractVMAdapter adapter,
+ IPresentationContext context, DsfSession session) {
+ super(adapter, context, session);
+ }
+
+ public void getActiveFormat(IPresentationContext context, IVMNode node,
+ Object viewerInput, TreePath elementPath, DataRequestMonitor rm) {
+ Object p = context.getProperty(myPersistId);
+ if (p instanceof TestPersistable == false) {
+ rm.setData(null);
+ rm.done();
+ return;
+ }
+ TestPersistable persistable = (TestPersistable) p;
+ int end = elementPath.getSegmentCount();
+ int start = elementPath.getSegmentCount() - 1;
+ if (elementFormatApplyDepth == -1) {
+ start = 0;
+ } else if (elementFormatApplyDepth >= 1) {
+ start = elementPath.getSegmentCount() - elementFormatApplyDepth;
+ }
+ if (start < 0)
+ start = 0;
+ for (int i = end; --i >= start;) {
+ Object x = elementPath.getSegment(i);
+ if (x instanceof TestElementVMContext) {
+ String s = ((TestElementVMContext) x).getElement().getID();
+ String format = persistable.getFormat(s);
+ if (format != null) {
+ rm.setData(format);
+ rm.done();
+ return;
+ }
+ }
+ }
+ rm.setData(null);
+ rm.done();
+ }
+
+ public void setActiveFormat(IPresentationContext context, IVMNode[] node,
+ Object viewerInput, TreePath[] elementPath, String format) {
+ Object p = context.getProperty(myPersistId);
+ TestPersistable persistable = null;
+ if (p instanceof TestPersistable) {
+ persistable = (TestPersistable) p;
+ } else {
+ persistable = new TestPersistable();
+ context.setProperty(myPersistId, persistable);
+ }
+ HashSet changed = new HashSet(elementPath.length);
+ for (int i = 0; i < elementPath.length; i++) {
+ Object x = elementPath[i].getLastSegment();
+ if (x instanceof TestElementVMContext) {
+ String s = ((TestElementVMContext) x).getElement().getID();
+ persistable.setFormat(s, format);
+ changed.add(x);
+ }
+ }
+ if (changed.size() > 0) {
+// this.refresh();
+ handleEvent(new ElementFormatEvent(changed, elementFormatApplyDepth));
+ }
+ }
+
+ public boolean supportFormat(IVMContext context) {
+ return true;
+ }
+}
diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestModelDMVMNode.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestModelDMVMNode.java
index 19f15555ec8..18119d10084 100644
--- a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestModelDMVMNode.java
+++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestModelDMVMNode.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008, 2010 Wind River Systems and others.
+ * Copyright (c) 2008, 2011 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,15 +7,20 @@
*
* Contributors:
* Wind River Systems - initial API and implementation
+ * Winnie Lai (Texas Instruments) - Individual Element Number Format (Bug 202556)
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.vm;
+import java.util.Iterator;
+import java.util.Set;
+
import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.IDebugVMConstants;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat.FormattedValueLabelText;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat.FormattedValueRetriever;
+import org.eclipse.cdt.dsf.debug.ui.viewmodel.update.ElementFormatEvent;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.dsf.ui.viewmodel.IRootVMNode;
import org.eclipse.cdt.dsf.ui.viewmodel.VMDelta;
@@ -210,6 +215,10 @@ public class TestModelDMVMNode extends AbstractDMVMNode implements IRootVMNode,
{
return IModelDelta.CONTENT;
}
+ if ( e instanceof ElementFormatEvent)
+ {
+ return IModelDelta.STATE;
+ }
if (e instanceof TestEvent) {
return ((TestEvent)e).getType();
}
@@ -223,6 +232,14 @@ public class TestModelDMVMNode extends AbstractDMVMNode implements IRootVMNode,
{
parent.setFlags(parent.getFlags() | IModelDelta.CONTENT);
}
+ if ( e instanceof ElementFormatEvent)
+ {
+ Set elements = ((ElementFormatEvent) e).getElements();
+ Iterator it = elements.iterator();
+ while (it.hasNext()) {
+ parent.addNode(it.next(), IModelDelta.STATE);
+ }
+ }
rm.done();
}
@@ -238,6 +255,10 @@ public class TestModelDMVMNode extends AbstractDMVMNode implements IRootVMNode,
{
flags |= IModelDelta.CONTENT;
}
+ if ( event instanceof ElementFormatEvent)
+ {
+ flags |= IModelDelta.CONTENT;
+ }
// TODO: make more sophisticated to update specific elements.
if (event instanceof TestEvent) {
diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestPersistable.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestPersistable.java
new file mode 100644
index 00000000000..a6ed00a8d70
--- /dev/null
+++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestPersistable.java
@@ -0,0 +1,83 @@
+/*****************************************************************
+ * Copyright (c) 2011 Texas Instruments and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Winnie Lai (Texas Instruments) - Individual Element Number Format (Bug 202556)
+ *****************************************************************/
+package org.eclipse.cdt.tests.dsf.vm;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map.Entry;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.IPersistableElement;
+
+/**
+ * Test persistable for junit test cases. This is used along with element format
+ * test cases, and can be extended to support other persistable properties
+ * contained in PresentationContext, e.g. type cast/cast as array.
+ */
+class TestPersistable implements IPersistableElement, IAdaptable {
+
+ HashMap map = new HashMap();
+
+ public void saveState(IMemento memento) {
+ HashMap clone = null;
+ synchronized (map) {
+ clone = new HashMap(map);
+ }
+ Iterator> it = clone.entrySet().iterator();
+ while (it.hasNext()) {
+ Entry entry = it.next();
+ IMemento value = memento.createChild("variable", entry.getKey());
+ value.putString("format", entry.getValue());
+ }
+ }
+
+ void restore(IMemento memento) {
+ IMemento[] list = memento.getChildren("variable");
+ HashMap clone = new HashMap();
+ for (int i = 0; i < list.length; i++) {
+ clone.put(list[i].getID(), list[i].getString("format"));
+ }
+ synchronized (map) {
+ map.clear();
+ map.putAll(clone);
+ }
+ }
+
+ String getFormat(String key) {
+ if (key == null)
+ return null;
+ synchronized (map) {
+ return map.get(key);
+ }
+ }
+
+ void setFormat(String key, String format) {
+ synchronized (map) {
+ if (format == null) {
+ map.remove(key);
+ } else {
+ map.put(key, format);
+ }
+ }
+ }
+
+ public String getFactoryId() {
+ return TestPersistableFactory.factoryId;
+ }
+
+ public Object getAdapter(Class adapter) {
+ if (adapter.isInstance(this)) {
+ return this;
+ }
+ return null;
+ }
+}
diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestPersistableFactory.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestPersistableFactory.java
new file mode 100644
index 00000000000..bcf685eac47
--- /dev/null
+++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestPersistableFactory.java
@@ -0,0 +1,30 @@
+/*****************************************************************
+ * Copyright (c) 2011 Texas Instruments and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Winnie Lai (Texas Instruments) - Individual Element Number Format (Bug 202556)
+ *****************************************************************/
+package org.eclipse.cdt.tests.dsf.vm;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.ui.IElementFactory;
+import org.eclipse.ui.IMemento;
+
+/**
+ * Factory for TestPersitable
+ */
+public class TestPersistableFactory implements IElementFactory {
+
+ static String factoryId = "org.eclipse.cdt.tests.dsf.vm.testPersistableFactory";
+
+ public IAdaptable createElement(IMemento memento) {
+ TestPersistable x = new TestPersistable();
+ x.restore(memento);
+ return x;
+ }
+
+}