mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Bug 460837 - [visualizer] Add persistent information storage in the MV
Change-Id: I18bf08043c17f3bf4c1a2da86cbd6ef5b46d0120
This commit is contained in:
parent
498bfb6509
commit
d38aa32296
4 changed files with 451 additions and 14 deletions
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012 Ericsson and others.
|
||||
* Copyright (c) 2012, 2015 Ericsson 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
|
||||
|
@ -8,6 +8,7 @@
|
|||
* Contributors:
|
||||
* Marc Khouzam (Ericsson) - initial API and implementation
|
||||
* William R. Swanson (Tilera Corporation) - added resource support
|
||||
* Marc Dumais (Ericsson) - Bug 460837
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui;
|
||||
|
||||
|
@ -16,6 +17,8 @@ import org.eclipse.cdt.visualizer.ui.plugin.CDTVisualizerUIPlugin;
|
|||
import org.eclipse.cdt.visualizer.ui.util.UIResourceManager;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
|
||||
import org.eclipse.core.runtime.preferences.InstanceScope;
|
||||
import org.eclipse.jface.dialogs.ErrorDialog;
|
||||
import org.eclipse.jface.resource.ImageDescriptor;
|
||||
import org.eclipse.swt.graphics.Font;
|
||||
|
@ -283,4 +286,9 @@ public class MulticoreVisualizerUIPlugin extends AbstractUIPlugin
|
|||
public static Font getFont(String fontName, int height, int style) {
|
||||
return getDefault().getPluginResources().getFont(fontName, height, style);
|
||||
}
|
||||
|
||||
/** Get the preference store for this Eclipse plug-in */
|
||||
public static IEclipsePreferences getEclipsePreferenceStore() {
|
||||
return InstanceScope.INSTANCE.getNode(PLUGIN_ID);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
* Marc Dumais (Ericsson) - Bug 458076
|
||||
* Alvaro Sanchez-Leon (Ericsson) - Bug 459114 - override construction of the data model
|
||||
* Marc Dumais (Ericsson) - Bug 460737
|
||||
* Marc Dumais (Ericsson) - Bug 460837
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.view;
|
||||
|
@ -62,6 +63,8 @@ import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.utils.DSFDebugModel;
|
|||
import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.utils.DSFSessionState;
|
||||
import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.utils.DebugViewUtils;
|
||||
import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.utils.IDSFTargetDataProxy;
|
||||
import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.utils.PersistentSettingsManager;
|
||||
import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.utils.PersistentSettingsManager.PersistentParameter;
|
||||
import org.eclipse.cdt.dsf.gdb.service.IGDBHardwareAndOS.ICPUDMContext;
|
||||
import org.eclipse.cdt.dsf.gdb.service.IGDBHardwareAndOS.ICoreDMContext;
|
||||
import org.eclipse.cdt.dsf.gdb.service.IGDBHardwareAndOS2.ILoadInfo;
|
||||
|
@ -158,11 +161,13 @@ public class MulticoreVisualizer extends GraphicCanvasVisualizer implements IPin
|
|||
|
||||
|
||||
/** Main switch that determines if we should display the load meters */
|
||||
protected boolean m_loadMetersEnabled = false;
|
||||
private PersistentParameter<Boolean> m_loadMetersEnabled;
|
||||
|
||||
/** Timer used to trigger the update of the CPU/core load meters */
|
||||
protected Timer m_updateLoadMeterTimer = null;
|
||||
|
||||
/** update period for the load meters */
|
||||
protected int m_loadMeterTimerPeriod = LOAD_METER_TIMER_MEDIUM; // default 1000ms
|
||||
private PersistentParameter<Integer> m_loadMeterTimerPeriod;
|
||||
|
||||
// Load meters refresh periods, in ms
|
||||
/** constant for the very short load meters update period */
|
||||
|
@ -233,6 +238,9 @@ public class MulticoreVisualizer extends GraphicCanvasVisualizer implements IPin
|
|||
|
||||
/** Menu action */
|
||||
protected PinToDebugSessionAction m_pinToDbgSessionAction = null;
|
||||
|
||||
/** persistent settings manager */
|
||||
protected PersistentSettingsManager m_persistentSettingsManager = null;
|
||||
|
||||
// --- constructors/destructors ---
|
||||
|
||||
|
@ -272,14 +280,29 @@ public class MulticoreVisualizer extends GraphicCanvasVisualizer implements IPin
|
|||
if (m_visualizerInstanceId == null) {
|
||||
m_visualizerInstanceId = "0"; //$NON-NLS-1$
|
||||
}
|
||||
initializePersistentParameters(m_visualizerInstanceId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the persistent parameters
|
||||
*/
|
||||
protected void initializePersistentParameters(String visualizerInstanceId) {
|
||||
// setting managers
|
||||
m_persistentSettingsManager = new PersistentSettingsManager("MulticoreVisualizer", visualizerInstanceId); //$NON-NLS-1$
|
||||
|
||||
// define persistent parameters:
|
||||
m_loadMetersEnabled = m_persistentSettingsManager.getNewParameter(Boolean.class,
|
||||
"enableLoadMeters", true, false); //$NON-NLS-1$
|
||||
m_loadMeterTimerPeriod = m_persistentSettingsManager.getNewParameter(Integer.class,
|
||||
"loadMeterTimerPeriod", true, LOAD_METER_TIMER_MEDIUM); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets-up the timer associated to load meters refresh
|
||||
*/
|
||||
protected void initializeLoadMeterTimer() {
|
||||
if (!m_loadMetersEnabled) return;
|
||||
m_updateLoadMeterTimer = getLoadTimer(m_sessionState, m_loadMeterTimerPeriod);
|
||||
if (!getLoadMetersEnabled()) return;
|
||||
m_updateLoadMeterTimer = getLoadTimer(m_sessionState, getLoadMeterTimerPeriod());
|
||||
// one-shot timer (re-scheduled upon successful triggering)
|
||||
m_updateLoadMeterTimer.setRepeating(false);
|
||||
}
|
||||
|
@ -328,24 +351,34 @@ public class MulticoreVisualizer extends GraphicCanvasVisualizer implements IPin
|
|||
*/
|
||||
public void setLoadMeterTimerPeriod(int p) {
|
||||
assert (p > LOAD_METER_TIMER_MIN);
|
||||
if (m_loadMeterTimerPeriod == p) return;
|
||||
m_loadMeterTimerPeriod = p > LOAD_METER_TIMER_MIN ? p : LOAD_METER_TIMER_MIN;
|
||||
if (getLoadMeterTimerPeriod() == p) return;
|
||||
m_loadMeterTimerPeriod.set(p > LOAD_METER_TIMER_MIN ? p : LOAD_METER_TIMER_MIN);
|
||||
disposeLoadMeterTimer();
|
||||
initializeLoadMeterTimer();
|
||||
}
|
||||
|
||||
/** Gets the load meter period */
|
||||
public int getLoadMeterTimerPeriod() {
|
||||
return m_loadMeterTimerPeriod != null ? m_loadMeterTimerPeriod.value() : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* enables or disables the load meters
|
||||
*/
|
||||
public void setLoadMetersEnabled(boolean enabled) {
|
||||
if (m_loadMetersEnabled == enabled) return;
|
||||
m_loadMetersEnabled = enabled;
|
||||
if (m_loadMetersEnabled.value() == enabled) return;
|
||||
m_loadMetersEnabled.set(enabled);
|
||||
// save load meter enablement in model
|
||||
fDataModel.setLoadMetersEnabled(m_loadMetersEnabled);
|
||||
fDataModel.setLoadMetersEnabled(getLoadMetersEnabled());
|
||||
disposeLoadMeterTimer();
|
||||
initializeLoadMeterTimer();
|
||||
}
|
||||
|
||||
/** Returns whether the load meters are enabled */
|
||||
public boolean getLoadMetersEnabled() {
|
||||
return m_loadMetersEnabled != null? m_loadMetersEnabled.value() : false;
|
||||
}
|
||||
|
||||
// --- canvas management ---
|
||||
|
||||
/** Creates and returns visualizer canvas control. */
|
||||
|
@ -457,7 +490,7 @@ public class MulticoreVisualizer extends GraphicCanvasVisualizer implements IPin
|
|||
m_loadMetersRefreshSubSubmenu = new MenuManager(MulticoreVisualizerUIPlugin.getString(
|
||||
"MulticoreVisualizer.actions.LoadMetersRefreshSubSubmenu.text")); //$NON-NLS-1$
|
||||
|
||||
m_enableLoadMetersAction = new EnableLoadMetersAction(m_loadMetersEnabled);
|
||||
m_enableLoadMetersAction = new EnableLoadMetersAction(getLoadMetersEnabled());
|
||||
m_enableLoadMetersAction.init(this);
|
||||
// enable the load meter sub-menu
|
||||
m_enableLoadMetersAction.setEnabled(true);
|
||||
|
@ -467,6 +500,7 @@ public class MulticoreVisualizer extends GraphicCanvasVisualizer implements IPin
|
|||
MulticoreVisualizerUIPlugin.getString("MulticoreVisualizer.actions.SetLoadMeterPeriod.fast.text"), //$NON-NLS-1$
|
||||
LOAD_METER_TIMER_FAST));
|
||||
|
||||
// TODO: the default load meter refresh speed is set here but we could instead rely on the value saved in the data store
|
||||
SetLoadMeterPeriodAction defaultAction = new SetLoadMeterPeriodAction(
|
||||
MulticoreVisualizerUIPlugin.getString("MulticoreVisualizer.actions.SetLoadMeterPeriod.medium.text"), //$NON-NLS-1$
|
||||
LOAD_METER_TIMER_MEDIUM);
|
||||
|
@ -520,7 +554,7 @@ public class MulticoreVisualizer extends GraphicCanvasVisualizer implements IPin
|
|||
|
||||
// show the load meter refresh speed sub-menu only
|
||||
// if the load meters are enabled
|
||||
m_loadMetersRefreshSubSubmenu.setVisible(m_loadMetersEnabled);
|
||||
m_loadMetersRefreshSubSubmenu.setVisible(getLoadMetersEnabled());
|
||||
|
||||
// Enable pinning menu item when there is a current debug session
|
||||
m_pinToDbgSessionAction.setEnabled(m_sessionState != null);
|
||||
|
@ -1158,7 +1192,7 @@ public class MulticoreVisualizer extends GraphicCanvasVisualizer implements IPin
|
|||
/** Invoked when getModel() request completes. */
|
||||
@ConfinedToDsfExecutor("getSession().getExecutor()")
|
||||
public void getVisualizerModelDone(VisualizerModel model) {
|
||||
model.setLoadMetersEnabled(m_loadMetersEnabled);
|
||||
model.setLoadMetersEnabled(getLoadMetersEnabled());
|
||||
updateLoads(model);
|
||||
model.sort();
|
||||
setCanvasModel(model);
|
||||
|
@ -1395,7 +1429,7 @@ public class MulticoreVisualizer extends GraphicCanvasVisualizer implements IPin
|
|||
return;
|
||||
}
|
||||
// if meters not enabled, do not query backend
|
||||
if (!m_loadMetersEnabled) {
|
||||
if (!getLoadMetersEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,202 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2015 Ericsson 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:
|
||||
* Marc Dumais (Ericsson) - initial API and implementation (bug 460837)
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.utils;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.transform.OutputKeys;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
|
||||
import org.w3c.dom.Attr;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.InputSource;
|
||||
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$
|
||||
|
||||
|
||||
/** Returns a XML memento, that encodes a single String parameter */
|
||||
public static String encodeStringIntoMemento(String str) {
|
||||
List<String> list = new ArrayList<String>();
|
||||
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);
|
||||
}
|
||||
|
||||
/** Returns a XML memento, that encodes a Map of Strings */
|
||||
public static String encodeMapIntoMemento(Map<String, String> keyPairValues) {
|
||||
String returnValue = null;
|
||||
|
||||
DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder docBuilder = null;
|
||||
try {
|
||||
docBuilder = dfactory.newDocumentBuilder();
|
||||
Document doc = docBuilder.newDocument();
|
||||
|
||||
Element rootElement = doc.createElement(ROOT_ELEMENT_TAGNAME);
|
||||
doc.appendChild(rootElement);
|
||||
// create one XML element per map entry
|
||||
for (String key : keyPairValues.keySet()) {
|
||||
Element elem = doc.createElement(ELEMENT_TAGNAME);
|
||||
elem.setAttribute(key, keyPairValues.get(key));
|
||||
rootElement.appendChild(elem);
|
||||
}
|
||||
|
||||
ByteArrayOutputStream s = new ByteArrayOutputStream();
|
||||
|
||||
TransformerFactory factory = TransformerFactory.newInstance();
|
||||
Transformer transformer = factory.newTransformer();
|
||||
transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
|
||||
transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
|
||||
|
||||
DOMSource source = new DOMSource(doc);
|
||||
StreamResult outputTarget = new StreamResult(s);
|
||||
transformer.transform(source, outputTarget);
|
||||
|
||||
returnValue = s.toString("UTF8"); //$NON-NLS-1$
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
|
||||
/** 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>();
|
||||
|
||||
Element root = null;
|
||||
DocumentBuilder parser;
|
||||
try {
|
||||
parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
|
||||
parser.setErrorHandler(new DefaultHandler());
|
||||
root = parser.parse(new InputSource(new StringReader(memento))).getDocumentElement();
|
||||
NodeList nodeList = root.getChildNodes();
|
||||
for (int i = 0; i < nodeList.getLength(); i++) {
|
||||
Node node = nodeList.item(i);
|
||||
if (node.getNodeType() == Node.ELEMENT_NODE) {
|
||||
Element elem = (Element) node;
|
||||
NamedNodeMap nodeMap = elem.getAttributes();
|
||||
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);
|
||||
}
|
||||
else {
|
||||
throw new Exception();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return keyPairValues;
|
||||
}
|
||||
|
||||
|
||||
/** Returns a XML memento, that encodes a List of Strings */
|
||||
public static String encodeListIntoMemento(List<String> labels) {
|
||||
String returnValue = null;
|
||||
|
||||
DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder docBuilder = null;
|
||||
try {
|
||||
docBuilder = dfactory.newDocumentBuilder();
|
||||
Document doc = docBuilder.newDocument();
|
||||
|
||||
Element rootElement = doc.createElement(ROOT_ELEMENT_TAGNAME);
|
||||
doc.appendChild(rootElement);
|
||||
// create one XML element per list entry to save
|
||||
for (String lbl : labels) {
|
||||
Element elem = doc.createElement(ELEMENT_TAGNAME);
|
||||
elem.setAttribute(ATTRIBUTE_NAME, lbl);
|
||||
rootElement.appendChild(elem);
|
||||
}
|
||||
|
||||
ByteArrayOutputStream s = new ByteArrayOutputStream();
|
||||
|
||||
TransformerFactory factory = TransformerFactory.newInstance();
|
||||
Transformer transformer = factory.newTransformer();
|
||||
transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
|
||||
transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
|
||||
|
||||
DOMSource source = new DOMSource(doc);
|
||||
StreamResult outputTarget = new StreamResult(s);
|
||||
transformer.transform(source, outputTarget);
|
||||
|
||||
returnValue = s.toString("UTF8"); //$NON-NLS-1$
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
/** Returns a List of Strings, decoded from a XML memento */
|
||||
public static List<String> decodeListFromMemento(String memento) {
|
||||
List<String> list = new ArrayList<String>();
|
||||
|
||||
Element root = null;
|
||||
DocumentBuilder parser;
|
||||
try {
|
||||
parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
|
||||
parser.setErrorHandler(new DefaultHandler());
|
||||
root = parser.parse(new InputSource(new StringReader(memento))).getDocumentElement();
|
||||
NodeList nodeList = root.getChildNodes();
|
||||
for (int i = 0; i < nodeList.getLength(); i++) {
|
||||
Node node = nodeList.item(i);
|
||||
if (node.getNodeType() == Node.ELEMENT_NODE) {
|
||||
Element elem = (Element) node;
|
||||
String value = elem.getAttribute(ATTRIBUTE_NAME);
|
||||
if (value != null) {
|
||||
list.add(value);
|
||||
}
|
||||
else {
|
||||
throw new Exception();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,193 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2015 Ericsson 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:
|
||||
* Marc Dumais (Ericsson) - initial API and implementation (bug 460837)
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.utils;
|
||||
|
||||
import java.security.InvalidParameterException;
|
||||
|
||||
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 */
|
||||
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;
|
||||
private T m_value;
|
||||
private T m_defaultValue;
|
||||
private Class<T> myClazz;
|
||||
private boolean m_perInstance;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param name: unique (for the namespace) label that identifies this parameter
|
||||
* @param perInstance: whether the parameter's value is persisted per client instance or
|
||||
* globally (one common shared stored value for all instances)
|
||||
* @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;
|
||||
}
|
||||
|
||||
/** Sets the default value to use if no persistent
|
||||
* value is found for this parameter */
|
||||
public void setDefault(T defaultValue) {
|
||||
m_defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
/** Sets the persistent value to set */
|
||||
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 */
|
||||
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) {
|
||||
// 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;
|
||||
}
|
||||
|
||||
/** 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);
|
||||
if (memento == null) return null;
|
||||
|
||||
String val = MementoUtils.decodeStringFromMemento(memento);
|
||||
|
||||
T convertedVal = convertToT(val);
|
||||
return convertedVal;
|
||||
}
|
||||
|
||||
/** Saves parameter's value in preference store */
|
||||
private void persistParameter(T value) {
|
||||
// create memento
|
||||
String memento = MementoUtils.encodeStringIntoMemento(value.toString());
|
||||
|
||||
// save memento in store
|
||||
if (memento != null) {
|
||||
IEclipsePreferences store = MulticoreVisualizerUIPlugin.getEclipsePreferenceStore();
|
||||
store.put(m_storeKey, memento);
|
||||
try {
|
||||
store.flush();
|
||||
} catch (BackingStoreException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
else if (Integer.class.isAssignableFrom(myClazz)) {
|
||||
return (T) Integer.valueOf(val);
|
||||
}
|
||||
else if (Boolean.class.isAssignableFrom(myClazz)) {
|
||||
return (T) Boolean.valueOf(val);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/** String that is used to insulate the namespace for the parameters
|
||||
* saved by a specific instance of the class */
|
||||
private final String m_category;
|
||||
|
||||
/** an identifier that differentiates different client instances. For example, to save the
|
||||
* value of a parameter that is applicable per-view, the view secondary id could be used so
|
||||
* that each view has its own stored value */
|
||||
private final String m_instance;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param category : an optional id that is used to insulate the namespace for the parameters
|
||||
* saved by this instance of the class. Using different category values permits to distinguish
|
||||
* two or more parameters with the same label. Example: class name where the parameter is used.
|
||||
* This can be set to null if unused.
|
||||
* @param instance : a unique id that identifies the client's instance. Used when
|
||||
* a parameter is defined as per-instance
|
||||
*/
|
||||
public PersistentSettingsManager(String category, String instance) {
|
||||
m_category = category != null ? category : ""; //$NON-NLS-1$
|
||||
m_instance = instance != null ? instance : ""; //$NON-NLS-1$
|
||||
}
|
||||
|
||||
/** Constructor
|
||||
* @param instance: a unique id that identifies the client's instance. Used when
|
||||
* a parameter is not global (i.e. meant to be persisted per instance).
|
||||
*/
|
||||
public PersistentSettingsManager(String instance) {
|
||||
this(null, instance);
|
||||
}
|
||||
|
||||
/** Constructor */
|
||||
public PersistentSettingsManager() {
|
||||
this(null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new persistent parameter, using the namespace and instance id of this manager.
|
||||
* @param clazz: the class of the persistent parameter. 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> PersistentParameter<T> getNewParameter(Class<T> clazz, String label, boolean perInstance, T defaultValue) {
|
||||
// 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$
|
||||
setting.setDefault(defaultValue);
|
||||
|
||||
return setting;
|
||||
}
|
||||
else {
|
||||
throw new InvalidParameterException("Unsupported class type: " + clazz.toString()); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** 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$
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Reference in a new issue