Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptGraphOptionsTab.java')
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptGraphOptionsTab.java939
1 files changed, 729 insertions, 210 deletions
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptGraphOptionsTab.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptGraphOptionsTab.java
index bc4542f5ff..ed4142607e 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptGraphOptionsTab.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptGraphOptionsTab.java
@@ -12,6 +12,7 @@
package org.eclipse.linuxtools.internal.systemtap.ui.ide.launcher;
+import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
@@ -24,6 +25,7 @@ import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
+import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.linuxtools.internal.systemtap.ui.ide.IDEPlugin;
import org.eclipse.linuxtools.systemtap.graphingapi.core.datasets.IDataSet;
@@ -46,6 +48,7 @@ import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
@@ -60,14 +63,23 @@ import org.eclipse.ui.plugin.AbstractUIPlugin;
public class SystemTapScriptGraphOptionsTab extends
AbstractLaunchConfigurationTab {
+ /**
+ * The maximum number of regular expressions that can be stored in a configuration.
+ */
+ static final int MAX_NUMBER_OF_REGEXS = 20;
+
+ // Note: any non-private String key with a trailing underscore is to be appended with an integer when looking up values.
static final String RUN_WITH_CHART = "runWithChart"; //$NON-NLS-1$
- static final String NUMBER_OF_COLUMNS = "numberOfColumns"; //$NON-NLS-1$
+ static final String NUMBER_OF_REGEXS = "numberOfRegexs"; //$NON-NLS-1$
+ static final String NUMBER_OF_COLUMNS = "numberOfColumns_"; //$NON-NLS-1$
static final String REGEX_BOX = "regexBox_"; //$NON-NLS-1$
- static final String NUMBER_OF_EXTRAS = "numberOfExtras"; //$NON-NLS-1$
+ static final String NUMBER_OF_EXTRAS = "numberOfExtras_"; //$NON-NLS-1$
static final String EXTRA_BOX = "extraBox_"; //$NON-NLS-1$
- static final String REGULARE_EXPRESSION = "regularExpression"; //$NON-NLS-1$
- static final String SAMPLE_OUTPUT = "sampleOutput"; //$NON-NLS-1$
+ static final String REGULAR_EXPRESSION = "regularExpression_"; //$NON-NLS-1$
+ static final String SAMPLE_OUTPUT = "sampleOutput_"; //$NON-NLS-1$
+ // Note: all graph-related keys point to 2D lists (regular expression & graph number),
+ // except for GRAPH_Y_SERIES (which is a 3D list).
private static final String NUMBER_OF_GRAPHS = "numberOfGraphs"; //$NON-NLS-1$
private static final String GRAPH_TITLE = "graphTitle"; //$NON-NLS-1$
private static final String GRAPH_KEY = "graphKey"; //$NON-NLS-1$
@@ -78,9 +90,26 @@ public class SystemTapScriptGraphOptionsTab extends
protected Pattern pattern;
protected Matcher matcher;
- private ModifyListener regExListener = new ModifyListener() {
+ private ModifyListener regexListener = new ModifyListener() {
@Override
public void modifyText(ModifyEvent event) {
+ if (!textListenersEnabled || regularExpressionCombo.getSelectionIndex() != -1) {
+ return;
+ }
+ regularExpressionCombo.setItem(selectedRegex, regularExpressionCombo.getText());
+ regularExpressionCombo.select(selectedRegex);
+ refreshRegexRows();
+ updateLaunchConfigurationDialog();
+ }
+ };
+
+ private ModifyListener sampleOutputListener = new ModifyListener() {
+ @Override
+ public void modifyText(ModifyEvent event) {
+ if (!textListenersEnabled) {
+ return;
+ }
+ outputList.set(selectedRegex, sampleOutputText.getText());
refreshRegexRows();
updateLaunchConfigurationDialog();
}
@@ -89,13 +118,32 @@ public class SystemTapScriptGraphOptionsTab extends
private ModifyListener columnNameListener = new ModifyListener() {
@Override
public void modifyText(ModifyEvent event) {
+ if (!textListenersEnabled) {
+ return;
+ }
+
+ ArrayList<String> columnNames = new ArrayList<String>();
+ Control[] children = textFieldsComposite.getChildren();
+ for (int i = 0; i < numberOfVisibleColumns; i++) {
+ columnNames.add(((Text)children[i*2]).getText());
+ }
+ columnNamesList.set(selectedRegex, columnNames);
updateLaunchConfigurationDialog();
}
};
- private Text regularExpressionText;
+ private Combo regularExpressionCombo;
+ private Button removeRegexButton;
+ private Text sampleOutputText;
private Composite textFieldsComposite;
+ /**
+ * This value controls whether or not the ModifyListeners associated with
+ * the Texts will perform when dispatched. Sometimes the listeners should
+ * be disabled to prevent needless/unsafe operations.
+ */
+ private boolean textListenersEnabled = true;
+
private ScrolledComposite regexTextScrolledComposite;
private Group outputParsingGroup;
private Button runWithChartCheckButton;
@@ -104,64 +152,190 @@ public class SystemTapScriptGraphOptionsTab extends
private Button addGraphButton, duplicateGraphButton, editGraphButton, removeGraphButton;
private TableItem selectedTableItem;
private Group graphsGroup;
- private Text sampleOutputText;
private int numberOfVisibleColumns = 0;
private boolean graphingEnabled = true;
- private String regexErrorMessage;
- private Stack<String> cachedNames = new Stack<String>();
- private List<TableItem> badGraphs = new LinkedList<TableItem>();
- private int oldNumColumns;
- private int oldNumExtras;
- public static IDataSetParser createDatasetParser(ILaunchConfiguration configuration) {
+ /**
+ * A list of error messages, each entry corresponding to an entered regular expression.
+ */
+ private List<String> regexErrorMessages = new ArrayList<String>();
+
+ /**
+ * The index of the selected regular expression.
+ */
+ private int selectedRegex = -1;
+
+ /**
+ * A list containing the user-defined sample outputs associated with the regex of every index.
+ */
+ private List<String> outputList = new ArrayList<String>();
+
+ /**
+ * A name is given to each group captured by a regular expression. This stack contains
+ * the names of all of a regex's groups that have been deleted, so each name may be
+ * restored (without having to retype it) when a group is added again.
+ */
+ private Stack<String> cachedNames;
+
+ /**
+ * A list of cachedNames stacks, containing one entry for each regular expression stored.
+ */
+ private List<Stack<String>> cachedNamesList = new ArrayList<Stack<String>>();
+
+ /**
+ * A two-dimensional list that holds references to the names given to each regular expression's captured groups.
+ */
+ private List<ArrayList<String>> columnNamesList = new ArrayList<ArrayList<String>>();
+
+ /**
+ * A list holding the data of every graph for the selected regular expression.
+ */
+ private List<GraphData> graphsData = new LinkedList<GraphData>();
+
+ /**
+ * A list of graphsData lists. This is needed because each regular expression has its own set of graphs.
+ */
+ private List<LinkedList<GraphData>> graphsDataList = new ArrayList<LinkedList<GraphData>>();
+
+ /**
+ * A list of GraphDatas that rely on series information that has been deleted from their relying regex.
+ */
+ private List<GraphData> badGraphs = new LinkedList<GraphData>();
+
+ /**
+ * Returns the list of the names given to reach regular expression.
+ * @param configuration
+ * @return
+ */
+ public static ArrayList<String> createDatasetNames(ILaunchConfiguration configuration) {
try {
- return new LineParser("^" + configuration.getAttribute(REGULARE_EXPRESSION, "") + "$"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ int numberOfRegexs = configuration.getAttribute(NUMBER_OF_REGEXS, 0);
+ ArrayList<String> names = new ArrayList<String>(numberOfRegexs);
+ for (int r = 0; r < numberOfRegexs; r++) {
+ names.add(MessageFormat.format(Messages.SystemTapScriptGraphOptionsTab_graphSetTitleBase, r + 1));
+ }
+ return names;
} catch (CoreException e) {
ExceptionErrorDialog.openError(Messages.SystemTapScriptGraphOptionsTab_0, e);
}
return null;
}
- public static IDataSet createDataset(ILaunchConfiguration configuration) {
- int n;
+ /**
+ * Creates a list of parsers, one for each regular expression created, that will be used
+ * to parse the output of a running script.
+ * @param configuration The desired run configuration.
+ * @return A list of parsers.
+ */
+ public static ArrayList<IDataSetParser> createDatasetParsers(ILaunchConfiguration configuration) {
try {
- n = configuration.getAttribute(NUMBER_OF_COLUMNS, 0);
- ArrayList<String> labels = new ArrayList<String>(n);
+ int numberOfRegexs = configuration.getAttribute(NUMBER_OF_REGEXS, 0);
+ ArrayList<IDataSetParser> parsers = new ArrayList<IDataSetParser>(numberOfRegexs);
+ for (int r = 0; r < numberOfRegexs; r++) {
+ parsers.add(new LineParser("^" + configuration.getAttribute(REGULAR_EXPRESSION + r, "") + "$")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+ return parsers;
+ } catch (CoreException e) {
+ ExceptionErrorDialog.openError(Messages.SystemTapScriptGraphOptionsTab_0, e);
+ }
+ return null;
+ }
- for (int i = 0; i < n; i++) {
- String text = configuration.getAttribute(REGEX_BOX + i, (String) null);
- labels.add(text);
+ /**
+ * Creates a data set corresponding to the titles given to each output column
+ * from each of a run configuration's regular expressions.
+ * @param configuration
+ * @return
+ */
+ public static ArrayList<IDataSet> createDataset(ILaunchConfiguration configuration) {
+ try {
+ int numberOfRegexs = configuration.getAttribute(NUMBER_OF_REGEXS, 0);
+ ArrayList<IDataSet> datasets = new ArrayList<IDataSet>(numberOfRegexs);
+
+ for (int r = 0; r < numberOfRegexs; r++) {
+ int numberOfColumns = configuration.getAttribute(NUMBER_OF_COLUMNS + r, 0);
+ ArrayList<String> labels = new ArrayList<String>(numberOfColumns);
+
+ for (int c = 0; c < numberOfColumns; c++) {
+ labels.add(configuration.getAttribute(get2DConfigData(REGEX_BOX, r, c), "")); //$NON-NLS-1$
+ }
+ datasets.add(DataSetFactory.createDataSet(RowDataSet.ID, labels.toArray(new String[] {})));
}
- return DataSetFactory.createDataSet(RowDataSet.ID, labels.toArray(new String[] {}));
+ return datasets;
} catch (CoreException e) {
ExceptionErrorDialog.openError(Messages.SystemTapScriptGraphOptionsTab_1, e);
}
return null;
}
- public static LinkedList<GraphData> createGraphsFromConfiguration (ILaunchConfiguration configuration) throws CoreException {
- LinkedList<GraphData> graphs = new LinkedList<GraphData>();
- int n = configuration.getAttribute(NUMBER_OF_GRAPHS, 0);
- for (int i = 0; i < n; i++) {
- GraphData graphData = new GraphData();
- graphData.title = configuration.getAttribute (GRAPH_TITLE + i, ""); //$NON-NLS-1$
-
- graphData.key = configuration.getAttribute(GRAPH_KEY + i, ""); //$NON-NLS-1$
- graphData.xSeries = configuration.getAttribute(GRAPH_X_SERIES + i, 0);
- graphData.graphID = configuration.getAttribute(GRAPH_ID + i, ""); //$NON-NLS-1$
+ /**
+ * Creates graph data corresponding to the graphs that will plot a script's parsed output data.
+ * @param configuration The desired run configuration.
+ * @return A data set.
+ */
+ public static ArrayList<LinkedList<GraphData>> createGraphsFromConfiguration (ILaunchConfiguration configuration)
+ throws CoreException {
+ // Restrict number of regexs to at least one, so at least
+ // one inner list will exist in the return value.
+ int numberOfRegexs = Math.max(configuration.getAttribute(NUMBER_OF_REGEXS, 1), 1);
+ ArrayList<LinkedList<GraphData>> graphsList = new ArrayList<LinkedList<GraphData>>(numberOfRegexs);
+
+ for (int r = 0; r < numberOfRegexs; r++) {
+ int numberOfGraphs = configuration.getAttribute(NUMBER_OF_GRAPHS + r, 0);
+ LinkedList<GraphData> graphs = new LinkedList<GraphData>();
+ for (int i = 0; i < numberOfGraphs; i++) {
+ GraphData graphData = new GraphData();
+ graphData.title = configuration.getAttribute(get2DConfigData(GRAPH_TITLE, r, i), (String) null);
+
+ graphData.key = configuration.getAttribute(get2DConfigData(GRAPH_KEY, r, i), (String) null);
+ graphData.xSeries = configuration.getAttribute(get2DConfigData(GRAPH_X_SERIES, r, i), 0);
+ graphData.graphID = configuration.getAttribute(get2DConfigData(GRAPH_ID, r, i), (String) null);
+
+ int ySeriesLength = configuration.getAttribute(get2DConfigData(GRAPH_Y_SERIES_LENGTH, r, i), 0);
+ if (ySeriesLength == 0) {
+ graphData.ySeries = null;
+ } else {
+ int[] ySeries = new int[ySeriesLength];
+ for (int j = 0; j < ySeriesLength; j++) {
+ ySeries[j] = configuration.getAttribute(get2DConfigData(GRAPH_Y_SERIES, r, i + "_" + j), 0); //$NON-NLS-1$
+ }
+ graphData.ySeries = ySeries;
+ }
- int ySeriesLength = configuration.getAttribute(GRAPH_Y_SERIES_LENGTH + i, 0);
- int[] ySeries = new int[ySeriesLength];
- for (int j = 0; j < ySeriesLength; j++) {
- ySeries[j] = configuration.getAttribute(GRAPH_Y_SERIES + i + "_" + j, 0); //$NON-NLS-1$
+ graphs.add(graphData);
}
- graphData.ySeries = ySeries;
-
- graphs.add(graphData);
+ graphsList.add(graphs);
}
- return graphs;
+ return graphsList;
+ }
+
+ /**
+ * Returns the key associated with the i'th data item of the r'th regular expression.
+ * @param configDataName The type of data to access from the configuration.
+ * @param r The index of the regular expression.
+ * @param i The index of the data item to access.
+ */
+ private static String get2DConfigData(String configDataName, int r, int i) {
+ return configDataName + r + "_" + i; //$NON-NLS-1$
+ }
+
+ /**
+ * Returns the key associated with the data item of the r'th regular expression, tagged by string s.
+ * @param configDataName The type of data to access from the configuration.
+ * @param r The index of the regular expression.
+ * @param s The string to put at the end of the key.
+ */
+ private static String get2DConfigData(String configDataName, int r, String s) {
+ return configDataName + r + "_" + s; //$NON-NLS-1$
+ }
+
+ /**
+ * Returns the total number of regular expressions of the current configuration.
+ */
+ private int getNumberOfRegexs() {
+ return outputList.size();
}
@Override
@@ -194,7 +368,6 @@ public class SystemTapScriptGraphOptionsTab extends
this.createColumnSelector(outputParsingGroup);
this.graphsGroup = new Group(top, SWT.SHADOW_ETCHED_IN);
- graphsGroup.setText(Messages.SystemTapScriptGraphOptionsTab_graphsTitle);
graphsGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
createGraphCreateArea(graphsGroup);
@@ -210,42 +383,118 @@ public class SystemTapScriptGraphOptionsTab extends
GridLayout twoColumns = new GridLayout();
twoColumns.numColumns = 2;
+ GridLayout threeColumns = new GridLayout();
+ threeColumns.numColumns = 3;
+
+ Composite regexButtonLayout = new Composite(parent, SWT.NONE);
+ regexButtonLayout.setLayout(threeColumns);
+ regexButtonLayout.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+
+ Label selectedRegexLabel = new Label(regexButtonLayout, SWT.NONE);
+ selectedRegexLabel.setText(Messages.SystemTapScriptGraphOptionsTab_regexLabel);
+ selectedRegexLabel.setToolTipText(Messages.SystemTapScriptGraphOptionsTab_regexTooltip);
+ regularExpressionCombo = new Combo(regexButtonLayout, SWT.DROP_DOWN);
+ regularExpressionCombo.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ regularExpressionCombo.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ int selected = regularExpressionCombo.getSelectionIndex();
+ if (selected == selectedRegex) {
+ return;
+ }
+
+ // If deselecting an empty regular expression, delete it automatically.
+ if (regularExpressionCombo.getItem(selectedRegex).equals("") //$NON-NLS-1$
+ && graphsDataList.get(selectedRegex).size() == 0
+ && outputList.get(selectedRegex).equals("")) { //$NON-NLS-1$
+
+ // If the deselected regex is the last one in the combo, just quit.
+ // Otherwise, the deleted blank entry would be replaced by another blank entry.
+ if (selected == regularExpressionCombo.getItemCount() - 1) {
+ regularExpressionCombo.select(selectedRegex); // To keep the text blank.
+ return;
+ }
+ removeRegex(false);
+ if (selected > selectedRegex) {
+ selected--;
+ }
+ }
+
+ // When selecting the "Add New Regex" item in the combo (which is always the last item),
+ // update all appropriate values to make room for a new regular expression.
+ if (selected == regularExpressionCombo.getItemCount() - 1 && getNumberOfRegexs() < MAX_NUMBER_OF_REGEXS) {
+ outputList.add(""); //$NON-NLS-1$
+ regexErrorMessages.add(null);
+ columnNamesList.add(new ArrayList<String>());
+ cachedNamesList.add(new Stack<String>());
+ graphsDataList.add(new LinkedList<GraphData>());
+
+ // Remove "Add New Regex" from the selected combo item; make it blank.
+ regularExpressionCombo.setItem(selected, ""); //$NON-NLS-1$
+ regularExpressionCombo.select(selected);
+ updateRegexSelection(selected, false);
+ updateLaunchConfigurationDialog();
+
+ // Enable the "remove" button if only one item was present before.
+ // (Don't do this _every_ time something is added.)
+ if (getNumberOfRegexs() == 2) {
+ removeRegexButton.setEnabled(true);
+ }
+ if (getNumberOfRegexs() < MAX_NUMBER_OF_REGEXS) {
+ regularExpressionCombo.add(Messages.SystemTapScriptGraphOptionsTab_regexAddNew);
+ }
+ } else {
+ updateRegexSelection(selected, false);
+ }
+ }
+ });
+ regularExpressionCombo.addModifyListener(regexListener);
+
+ removeRegexButton = new Button(regexButtonLayout, SWT.PUSH);
+ removeRegexButton.setLayoutData(new GridData(SWT.BEGINNING, SWT.BEGINNING, false, false));
+ removeRegexButton.setText(Messages.SystemTapScriptGraphOptionsTab_regexRemove);
+ removeRegexButton.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ IWorkbench workbench = PlatformUI.getWorkbench();
+ MessageDialog dialog = new MessageDialog(workbench
+ .getActiveWorkbenchWindow().getShell(), Messages.SystemTapScriptGraphOptionsTab_removeRegexTitle, null,
+ MessageFormat.format(Messages.SystemTapScriptGraphOptionsTab_removeRegexAsk,
+ regularExpressionCombo.getItem(selectedRegex)),
+ MessageDialog.QUESTION, new String[]{"Yes", "No"}, 0); //$NON-NLS-1$ //$NON-NLS-2$
+ int result = dialog.open();
+ if (result == 0) { //Yes
+ removeRegex(true);
+ }
+ }
+ });
+
Composite regexSummaryComposite = new Composite(parent, SWT.NONE);
regexSummaryComposite.setLayout(twoColumns);
regexSummaryComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- Label regularExpressionLabel = new Label(regexSummaryComposite, SWT.NONE);
- regularExpressionLabel.setText(Messages.ParsingWizardPage_RegularExpression + ":"); //$NON-NLS-1$
- regularExpressionLabel.setToolTipText(Messages.SystemTapScriptGraphOptionsTab_regexTooltip);
- regularExpressionText = new Text(regexSummaryComposite, SWT.BORDER);
- regularExpressionText.setToolTipText(Messages.SystemTapScriptGraphOptionsTab_regexTooltip);
- regularExpressionText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- regularExpressionText.addModifyListener(regExListener);
-
Label sampleOutputLabel = new Label(regexSummaryComposite, SWT.NONE);
sampleOutputLabel.setText(Messages.SystemTapScriptGraphOptionsTab_sampleOutputLabel);
sampleOutputLabel.setToolTipText(Messages.SystemTapScriptGraphOptionsTab_sampleOutputTooltip);
this.sampleOutputText = new Text(regexSummaryComposite, SWT.BORDER);
this.sampleOutputText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- this.sampleOutputText.addModifyListener(regExListener);
+ this.sampleOutputText.addModifyListener(sampleOutputListener);
sampleOutputText.setToolTipText(Messages.SystemTapScriptGraphOptionsTab_sampleOutputTooltip);
- GridLayout threeColumnLayout = new GridLayout();
- threeColumnLayout.numColumns = 3;
- threeColumnLayout.makeColumnsEqualWidth = true;
Composite expressionTableLabels = new Composite(parent, SWT.NONE);
- expressionTableLabels.setLayout(threeColumnLayout);
+ expressionTableLabels.setLayout(twoColumns);
expressionTableLabels.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
Label label = new Label(expressionTableLabels, SWT.NONE);
- label.setText(Messages.ParsingWizardPage_Title);
- label.setAlignment(SWT.CENTER);
+ label.setText(Messages.SystemTapScriptGraphOptionsTab_columnTitle);
+ label.setAlignment(SWT.LEFT);
GridData data = new GridData(SWT.FILL, SWT.FILL, false, false);
data.widthHint = 200;
label.setLayoutData(data);
label = new Label(expressionTableLabels, SWT.NONE);
+ label.setAlignment(SWT.CENTER);
label.setText(Messages.SystemTapScriptGraphOptionsTab_extractedValueLabel);
label.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
@@ -260,20 +509,10 @@ public class SystemTapScriptGraphOptionsTab extends
regexTextScrolledComposite.setContent(textFieldsComposite);
regexTextScrolledComposite.setExpandHorizontal(true);
regexTextScrolledComposite.setExpandVertical(false);
-
- refreshRegexRows();
}
- private IDataSet getDataset() {
- Control[] textBoxes = this.textFieldsComposite.getChildren();
- int numberOfColumns = textBoxes.length/2;
- ArrayList<String> labels = new ArrayList<String>(numberOfColumns);
-
- for (int i = 0; i < numberOfColumns; i++) {
- String text = ((Text)textBoxes[i*2]).getText();
- labels.add(text);
- }
- return DataSetFactory.createDataSet(RowDataSet.ID, labels.toArray(new String[] {}));
+ private IDataSet getCurrentDataset() {
+ return DataSetFactory.createDataSet(RowDataSet.ID, columnNamesList.get(selectedRegex).toArray(new String[] {}));
}
private void createGraphCreateArea(Composite comp){
@@ -332,7 +571,7 @@ public class SystemTapScriptGraphOptionsTab extends
addGraphButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
- SelectGraphAndSeriesWizard wizard = new SelectGraphAndSeriesWizard(getDataset(), null);
+ SelectGraphAndSeriesWizard wizard = new SelectGraphAndSeriesWizard(getCurrentDataset(), null);
IWorkbench workbench = PlatformUI.getWorkbench();
wizard.init(workbench, null);
WizardDialog dialog = new WizardDialog(workbench
@@ -344,9 +583,8 @@ public class SystemTapScriptGraphOptionsTab extends
if (null != gd) {
TableItem item = new TableItem(graphsTable, SWT.NONE);
- item.setText(GraphFactory.getGraphName(gd.graphID) + ":" //$NON-NLS-1$
- + gd.title);
- item.setData(gd);
+ graphsData.add(gd);
+ setUpGraphTableItem(item, gd, false);
updateLaunchConfigurationDialog();
}
}
@@ -356,15 +594,15 @@ public class SystemTapScriptGraphOptionsTab extends
duplicateGraphButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
- GraphData gd = (GraphData) selectedTableItem.getData();
+ GraphData gd = ((GraphData) selectedTableItem.getData()).getCopy();
TableItem item = new TableItem(graphsTable, SWT.NONE);
- item.setText(GraphFactory.getGraphName(gd.graphID) + ":" //$NON-NLS-1$
- + gd.title);
- item.setData(gd);
- if (badGraphs.contains(selectedTableItem)) {
- badGraphs.add(item);
- markGraphTableItem(item, true);
+ graphsData.add(gd);
+ if (badGraphs.contains(selectedTableItem.getData())) {
+ badGraphs.add(gd);
+ setUpGraphTableItem(item, gd, true);
+ } else {
+ setUpGraphTableItem(item, gd, false);
}
updateLaunchConfigurationDialog();
}
@@ -376,7 +614,7 @@ public class SystemTapScriptGraphOptionsTab extends
editGraphButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
- SelectGraphAndSeriesWizard wizard = new SelectGraphAndSeriesWizard(getDataset(),
+ SelectGraphAndSeriesWizard wizard = new SelectGraphAndSeriesWizard(getCurrentDataset(),
(GraphData) selectedTableItem.getData());
IWorkbench workbench = PlatformUI.getWorkbench();
wizard.init(workbench, null);
@@ -386,14 +624,14 @@ public class SystemTapScriptGraphOptionsTab extends
dialog.open();
GraphData gd = wizard.getGraphData();
-
- if (null != gd) {
- selectedTableItem.setText(GraphFactory.getGraphName(gd.graphID) + ":" //$NON-NLS-1$
- + gd.title);
- selectedTableItem.setData(gd);
- if (badGraphs.contains(selectedTableItem)){
- findBadGraphs(selectedTableItem);
- }
+ if (null == gd) {
+ return;
+ }
+ GraphData old_gd = (GraphData) selectedTableItem.getData();
+ if (!gd.equals(old_gd)) {
+ badGraphs.remove(old_gd);
+ setUpGraphTableItem(selectedTableItem, gd, false);
+ graphsData.set(graphsTable.indexOf(selectedTableItem), gd);
updateLaunchConfigurationDialog();
}
}
@@ -403,7 +641,9 @@ public class SystemTapScriptGraphOptionsTab extends
removeGraphButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
- badGraphs.remove(selectedTableItem);
+ GraphData gd = (GraphData) selectedTableItem.getData();
+ graphsData.remove(gd);
+ badGraphs.remove(gd);
selectedTableItem.dispose();
setSelectionControlsEnabled(false);
updateLaunchConfigurationDialog();
@@ -411,117 +651,284 @@ public class SystemTapScriptGraphOptionsTab extends
});
}
+ private void removeRegex(boolean autoSelect) {
+ int removedRegex = selectedRegex;
+ if (autoSelect) {
+ // The current selection is to be removed, so select something else that will be available.
+ regularExpressionCombo.select(selectedRegex != 0 ? selectedRegex - 1 : 1);
+ updateRegexSelection(regularExpressionCombo.getSelectionIndex(), false);
+ }
+
+ regularExpressionCombo.remove(removedRegex);
+ outputList.remove(removedRegex);
+ regexErrorMessages.remove(removedRegex);
+ columnNamesList.remove(removedRegex);
+ cachedNamesList.remove(removedRegex);
+ graphsDataList.remove(removedRegex);
+
+ if (autoSelect) {
+ // Make sure the index of the selection is accurate.
+ selectedRegex = regularExpressionCombo.getSelectionIndex();
+ }
+
+ // Re-add the "Add New Regex" entry if it is missing.
+ if (getNumberOfRegexs() == MAX_NUMBER_OF_REGEXS - 1) {
+ regularExpressionCombo.add(Messages.SystemTapScriptGraphOptionsTab_regexAddNew);
+ }
+
+ // Disable the "remove" button if only one selection is left; never want zero items.
+ if (getNumberOfRegexs() == 1) {
+ removeRegexButton.setEnabled(false);
+ }
+ updateLaunchConfigurationDialog();
+ }
+
+ /**
+ * This handles UI & list updating whenever a different regular expression is selected.
+ * @param newSelection The index of the regex to be selected.
+ * @param force If true, the UI will update even if the index of the selected regex did not change.
+ */
+ private void updateRegexSelection(int newSelection, boolean force) {
+ // Quit if the selection didn't change anything, or if the selection is invalid (-1).
+ if (newSelection == -1 || (!force && selectedRegex == newSelection)) {
+ return;
+ }
+ selectedRegex = newSelection;
+
+ boolean textListenersDisabled = !textListenersEnabled;
+ if (!textListenersDisabled)
+ textListenersEnabled = false;
+
+ sampleOutputText.setText(outputList.get(selectedRegex));
+ cachedNames = cachedNamesList.get(selectedRegex);
+
+ // Update the number of columns and their titles here, and not in refreshRegexRows,
+ // using the list of saved active names instead of a cachedNames stack.
+ ArrayList<String> columnNames = columnNamesList.get(selectedRegex);
+ int desiredNumberOfColumns = columnNames.size();
+ // Remove all columns to easily update them all immediately afterwards.
+ while (numberOfVisibleColumns > 0) {
+ removeColumn(false);
+ }
+ while (numberOfVisibleColumns < desiredNumberOfColumns) {
+ addColumn(columnNames.get(numberOfVisibleColumns));
+ }
+
+ refreshRegexRows();
+
+ // Now, only display graphs that are associated with the selected regex.
+ graphsData = graphsDataList.get(selectedRegex);
+ graphsTable.removeAll();
+ selectedTableItem = null;
+ setSelectionControlsEnabled(false);
+
+ for (GraphData gd : graphsData) {
+ TableItem item = new TableItem(graphsTable, SWT.NONE);
+ setUpGraphTableItem(item, gd, badGraphs.contains(gd));
+ }
+ graphsGroup.setText(MessageFormat.format(Messages.SystemTapScriptGraphOptionsTab_graphSetTitleBase,
+ selectedRegex + 1));
+
+ if (!textListenersDisabled)
+ textListenersEnabled = true;
+ }
+
private void refreshRegexRows() {
try{
- pattern = Pattern.compile(regularExpressionText.getText());
+ pattern = Pattern.compile(regularExpressionCombo.getText());
matcher = pattern.matcher(sampleOutputText.getText());
- this.regexErrorMessage = ""; //$NON-NLS-1$
+ regexErrorMessages.set(selectedRegex, null);
}catch (PatternSyntaxException e){
- this.regexErrorMessage = e.getMessage();
+ regexErrorMessages.set(selectedRegex, e.getMessage());
return;
}
- if (regularExpressionText.getText().contains("()")){ //$NON-NLS-1$
- this.regexErrorMessage = Messages.SystemTapScriptGraphOptionsTab_6;
+ regexErrorMessages.set(selectedRegex, checkRegex(regularExpressionCombo.getText()));
+ if (regexErrorMessages.get(selectedRegex) != null) {
return;
}
- int desiredNumberOfColumns = matcher.groupCount();
+ int desiredNumberOfColumns = matcher.groupCount();
while (numberOfVisibleColumns < desiredNumberOfColumns){
- addColumn();
+ addColumn(null);
}
while (numberOfVisibleColumns > desiredNumberOfColumns){
- removeColumn();
+ removeColumn(true);
}
// Set values
Control[] children = textFieldsComposite.getChildren();
for (int i = 0; i < numberOfVisibleColumns; i++) {
- if (!matcher.matches()){
- ((Label)children[i*2+1]).setText(""); //$NON-NLS-1$
+ String sampleOutputResults;
+ if (matcher.matches()) {
+ sampleOutputResults = matcher.group(i+1);
+ }
+ else if (sampleOutputText.getText().length() == 0){
+ sampleOutputResults = Messages.SystemTapScriptGraphOptionsTab_sampleOutputIsEmpty;
} else {
- ((Label)children[i*2+1]).setText(" " +matcher.group(i+1)); //$NON-NLS-1$
+ sampleOutputResults = Messages.SystemTapScriptGraphOptionsTab_sampleOutputNoMatch;
}
+ ((Label)children[i*2+1]).setText(" " + sampleOutputResults); //$NON-NLS-1$
}
+ // May only add/edit graphs if there is output data being captured.
+ addGraphButton.setEnabled(numberOfVisibleColumns > 0);
+ if (selectedTableItem != null) {
+ editGraphButton.setEnabled(numberOfVisibleColumns > 0);
+ }
+
+ regexErrorMessages.set(selectedRegex, findBadGraphs(selectedRegex));
+ }
+
+ /**
+ * Checks if a provided regular expression is valid.
+ * @param regex The regular expression to check for validity.
+ * @return <code>null</code> if the regular expression is valid, or an error message.
+ */
+ private String checkRegex(String regex) {
+ //TODO may add more invalid regexs here, each with its own error message.
+ if (regex.contains("()")){ //$NON-NLS-1$
+ return Messages.SystemTapScriptGraphOptionsTab_6;
+ }
+ return null;
}
- private void addColumn(){
+ /**
+ * Adds one column to the list of the currently-selected regex's columns.
+ * This creates an extra Text in which the name of the column may be entered,
+ * and a corresponding Label containing sample expected output.
+ * @param nameToAdd If non-null, the name of the newly-created column will
+ * match this String. If null, the column will be given a name recovered from
+ * the active stack of cached names, or a default name if one doesn't exist.
+ */
+ private void addColumn(String nameToAdd) {
Text text = new Text(textFieldsComposite, SWT.BORDER);
GridData data = new GridData(SWT.FILL, SWT.FILL, false, false);
data.minimumWidth = 200;
data.widthHint = 200;
text.setLayoutData(data);
- if (cachedNames.size() > 0) {
- text.setText(cachedNames.pop());
- }
+
+ numberOfVisibleColumns++;
text.addModifyListener(columnNameListener);
+ if (nameToAdd == null) {
+ // Restore a deleted name by popping from the stack.
+ if (cachedNames.size() > 0) {
+ text.setText(cachedNames.pop());
+ } else {
+ text.setText(MessageFormat.format(Messages.SystemTapScriptGraphOptionsTab_defaultColumnTitleBase,
+ numberOfVisibleColumns));
+ }
+ } else {
+ text.setText(nameToAdd);
+ }
Label label = new Label(textFieldsComposite, SWT.BORDER);
label.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
- this.numberOfVisibleColumns++;
- findBadGraphs();
-
textFieldsComposite.layout();
textFieldsComposite.pack();
}
- private void removeColumn(){
+ /**
+ * Removes a column from the currently-selected regex, and removes its
+ * corresponding Text & Label from the UI.
+ * @param saveNames Set to <code>true</code> if the contents of removed
+ * columns are to be saved in a stack for later use.
+ */
+ private void removeColumn(Boolean saveNames) {
Control[] children = textFieldsComposite.getChildren();
int i = this.numberOfVisibleColumns*2 -1;
- cachedNames.push(((Text)children[i-1]).getText());
+
+ if (saveNames) {
+ // Push the removed name on a stack.
+ String name = ((Text)children[i-1]).getText();
+ if (name != null && name != "") { //$NON-NLS-1$
+ cachedNames.push(name);
+ }
+ columnNamesList.get(selectedRegex).remove(numberOfVisibleColumns - 1);
+ }
+
children[i].dispose();
children[i-1].dispose();
this.numberOfVisibleColumns--;
- findBadGraphs();
textFieldsComposite.layout();
textFieldsComposite.pack();
}
- private void findBadGraphs(){
- findBadGraphs(null);
- }
-
- private void findBadGraphs(TableItem itemToCheck){
- TableItem[] items = {itemToCheck};
- if (itemToCheck == null) {
- items = graphsTable.getItems();
- }
- if (items.length == 0){
- badGraphs.clear();
- return;
- }
- for (TableItem item : items){
- GraphData gd = (GraphData) item.getData();
+ /**
+ * Marks all graphs belonging to the indicated regular expression that are
+ * missing column data, or unmarks graphs that aren't missing data.
+ * @param regex The index of the regular expression to check for invalid graphs.
+ * @return An appropriate error message if an invalid graph is found, or if the
+ * selected regular expression parses nothing.
+ */
+ private String findBadGraphs(int regex) {
+ boolean foundBad = false;
+ int numberOfColumns = columnNamesList.get(regex).size();
+ for (GraphData gd : graphsDataList.get(regex)) {
boolean removed = false;
- if (gd.xSeries >= this.numberOfVisibleColumns){
+ if (gd.xSeries >= numberOfColumns) {
removed = true;
}
- for (int s = 0; s < gd.ySeries.length && !removed; s++){
- if (gd.ySeries[s] >= this.numberOfVisibleColumns){
+ for (int s = 0; s < gd.ySeries.length && !removed; s++) {
+ if (gd.ySeries[s] >= numberOfColumns) {
removed = true;
}
}
-
- if (removed){
- if (!badGraphs.contains(item)){
- badGraphs.add(item);
- markGraphTableItem(item, true);
+ if (removed) {
+ foundBad = true;
+ if (!badGraphs.contains(gd)) {
+ badGraphs.add(gd);
+ setUpGraphTableItem(findGraphTableItem(gd), null, true);
}
- }else if (badGraphs.contains(item)){
- badGraphs.remove(item);
- markGraphTableItem(item, false);
+ } else if (badGraphs.contains(gd)) {
+ badGraphs.remove(gd);
+ setUpGraphTableItem(findGraphTableItem(gd), null, false);
}
}
+ if (numberOfColumns == 0) {
+ return Messages.SystemTapScriptGraphOptionsTab_9;
+ }
+ if (foundBad) {
+ return Messages.SystemTapScriptGraphOptionsTab_8;
+ }
+ return null;
}
- private void markGraphTableItem(TableItem item, boolean bad){
+ private TableItem findGraphTableItem(GraphData gd) {
+ for (TableItem item : graphsTable.getItems()) {
+ if (item.getData().equals(gd)) {
+ return item;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Sets up a given {@link TableItem} with the proper title & appearance based on
+ * its graph data & (in)valid status.
+ * @param item The {@link TableItem} to set up.
+ * @param gd The {@link GraphData} that the item will hold. Set to <code>null</code>
+ * to preserve the item's existing data.
+ * @param bad <code>true</code> if the item should appear as invalid, <code>false</code> otherwise.
+ */
+ private void setUpGraphTableItem(TableItem item, GraphData gd, boolean bad) {
+ // Include a null check to avoid accidentally marking non-visible items.
+ if (item == null) {
+ return;
+ }
+ if (gd != null) {
+ item.setData(gd);
+ } else {
+ gd = (GraphData) item.getData();
+ }
item.setForeground(item.getDisplay().getSystemColor(bad ? SWT.COLOR_RED : SWT.COLOR_BLACK));
+ item.setText(GraphFactory.getGraphName(gd.graphID) + ":" + gd.title //$NON-NLS-1$
+ + (bad ? " " + Messages.SystemTapScriptGraphOptionsTab_invalidGraph : "")); //$NON-NLS-1$ //$NON-NLS-2$
}
public boolean canFlipToNextPage() {
@@ -531,54 +938,85 @@ public class SystemTapScriptGraphOptionsTab extends
@Override
public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
configuration.setAttribute(RUN_WITH_CHART, false);
- configuration.setAttribute(NUMBER_OF_COLUMNS, 0);
- configuration.setAttribute(NUMBER_OF_GRAPHS, 0);
- configuration.setAttribute(NUMBER_OF_GRAPHS, 0);
- configuration.setAttribute(REGULARE_EXPRESSION, ""); //$NON-NLS-1$
- configuration.setAttribute(SAMPLE_OUTPUT, ""); //$NON-NLS-1$
+ configuration.setAttribute(NUMBER_OF_REGEXS, 1);
+ configuration.setAttribute(NUMBER_OF_COLUMNS + 0, 0);
+ configuration.setAttribute(NUMBER_OF_EXTRAS + 0, 0);
+ configuration.setAttribute(REGULAR_EXPRESSION + 0, ""); //$NON-NLS-1$
+ configuration.setAttribute(SAMPLE_OUTPUT + 0, ""); //$NON-NLS-1$
+ configuration.setAttribute(NUMBER_OF_GRAPHS + 0, 0);
}
@Override
public void initializeFrom(ILaunchConfiguration configuration) {
try {
+ textListenersEnabled = false;
+
boolean chart = configuration.getAttribute(RUN_WITH_CHART, false);
setGraphingEnabled(chart);
this.runWithChartCheckButton.setSelection(chart);
- regularExpressionText.setText(configuration.getAttribute(REGULARE_EXPRESSION, "")); //$NON-NLS-1$
- sampleOutputText.setText(configuration.getAttribute(SAMPLE_OUTPUT, "")); //$NON-NLS-1$
+ // Reset lists & settings to keep things idempotent.
+ regularExpressionCombo.removeAll();
+ outputList.clear();
+ regexErrorMessages.clear();
+ columnNamesList.clear();
+ cachedNamesList.clear();
+ graphsTable.removeAll();
+ badGraphs.clear();
+
+ // There should always be at least one regular expression (a blank one still counts).
+ // If configuration's number of regexs is zero, it is outdated.
+ int numberOfRegexs = Math.max(configuration.getAttribute(NUMBER_OF_REGEXS, 1), 1);
- oldNumColumns = configuration.getAttribute(NUMBER_OF_COLUMNS, 0);
- Control[] textBoxes = this.textFieldsComposite.getChildren();
+ // Only allow removing regexs if there are more than one.
+ removeRegexButton.setEnabled(numberOfRegexs > 1);
- for (int i = 0; i < oldNumColumns && i*2 < textBoxes.length; i++) {
- String text = configuration.getAttribute(REGEX_BOX+i, (String)null);
- if (text != null) {
- ((Text)textBoxes[i*2]).setText(text);
+ for (int r = 0; r < numberOfRegexs; r++) {
+ // Save all of the configuration's regular expressions & sample outputs in a list.
+ regularExpressionCombo.add(configuration.getAttribute(REGULAR_EXPRESSION + r, "")); //$NON-NLS-1$
+ outputList.add(configuration.getAttribute(SAMPLE_OUTPUT + r, "")); //$NON-NLS-1$
+
+ // Save each regex's list of group names.
+ int numberOfColumns = configuration.getAttribute(NUMBER_OF_COLUMNS + r, 0);
+ ArrayList<String> namelist = new ArrayList<String>(numberOfColumns);
+ for (int i = 0; i < numberOfColumns; i++) {
+ namelist.add(configuration.getAttribute(get2DConfigData(REGEX_BOX, r, i), (String)null));
}
- }
+ columnNamesList.add(namelist);
+
+ //Reclaim missing column data that was required for existing graphs at the time of the previous "apply".
+ int numberOfExtras = configuration.getAttribute(NUMBER_OF_EXTRAS + r, 0);
+ Stack<String> oldnames = new Stack<String>();
+ for (int i = 0; i < numberOfExtras; i++) {
+ oldnames.push(configuration.getAttribute(get2DConfigData(EXTRA_BOX, r, i), (String)null));
+ }
+ cachedNamesList.add(oldnames);
- cachedNames.clear();
- oldNumExtras = configuration.getAttribute(NUMBER_OF_EXTRAS, 0);
- for (int i = oldNumExtras-1; i >= 0; i--) {
- cachedNames.push(configuration.getAttribute(EXTRA_BOX+i, "")); //$NON-NLS-1$
+ regexErrorMessages.add(null);
+ }
+ if (getNumberOfRegexs() < MAX_NUMBER_OF_REGEXS) {
+ regularExpressionCombo.add(Messages.SystemTapScriptGraphOptionsTab_regexAddNew);
}
+ // When possible, preserve the selection on subsequent initializations, for user convenience.
+ int defaultSelectedRegex = 0 <= selectedRegex && selectedRegex < numberOfRegexs ? selectedRegex : 0;
+ regularExpressionCombo.select(defaultSelectedRegex);
+
// Add graphs
- graphsTable.removeAll();
- badGraphs.clear();
- LinkedList<GraphData> graphs = createGraphsFromConfiguration(configuration);
- for (GraphData graphData : graphs) {
+ graphsDataList = createGraphsFromConfiguration(configuration);
+ graphsData = graphsDataList.get(defaultSelectedRegex);
+ for (GraphData graphData : graphsData) {
TableItem item = new TableItem(graphsTable, SWT.NONE);
- item.setText(GraphFactory.getGraphName(graphData.graphID) + ":" //$NON-NLS-1$
- + graphData.title);
- item.setForeground(item.getDisplay().getSystemColor(SWT.COLOR_BLACK));
- item.setData(graphData);
- findBadGraphs(item);
+ setUpGraphTableItem(item, graphData, true);
}
+ updateRegexSelection(0, true); // Handles all remaining updates.
+ checkAllOtherErrors();
+
} catch (CoreException e) {
ExceptionErrorDialog.openError(Messages.SystemTapScriptGraphOptionsTab_5, e);
+ } finally {
+ textListenersEnabled = true;
}
}
@@ -586,51 +1024,134 @@ public class SystemTapScriptGraphOptionsTab extends
public void performApply(ILaunchConfigurationWorkingCopy configuration) {
configuration.setAttribute(RUN_WITH_CHART, this.runWithChartCheckButton.getSelection());
- configuration.setAttribute(REGULARE_EXPRESSION, regularExpressionText.getText());
- configuration.setAttribute(SAMPLE_OUTPUT, sampleOutputText.getText());
-
- Control[] textBoxes = this.textFieldsComposite.getChildren();
- int numberOfColumns = textBoxes.length/2;
- configuration.setAttribute(NUMBER_OF_COLUMNS, numberOfColumns);
+ int numberOfRegexs = getNumberOfRegexs();
+ for (int r = 0; r < numberOfRegexs; r++) {
+ // Save data sets, and clear removed ones.
+ configuration.setAttribute(REGULAR_EXPRESSION + r, regularExpressionCombo.getItem(r));
+ configuration.setAttribute(SAMPLE_OUTPUT + r, outputList.get(r));
- for (int i = 0; i < numberOfColumns; i++) {
- String text = ((Text)textBoxes[i*2]).getText();
- configuration.setAttribute(REGEX_BOX+i, text);
+ ArrayList<String> columnNames = columnNamesList.get(r);
+ int numberOfColumns = columnNames.size();
+ for (int i = 0; i < numberOfColumns; i++) {
+ configuration.setAttribute(get2DConfigData(REGEX_BOX, r, i), columnNames.get(i));
+ }
+ cleanUpConfigurationItem(configuration, NUMBER_OF_COLUMNS, REGEX_BOX, r, numberOfColumns);
+ configuration.setAttribute(NUMBER_OF_COLUMNS + r, numberOfColumns);
+
+ // If the current regex has graphs with missing data, store all cached names
+ // in the configuration so that they will be easily restorable for next time.
+ Stack<String> extranames = cachedNamesList.get(r);
+ int numberOfExtras = findBadGraphs(r) == null ? 0 : extranames.size();
+ for (int i = 0; i < numberOfExtras; i++) {
+ configuration.setAttribute(get2DConfigData(EXTRA_BOX, r, i), extranames.get(i));
+ }
+ cleanUpConfigurationItem(configuration, NUMBER_OF_EXTRAS, EXTRA_BOX, r, numberOfExtras);
+ configuration.setAttribute(NUMBER_OF_EXTRAS + r, numberOfExtras);
+
+ // Save new graphs, and clear removed ones.
+ LinkedList<GraphData> list = graphsDataList.get(r);
+ int numberOfGraphs = list.size();
+ for (int i = 0; i < numberOfGraphs; i++) {
+ GraphData graphData = list.get(i);
+ configuration.setAttribute(get2DConfigData(GRAPH_TITLE, r, i), graphData.title);
+ configuration.setAttribute(get2DConfigData(GRAPH_KEY, r, i), graphData.key);
+ configuration.setAttribute(get2DConfigData(GRAPH_X_SERIES, r, i), graphData.xSeries);
+ configuration.setAttribute(get2DConfigData(GRAPH_ID, r, i), graphData.graphID);
+
+ int ySeriesLength = graphData.ySeries.length;
+ for (int j = 0; j < ySeriesLength; j++) {
+ configuration.setAttribute(get2DConfigData(GRAPH_Y_SERIES, r, i + "_" + j), //$NON-NLS-1$
+ graphData.ySeries[j]);
+ }
+ cleanUpConfigurationGraphYSeries(configuration, r, i, ySeriesLength);
+ configuration.setAttribute(get2DConfigData(GRAPH_Y_SERIES_LENGTH, r, i), ySeriesLength);
+ }
+ cleanUpConfigurationGraphs(configuration, r, numberOfGraphs);
+ configuration.setAttribute(NUMBER_OF_GRAPHS + r, numberOfGraphs);
}
- //clear what's unused
- for (int i = numberOfColumns; i < oldNumColumns; i++) {
- configuration.setAttribute(REGEX_BOX+i, (String) null);
+ cleanUpConfiguration(configuration, numberOfRegexs);
+ configuration.setAttribute(NUMBER_OF_REGEXS, numberOfRegexs);
+ }
+
+ /**
+ * Removes all configuration attributes associated with deleted regular expressions.
+ * @param configuration The configuration to remove attributes from.
+ * @param numberOfRegexs The number of regex-related properties to exist in the
+ * configuration after cleanup.
+ */
+ private void cleanUpConfiguration(ILaunchConfigurationWorkingCopy configuration, int numberOfRegexs) {
+ int oldNumberOfRegexs = 0;
+ try {
+ oldNumberOfRegexs = configuration.getAttribute(NUMBER_OF_REGEXS, 0);
+ } catch (CoreException e) {}
+ for (int r = numberOfRegexs; r < oldNumberOfRegexs; r++) {
+ configuration.removeAttribute(REGULAR_EXPRESSION + r);
+ configuration.removeAttribute(SAMPLE_OUTPUT + r);
+
+ cleanUpConfigurationItem(configuration, NUMBER_OF_COLUMNS, REGEX_BOX, r, 0);
+ configuration.removeAttribute(NUMBER_OF_COLUMNS + r);
+
+ cleanUpConfigurationItem(configuration, NUMBER_OF_COLUMNS, EXTRA_BOX, r, 0);
+ configuration.removeAttribute(NUMBER_OF_EXTRAS + r);
+
+ cleanUpConfigurationGraphs(configuration, r, 0);
+ configuration.removeAttribute(NUMBER_OF_GRAPHS + r);
}
- oldNumColumns = numberOfColumns;
+ }
- int numberOfExtras = (badGraphs.size() == 0) ? 0 : cachedNames.size();
- configuration.setAttribute(NUMBER_OF_EXTRAS, numberOfExtras);
- for (int i = 0; i < numberOfExtras; i++) {
- configuration.setAttribute(EXTRA_BOX+i, cachedNames.get(i));
+ private void cleanUpConfigurationGraphs(ILaunchConfigurationWorkingCopy configuration, int regex, int newNumberOfGraphs) {
+ int oldNumberOfGraphs = 0;
+ try {
+ oldNumberOfGraphs = configuration.getAttribute(NUMBER_OF_GRAPHS + regex, 0);
+ } catch (CoreException e) {}
+ for (int i = newNumberOfGraphs; i < oldNumberOfGraphs; i++) {
+ configuration.removeAttribute(get2DConfigData(GRAPH_TITLE, regex, i));
+ configuration.removeAttribute(get2DConfigData(GRAPH_KEY, regex, i));
+ configuration.removeAttribute(get2DConfigData(GRAPH_X_SERIES, regex, i));
+ configuration.removeAttribute(get2DConfigData(GRAPH_ID, regex, i));
+
+ cleanUpConfigurationGraphYSeries(configuration, regex, i, 0);
+ configuration.removeAttribute(get2DConfigData(GRAPH_Y_SERIES_LENGTH, regex, i));
}
- for (int i = numberOfExtras; i < oldNumExtras; i++) {
- configuration.setAttribute(EXTRA_BOX+i, (String) null);
+ }
+
+ private void cleanUpConfigurationItem(ILaunchConfigurationWorkingCopy configuration, String counter, String property, int regex, int newNumberOfItems) {
+ int oldNumberOfItems = 0;
+ try {
+ oldNumberOfItems = configuration.getAttribute(counter + regex, 0);
+ } catch (CoreException e) {}
+ for (int i = newNumberOfItems; i < oldNumberOfItems; i++) {
+ configuration.removeAttribute(get2DConfigData(property, regex, i));
}
- oldNumExtras = numberOfExtras;
+ }
- // Save graphs.
- TableItem[] list = this.graphsTable.getItems();
- configuration.setAttribute(NUMBER_OF_GRAPHS, list.length);
- for (int i = 0; i < list.length; i++) {
- GraphData graphData = (GraphData)list[i].getData();
- configuration.setAttribute(GRAPH_TITLE + i, graphData.title);
+ private void cleanUpConfigurationGraphYSeries(ILaunchConfigurationWorkingCopy configuration, int regex, int graph, int newLength) {
+ int oldYSeriesLength = 0;
+ try {
+ oldYSeriesLength = configuration.getAttribute(get2DConfigData(GRAPH_Y_SERIES_LENGTH, regex, graph), 0);
+ } catch (CoreException e) {}
+ for (int i = newLength; i < oldYSeriesLength; i++) {
+ configuration.removeAttribute(get2DConfigData(GRAPH_Y_SERIES, regex, graph + "_" + i)); //$NON-NLS-1$
+ }
+ }
- configuration.setAttribute(GRAPH_KEY + i, graphData.key);
- configuration.setAttribute(GRAPH_X_SERIES + i, graphData.xSeries);
- configuration.setAttribute(GRAPH_ID + i, graphData.graphID);
+ /**
+ * Checks all regular expressions for errors, except for the currently-selected
+ * expression (as it should be checked by {@link #refreshRegexRows}).
+ */
+ private void checkAllOtherErrors() {
+ for (int i = 0, n = getNumberOfRegexs(); i < n; i++) {
+ if (i == selectedRegex) {
+ continue;
+ }
- configuration.setAttribute(GRAPH_Y_SERIES_LENGTH + i, graphData.ySeries.length);
- for (int j = 0; j < graphData.ySeries.length; j++) {
- configuration.setAttribute(GRAPH_Y_SERIES + i + "_" + j, graphData.ySeries[j]); //$NON-NLS-1$
+ String error = findBadGraphs(i);
+ if (error == null) {
+ error = checkRegex(regularExpressionCombo.getItem(i));
}
- }
- addGraphButton.setEnabled(numberOfColumns > 0);
+ regexErrorMessages.set(i, error);
+ }
}
@Override
@@ -642,17 +1163,12 @@ public class SystemTapScriptGraphOptionsTab extends
return true;
}
- if (!this.regexErrorMessage.equals("")){ //$NON-NLS-1$
- setErrorMessage(regexErrorMessage);
- return false;
- }
- if (this.numberOfVisibleColumns == 0){
- setErrorMessage(Messages.SystemTapScriptGraphOptionsTab_9);
- return false;
- }
- if (badGraphs.size() > 0){
- setErrorMessage(Messages.SystemTapScriptGraphOptionsTab_8);
- return false;
+ for (int i = 0, n = getNumberOfRegexs(); i < n; i++) {
+ String regexErrorMessage = regexErrorMessages.get(i);
+ if (regexErrorMessage != null){
+ setErrorMessage(String.format("Expression \"%s\": %s", regularExpressionCombo.getItems()[i], regexErrorMessage)); //$NON-NLS-1$
+ return false;
+ }
}
return true;
@@ -678,6 +1194,9 @@ public class SystemTapScriptGraphOptionsTab extends
this.setControlEnabled(graphsGroup, enabled);
// Disable buttons that rely on a selected graph if no graph is selected.
this.setSelectionControlsEnabled(selectedTableItem != null);
+ this.addGraphButton.setEnabled(enabled && numberOfVisibleColumns > 0);
+ this.editGraphButton.setEnabled(enabled && numberOfVisibleColumns > 0);
+ this.removeRegexButton.setEnabled(enabled && getNumberOfRegexs() > 1);
updateLaunchConfigurationDialog();
}
@@ -697,7 +1216,7 @@ public class SystemTapScriptGraphOptionsTab extends
*/
private void setSelectionControlsEnabled(boolean enabled) {
duplicateGraphButton.setEnabled(enabled);
- editGraphButton.setEnabled(enabled);
+ editGraphButton.setEnabled(enabled && numberOfVisibleColumns > 0);
removeGraphButton.setEnabled(enabled);
}
}

Back to the top