Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Dumais2015-04-13 15:02:14 +0000
committerGerrit Code Review @ Eclipse.org2015-04-17 18:59:36 +0000
commit9cc312e1fef3e8db9e818a6002eeca25b587a5bd (patch)
tree2608431ba72b5213b408a2072fb9497c8b2b0a87 /dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui
parentd071e969b73264b7b54242a1c38ee7786453c087 (diff)
downloadorg.eclipse.cdt-9cc312e1fef3e8db9e818a6002eeca25b587a5bd.tar.gz
org.eclipse.cdt-9cc312e1fef3e8db9e818a6002eeca25b587a5bd.tar.xz
org.eclipse.cdt-9cc312e1fef3e8db9e818a6002eeca25b587a5bd.zip
Bug 462353 - [visualizer] Add support for persistent List<T> and
Map<String,T> parameters in PersistentSettingsManager Change-Id: I77fc411e7484e41a9b66bf388a4120bc51a78549
Diffstat (limited to 'dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui')
-rw-r--r--dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/utils/MementoUtils.java41
-rw-r--r--dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/utils/PersistentSettingsManager.java387
2 files changed, 369 insertions, 59 deletions
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/utils/MementoUtils.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/utils/MementoUtils.java
index 806665a6519..c30b054e14f 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/utils/MementoUtils.java
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/utils/MementoUtils.java
@@ -37,20 +37,19 @@ import org.xml.sax.helpers.DefaultHandler;
/** encodes and decodes memento to and from different data types; list, map, String*/
public class MementoUtils {
-
protected static final String ROOT_ELEMENT_TAGNAME = "root_element"; //$NON-NLS-1$
protected static final String ELEMENT_TAGNAME = "elem"; //$NON-NLS-1$
- protected static final String ATTRIBUTE_NAME = "value"; //$NON-NLS-1$
-
+ protected static final String ATTRIBUTE_KEY = "key"; //$NON-NLS-1$
+ protected static final String ATTRIBUTE_VALUE = "value"; //$NON-NLS-1$
+
/** Returns a XML memento, that encodes a single String parameter */
public static String encodeStringIntoMemento(String str) {
- List<String> list = new ArrayList<String>();
+ List<String> list = new ArrayList<>();
list.add(str);
return encodeListIntoMemento(list);
}
-
-
+
/** Returns a single String parameter, decoded from a XML memento */
public static String decodeStringFromMemento(String memento) {
return decodeListFromMemento(memento).get(0);
@@ -71,7 +70,9 @@ public class MementoUtils {
// create one XML element per map entry
for (String key : keyPairValues.keySet()) {
Element elem = doc.createElement(ELEMENT_TAGNAME);
- elem.setAttribute(key, keyPairValues.get(key));
+ // store key and value as values of 2 attributes
+ elem.setAttribute(ATTRIBUTE_KEY, key);
+ elem.setAttribute(ATTRIBUTE_VALUE, keyPairValues.get(key));
rootElement.appendChild(elem);
}
@@ -96,7 +97,7 @@ public class MementoUtils {
/** Returns a Map of Strings, decoded from a XML memento */
public static Map<String, String> decodeMapFromMemento(String memento) {
- Map<String, String> keyPairValues = new HashMap<String, String>();
+ Map<String, String> keyPairValues = new HashMap<>();
Element root = null;
DocumentBuilder parser;
@@ -110,20 +111,26 @@ public class MementoUtils {
if (node.getNodeType() == Node.ELEMENT_NODE) {
Element elem = (Element) node;
NamedNodeMap nodeMap = elem.getAttributes();
+ String key = null;
+ String value = null;
for(int idx = 0; idx < nodeMap.getLength(); idx++) {
Node attrNode = nodeMap.item(idx);
if (attrNode.getNodeType() == Node.ATTRIBUTE_NODE) {
Attr attr = (Attr) attrNode;
- String key = attr.getName();
- String value = attr.getValue();
- if (key != null && value != null) {
- keyPairValues.put(key, value);
+ if (attr.getName().equals(ATTRIBUTE_KEY)) {
+ key = attr.getValue();
}
- else {
- throw new Exception();
+ else if (attr.getName().equals(ATTRIBUTE_VALUE)) {
+ value = attr.getValue();
}
}
}
+ if (key != null && value != null) {
+ keyPairValues.put(key, value);
+ }
+ else {
+ throw new Exception();
+ }
}
}
} catch (Exception e) {
@@ -148,7 +155,7 @@ public class MementoUtils {
// create one XML element per list entry to save
for (String lbl : labels) {
Element elem = doc.createElement(ELEMENT_TAGNAME);
- elem.setAttribute(ATTRIBUTE_NAME, lbl);
+ elem.setAttribute(ATTRIBUTE_VALUE, lbl);
rootElement.appendChild(elem);
}
@@ -172,7 +179,7 @@ public class MementoUtils {
/** Returns a List of Strings, decoded from a XML memento */
public static List<String> decodeListFromMemento(String memento) {
- List<String> list = new ArrayList<String>();
+ List<String> list = new ArrayList<>();
Element root = null;
DocumentBuilder parser;
@@ -185,7 +192,7 @@ public class MementoUtils {
Node node = nodeList.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE) {
Element elem = (Element) node;
- String value = elem.getAttribute(ATTRIBUTE_NAME);
+ String value = elem.getAttribute(ATTRIBUTE_VALUE);
if (value != null) {
list.add(value);
}
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/utils/PersistentSettingsManager.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/utils/PersistentSettingsManager.java
index f7a9364ed7f..168f884e1d8 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/utils/PersistentSettingsManager.java
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/utils/PersistentSettingsManager.java
@@ -7,30 +7,100 @@
*
* Contributors:
* Marc Dumais (Ericsson) - initial API and implementation (bug 460837)
+ * Marc Dumais (Ericsson) - Bug 462353
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.utils;
+
import java.security.InvalidParameterException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.MulticoreVisualizerUIPlugin;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.osgi.service.prefs.BackingStoreException;
-/** This class manages one or more PersistentSetting objects, using a commmon
- * name-space and optionally an instance id so that multiple instances can
- * each have their own version of the parameter persisted */
+
+/**
+ * This class manages one or more PersistentParameter, PersistentListParameter,
+ * PersistentMapParameter objects, using a common name-space and optionally an
+ * instance id so that multiple instances can each have their own version of
+ * the parameter persisted
+ */
public class PersistentSettingsManager {
- // TODO: add a way to notify clients that the value of a global (shared) parameter
- // has been updated, and that they should re-read it.
- /** Class for a specific persistent parameter */
- public class PersistentParameter<T> {
- private String m_storeKey;
+ /** Base class for a persistent parameter */
+ private abstract class AbstractPersistentParameter<T> {
+ protected final Class<T> myClazz;
+ protected final boolean m_perInstance;
+ protected final String m_storeKey;
+
+ /** Constructor */
+ public AbstractPersistentParameter(Class<T> clazz, boolean perInstance, String storeKey) {
+ myClazz = clazz;
+ m_perInstance = perInstance;
+ m_storeKey = storeKey;
+ }
+
+ // accessors
+
+ /** Returns whether this parameter is persisted independently for each client instance */
+ public boolean isPerInstance() {
+ return m_perInstance;
+ }
+
+ /** Returns the class of the parameter */
+ public Class<T> getClazz() {
+ return myClazz;
+ }
+
+ protected String getStoreKey() {
+ return m_storeKey;
+ }
+
+ // misc
+
+ @SuppressWarnings("unchecked")
+ /** Converts a value from a String to its expected generic type. This is a base
+ * implementation that converts some base types - Use/Override as needed for more complex
+ * types, such as List or Map of these types */
+ protected T convertToT(String val) {
+ // TODO: Add other types? Float, etc
+ if (String.class.isAssignableFrom(getClazz())) {
+ return (T) val;
+ }
+ else if (Integer.class.isAssignableFrom(getClazz())) {
+ return (T) Integer.valueOf(val);
+ }
+ else if (Boolean.class.isAssignableFrom(getClazz())) {
+ return (T) Boolean.valueOf(val);
+ }
+ return null;
+ }
+
+ /** Returns whether the wanted Class type is supported, to use as a persistent parameter */
+ protected boolean isTypeSupported(Class<T> clazz) {
+ // TODO: Add other types? Float, etc
+ if (String.class.isAssignableFrom(clazz) ||
+ Integer.class.isAssignableFrom(clazz) ||
+ Boolean.class.isAssignableFrom(clazz))
+ {
+ return true;
+ }
+ return false;
+ }
+
+ // TODO: add a way to notify clients that the value of a global (shared) parameter
+ // has been updated, and that they should re-read it.
+ }
+
+ /** Class for a persistent parameter */
+ public class PersistentParameter<T> extends AbstractPersistentParameter<T> {
private T m_value;
private T m_defaultValue;
- private Class<T> myClazz;
- private boolean m_perInstance;
/**
* Constructor
@@ -40,9 +110,7 @@ public class PersistentSettingsManager {
* @param storeKey : The key used to store the parameter in the store
*/
public PersistentParameter(Class<T> clazz, boolean perInstance, String storeKey) {
- myClazz = clazz;
- m_perInstance = perInstance;
- m_storeKey = storeKey;
+ super(clazz, perInstance, storeKey);
}
/** Sets the default value to use if no persistent
@@ -51,36 +119,46 @@ public class PersistentSettingsManager {
m_defaultValue = defaultValue;
}
- /** Sets the persistent value to set */
+ /** Sets the value to persist */
public void set(T value) {
m_value = value;
// save value in preference store
persistParameter(value);
}
- /** Gets the persistent value, if found, else the default value */
+ /** Returns the persistent value, if found, else the default value */
public T value() {
if (m_value == null) {
// attempt to get the value from the preference store
m_value = restoreParameter();
}
// parameter has one value for any/all instances
- else if(!m_perInstance) {
+ else if(!isPerInstance()) {
// do not rely on cached value, since another instance might have
// changed it - reread from data store
m_value = restoreParameter();
}
- return (m_value!=null)? m_value : m_defaultValue;
+ return (m_value == null)? m_defaultValue : m_value;
+ }
+
+ /**
+ * Gets the persistent value, optionally forcing re-reading stored value
+ * @param forceRefresh whether to force to re-read memento in case value changed
+ */
+ public T value(boolean forceRefresh) {
+ if (forceRefresh) {
+ m_value = null;
+ }
+ return value();
}
/** Attempts to find the parameter in the preference store. Returns null if not found */
private T restoreParameter() {
IEclipsePreferences store = MulticoreVisualizerUIPlugin.getEclipsePreferenceStore();
- String memento = store.get(m_storeKey, null);
+ String memento = store.get(getStoreKey(), null);
if (memento == null) return null;
String val = MementoUtils.decodeStringFromMemento(memento);
-
T convertedVal = convertToT(val);
return convertedVal;
}
@@ -93,7 +171,7 @@ public class PersistentSettingsManager {
// save memento in store
if (memento != null) {
IEclipsePreferences store = MulticoreVisualizerUIPlugin.getEclipsePreferenceStore();
- store.put(m_storeKey, memento);
+ store.put(getStoreKey(), memento);
try {
store.flush();
} catch (BackingStoreException e) {
@@ -101,22 +179,208 @@ public class PersistentSettingsManager {
}
}
}
+ }
+
+ /** Class for a persistent {@literal List<T>} parameter */
+ public class PersistentListParameter<T> extends AbstractPersistentParameter<T> {
+ private List<T> m_value;
+ private List<T> m_defaultValue;
- @SuppressWarnings("unchecked")
- /** Converts the stored value from a String to its expected type */
- private T convertToT(String val) {
- // TODO: Add other types? Float, etc
- if (String.class.isAssignableFrom(myClazz)) {
- return (T) val;
+ public PersistentListParameter(Class<T> clazz, boolean perInstance, String storeKey) {
+ super(clazz, perInstance, storeKey);
+ }
+
+ /** Sets the default value to use if no persistent
+ * value is found for this parameter */
+ public void setDefault(List<T> defaultValues) {
+ m_defaultValue = defaultValues;
+ }
+
+ /** Sets the value to persist */
+ public void set(List<T> values) {
+ m_value = values;
+ // save value in preference store
+ persistParameter(values);
+ }
+
+ /** Returns the persistent value, if found, else the default value */
+ public List<T> value() {
+ if (m_value == null) {
+ // attempt to get the value from the preference store
+ m_value = restoreParameter();
}
- else if (Integer.class.isAssignableFrom(myClazz)) {
- return (T) Integer.valueOf(val);
+ // parameter has one value for any/all instances
+ else if(!isPerInstance()) {
+ // do not rely on cached value, since another instance might have
+ // changed it - reread from data store
+ m_value = restoreParameter();
}
- else if (Boolean.class.isAssignableFrom(myClazz)) {
- return (T) Boolean.valueOf(val);
+ return (m_value == null)? m_defaultValue : m_value ;
+ }
+
+ /**
+ * Gets the persistent value, optionally forcing re-reading stored value
+ * @param forceRefresh whether to force to re-read memento in case value changed
+ */
+ public List<T> value(boolean forceRefresh) {
+ if (forceRefresh) {
+ m_value = null;
}
+ return value();
+ }
+
+ /** Attempts to find the parameter in the preference store. Returns null if not found */
+ private List<T> restoreParameter() {
+ IEclipsePreferences store = MulticoreVisualizerUIPlugin.getEclipsePreferenceStore();
+ String memento = store.get(getStoreKey(), null);
+ if (memento == null) return null;
- return null;
+ List<String> vals = MementoUtils.decodeListFromMemento(memento);
+ // convert from List<String> to List<T>
+ List<T> convertedVal = convertToT(vals);
+ return convertedVal;
+ }
+
+ /** Saves parameter's value in preference store */
+ private void persistParameter(List<T> values) {
+ // Convert List<T> to List<String>
+ List<String> strList = convertTListToStringList(values);
+ // create memento from List<String>
+ String memento = MementoUtils.encodeListIntoMemento(strList);
+
+ // save memento in store
+ if (memento != null) {
+ IEclipsePreferences store = MulticoreVisualizerUIPlugin.getEclipsePreferenceStore();
+ store.put(getStoreKey(), memento);
+ try {
+ store.flush();
+ } catch (BackingStoreException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /** For list parameters, converts the restored values from String
+ * to its expected generic type */
+ private List<T> convertToT(List<String> vals) {
+ List<T> convertedList = new ArrayList<>();
+
+ for(String val : vals) {
+ convertedList.add(convertToT(val));
+ }
+ return convertedList;
+ }
+
+ /** Converts a list of generic type to a list of String */
+ private List<String> convertTListToStringList(List<T> tList) {
+ List<String> strList = new ArrayList<>();
+ // convert list to list of String
+ for(T elem : tList) {
+ strList.add(elem.toString());
+ }
+ return strList;
+ }
+ }
+
+
+ /** Class for a persistent {@literal Map<String,T>} parameter */
+ public class PersistentMapParameter<T> extends AbstractPersistentParameter<T> {
+ private Map<String,T> m_value;
+ private Map<String,T> m_defaultValue;
+
+ public PersistentMapParameter(Class<T> clazz, boolean perInstance, String storeKey) {
+ super(clazz, perInstance, storeKey);
+ }
+
+ /** Sets the default value to use if no persistent
+ * value is found for this parameter */
+ public void setDefault(Map<String,T> defaultValues) {
+ m_defaultValue = defaultValues;
+ }
+
+ /** Sets the value to persist */
+ public void set(Map<String,T> values) {
+ m_value = values;
+ // save value in preference store
+ persistParameter(values);
+ }
+
+ /** Returns the persistent value, if found, else the default value */
+ public Map<String,T> value() {
+ if (m_value == null) {
+ // attempt to get the value from the preference store
+ m_value = restoreParameter();
+ }
+ // parameter has one value for any/all instances
+ else if(!isPerInstance()) {
+ // do not rely on cached value, since another instance might have
+ // changed it - reread from data store
+ m_value = restoreParameter();
+ }
+ return (m_value == null)? m_defaultValue : m_value ;
+ }
+
+ /**
+ * Gets the persistent value, optionally forcing re-reading stored value
+ * @param forceRefresh whether to force to re-read memento in case value changed
+ */
+ public Map<String,T> value(boolean forceRefresh) {
+ if (forceRefresh) {
+ m_value = null;
+ }
+ return value();
+ }
+
+ /** Attempts to find the parameter in the preference store. Returns null if not found */
+ private Map<String,T> restoreParameter() {
+ IEclipsePreferences store = MulticoreVisualizerUIPlugin.getEclipsePreferenceStore();
+ String memento = store.get(getStoreKey(), null);
+ if (memento == null) return null;
+
+ Map<String,String> vals = MementoUtils.decodeMapFromMemento(memento);
+ // convert from Map<String,String> to Map<String,T>
+ Map<String,T> convertedVal = convertToT(vals);
+ return convertedVal;
+ }
+
+ /** Saves parameter's value in preference store */
+ private void persistParameter(Map<String,T> values) {
+ // Convert Map<String,T> to Map<String,String>
+ Map<String,String> strMap = convertTMapToStringMap(values);
+ // create memento from Map
+ String memento = MementoUtils.encodeMapIntoMemento(strMap);
+
+ // save memento in store
+ if (memento != null) {
+ IEclipsePreferences store = MulticoreVisualizerUIPlugin.getEclipsePreferenceStore();
+ store.put(getStoreKey(), memento);
+ try {
+ store.flush();
+ } catch (BackingStoreException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /** For Map parameters, converts the restored values from {@literal Map<String,String>}
+ * to {@literal Map<String, T>} */
+ private Map<String,T> convertToT(Map<String,String> vals) {
+ Map<String,T> convertedMap = new HashMap<>();
+
+ for(String key : vals.keySet()) {
+ convertedMap.put(key, convertToT(vals.get(key)));
+ }
+ return convertedMap;
+ }
+
+ /** Converts a {@literal Map<String,T>} to a {@literal Map<String,String>} */
+ private Map<String,String> convertTMapToStringMap(Map<String,T> map) {
+ Map<String,String> strMap = new HashMap<>();
+ // convert each entry
+ for(String key : map.keySet()) {
+ strMap.put(key, map.get(key).toString());
+ }
+ return strMap;
}
}
@@ -165,17 +429,56 @@ public class PersistentSettingsManager {
* @param defaultValue: default value to use (mandatory)
*/
public <T> PersistentParameter<T> getNewParameter(Class<T> clazz, String label, boolean perInstance, T defaultValue) {
+ PersistentParameter<T> setting;
+ // build the final store key with category, parameter label and specific instance, if applicable
+ setting = new PersistentParameter<T>(clazz, perInstance, getStorageKey(perInstance) + "." + label); //$NON-NLS-1$
// check that we're dealing with one of a few supported types
- // TODO: Add other types? Float, etc
- if (String.class.isAssignableFrom(clazz) ||
- Integer.class.isAssignableFrom(clazz) ||
- Boolean.class.isAssignableFrom(clazz))
- {
- PersistentParameter<T> setting;
- // build the final store key with category, parameter label and specific instance, if applicable
- setting = new PersistentParameter<T>(clazz, perInstance, getStorageKey(perInstance) + "." + label); //$NON-NLS-1$
+ if (setting.isTypeSupported(clazz)) {
+ setting.setDefault(defaultValue);
+ return setting;
+ }
+ else {
+ throw new InvalidParameterException("Unsupported class type: " + clazz.toString()); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Creates a new persistent {@literal List<T>} parameter, using the namespace and instance id of this manager.
+ * @param clazz: the class of the persistent parameter List (e.g. List of that type). Supported types: String, Integer, Boolean
+ * @param label: unique label that identifies this parameter.
+ * @param perInstance: whether the parameter's value should be persisted per client instance or
+ * globally (one common shared stored value for all instances)
+ * @param defaultValue: default value to use (mandatory).
+ */
+ public <T> PersistentListParameter<T> getNewListParameter(Class<T> clazz, String label, boolean perInstance, List<T> defaultValue) {
+ PersistentListParameter<T> setting;
+ // build the final store key with category, parameter label and specific instance, if applicable
+ setting = new PersistentListParameter<T>(clazz, perInstance, getStorageKey(perInstance) + "." + label); //$NON-NLS-1$
+ // check that we're dealing with one of a few supported types
+ if (setting.isTypeSupported(clazz)) {
+ setting.setDefault(defaultValue);
+ return setting;
+ }
+ else {
+ throw new InvalidParameterException("Unsupported class type: " + clazz.toString()); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Creates a new persistent {@literal Map<String,T>} parameter, using the namespace and instance id of this manager.
+ * @param clazz: the class of the persistent parameter List (e.g. List of that type). Supported types: String, Integer, Boolean
+ * @param label: unique label that identifies this parameter.
+ * @param perInstance: whether the parameter's value should be persisted per client instance or
+ * globally (one common shared stored value for all instances)
+ * @param defaultValue: default value to use (mandatory).
+ */
+ public <T> PersistentMapParameter<T> getNewMapParameter(Class<T> clazz, String label, boolean perInstance, Map<String,T> defaultValue) {
+ PersistentMapParameter<T> setting;
+ // build the final store key with category, parameter label and specific instance, if applicable
+ setting = new PersistentMapParameter<T>(clazz, perInstance, getStorageKey(perInstance) + "." + label); //$NON-NLS-1$
+ // check that we're dealing with one of a few supported types
+ if (setting.isTypeSupported(clazz)) {
setting.setDefault(defaultValue);
-
return setting;
}
else {
@@ -183,11 +486,11 @@ public class PersistentSettingsManager {
}
}
+ // ---- misc ----
/** Returns the key to be used to save parameter, taking into account the
* instance id, if applicable */
private String getStorageKey(boolean perInstance) {
return (perInstance ? m_instance : "") + (!m_category.equals("") ? "." + m_category : ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
}
-
-}
+} \ No newline at end of file

Back to the top