/******************************************************************************* | |
* Copyright (c) 2011, 2014 IBM Corporation 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: | |
* IBM Corporation - initial API and implementation | |
* SAP - ongoing enhancements | |
*******************************************************************************/ | |
package org.eclipse.ui.trace.internal; | |
import static org.eclipse.jface.viewers.ColumnViewerEditor.KEYBOARD_ACTIVATION; | |
import static org.eclipse.jface.viewers.ColumnViewerEditor.TABBING_HORIZONTAL; | |
import static org.eclipse.jface.viewers.ColumnViewerEditor.TABBING_MOVE_TO_ROW_NEIGHBOR; | |
import static org.eclipse.jface.viewers.ColumnViewerEditor.TABBING_VERTICAL; | |
import static org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent.KEY_PRESSED; | |
import static org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent.MOUSE_CLICK_SELECTION; | |
import static org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent.PROGRAMMATIC; | |
import static org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent.TRAVERSAL; | |
import java.io.File; | |
import java.util.*; | |
import org.eclipse.core.runtime.*; | |
import org.eclipse.core.runtime.preferences.IEclipsePreferences; | |
import org.eclipse.jface.layout.*; | |
import org.eclipse.jface.preference.PreferencePage; | |
import org.eclipse.jface.resource.JFaceResources; | |
import org.eclipse.jface.util.Util; | |
import org.eclipse.jface.viewers.*; | |
import org.eclipse.swt.SWT; | |
import org.eclipse.swt.events.SelectionAdapter; | |
import org.eclipse.swt.events.SelectionEvent; | |
import org.eclipse.swt.layout.GridData; | |
import org.eclipse.swt.layout.GridLayout; | |
import org.eclipse.swt.widgets.*; | |
import org.eclipse.ui.*; | |
import org.eclipse.ui.dialogs.FilteredTree; | |
import org.eclipse.ui.trace.internal.datamodel.*; | |
import org.eclipse.ui.trace.internal.providers.*; | |
import org.eclipse.ui.trace.internal.utils.*; | |
/** | |
* The 'Tracing' workspace preference page. | |
*/ | |
public class TracingPreferencePage extends PreferencePage implements IWorkbenchPreferencePage { | |
/** | |
* The key to activate the value cell editor. | |
* Cannot use the usual enter (CR) key to activate it since this would close the page. Fix is to use | |
* the space key as replacement. | |
* On Linux, however, space is used as default key on ComboBoxes, leading to the editor being deactivated. | |
* We use F2 instead. | |
*/ | |
private static final int VALUE_EDITOR_ACTIVATION_KEY = Util.isLinux() ? SWT.F2 : SWT.SPACE; | |
/** A list of {@link TracingComponent} objects to display in the UI */ | |
private Map<String, TracingComponent> displayableTracingComponents = null; | |
// widgets | |
/** Enabling Tracing button */ | |
protected Button enableTracingButton = null; | |
/** Tracing tree title*/ | |
protected Label tracingTreeTitleLabel = null; | |
/** A tree that can be filtered based on user input */ | |
protected FilteredTree filterTree = null; | |
/** A {@link Group} containing all of the tracing file options */ | |
protected Group tracingOptionsGroup = null; | |
/** A {@link Text} field for specify the tracing file */ | |
protected Text tracingFileText = null; | |
/** A {@link Text} field for specify the maximum size of the tracing files */ | |
protected Spinner maximumFileSizeSpinner = null; | |
/** A {@link Text} field for specify the maximum number of tracing files */ | |
protected Spinner maximumFileCountSpinner = null; | |
/** A {@link Button} for browsing the file-system for the tracing file */ | |
protected Button tracingFileBrowseButton = null; | |
/** A {@link Button} for 'Output file:' */ | |
protected Button tracingOutputFileButton = null; | |
/** A {@link Label} for 'Number of historical files:' */ | |
protected Label tracingFileMaxCountLabel = null; | |
/** A {@link Label} for 'Maximum file size (KB):' */ | |
protected Label tracingFileMaxSizeLabel = null; | |
/** A {@link Button} for 'Standard output stream:' */ | |
protected Button standardOutputStreamButton; | |
/** | |
* Constructor for {@link TracingPreferencePage} | |
*/ | |
public TracingPreferencePage() { | |
setDescription(Messages.preferencePageDescription); | |
} | |
public void init(IWorkbench workbench) { | |
// empty implementation | |
} | |
/* (non-Javadoc) | |
* @see org.eclipse.jface.dialogs.DialogPage#dispose() | |
*/ | |
@Override | |
public void dispose() { | |
super.dispose(); | |
disposeWidget(enableTracingButton); | |
disposeWidget(tracingTreeTitleLabel); | |
disposeWidget(filterTree); | |
disposeWidget(tracingOptionsGroup); | |
disposeWidget(tracingOutputFileButton); | |
disposeWidget(tracingFileText); | |
disposeWidget(tracingFileBrowseButton); | |
disposeWidget(tracingFileMaxCountLabel); | |
disposeWidget(maximumFileCountSpinner); | |
disposeWidget(tracingFileMaxSizeLabel); | |
disposeWidget(maximumFileSizeSpinner); | |
disposeWidget(standardOutputStreamButton); | |
purgeModel(); | |
} | |
/** | |
* A utility method to purge all caches used by the preference page | |
*/ | |
private void purgeModel() { | |
if (displayableTracingComponents != null) { | |
// clear the displayable tracing component cache | |
displayableTracingComponents.clear(); | |
displayableTracingComponents = null; | |
} | |
// clear the component caches | |
TracingCollections.getInstance().clear(); | |
} | |
/** | |
* A utility method to dispose a widget. | |
* | |
* @param widget | |
* The widget to dispose | |
*/ | |
private void disposeWidget(Widget widget) { | |
if (widget != null) { | |
if (!widget.isDisposed()) { | |
widget.dispose(); | |
} | |
} | |
} | |
@Override | |
protected Control createContents(Composite parent) { | |
Composite pageComposite = new Composite(parent, SWT.NONE); | |
GridLayoutFactory.fillDefaults().applyTo(pageComposite); | |
GridDataFactory.fillDefaults().grab(true, true).applyTo(pageComposite); | |
// add the widgets | |
addEnableTracingSection(pageComposite); | |
addBundleViewerSection(pageComposite); | |
addTracingOptionsSection(pageComposite); | |
// set the initial values in the widgets | |
setUIValuesFromPreferences(); | |
enableTracingButtonSelected(true); | |
// disable after enableTracingButton. | |
if (Boolean.parseBoolean(PreferenceHandler.getOutputToStandardStream())) { | |
setEnableTracingOutputFile(false); | |
} | |
// apply the font to this page | |
applyDialogFont(pageComposite); | |
PlatformUI.getWorkbench().getHelpSystem().setHelp(pageComposite, IHelpContextIds.TRACING_PREF_PAGE); | |
return pageComposite; | |
} | |
/** | |
* Add a section for a check button to be displayed like "[] Enable Tracing" | |
* | |
* @param parent | |
* The parent composite | |
*/ | |
protected void addEnableTracingSection(Composite parent) { | |
// If the preferences are being overridden by debug mode at launch time, warn the user | |
if (DebugOptionsHandler.isLaunchInDebugMode()) { | |
Composite warningComp = new Composite(parent, SWT.NONE); | |
GridData gd = new GridData(GridData.FILL, GridData.BEGINNING, true, false); | |
warningComp.setLayoutData(gd); | |
GridLayout gl = new GridLayout(2, false); | |
gl.marginWidth = gl.marginHeight = 0; | |
warningComp.setLayout(gl); | |
Label warningImage = new Label(warningComp, SWT.NONE); | |
warningImage.setImage(JFaceResources.getImage(org.eclipse.jface.dialogs.Dialog.DLG_IMG_MESSAGE_WARNING)); | |
gd = new GridData(GridData.BEGINNING, GridData.BEGINNING, false, false); | |
warningImage.setLayoutData(gd); | |
Label warningText = new Label(warningComp, SWT.WRAP); | |
warningText.setText(Messages.TracingPreferencePage_applicationLaunchedInDebugModeWarning); | |
gd = new GridData(GridData.FILL, GridData.BEGINNING, true, false); | |
gd.widthHint = 200; | |
warningText.setLayoutData(gd); | |
} | |
enableTracingButton = new Button(parent, SWT.CHECK); | |
enableTracingButton.setText(Messages.enableTracingButtonLabel); | |
GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.BEGINNING).grab(true, false).applyTo(enableTracingButton); | |
enableTracingButton.addSelectionListener(new SelectionAdapter() { | |
@Override | |
public void widgetSelected(SelectionEvent e) { | |
enableTracingButtonSelected(true); | |
} | |
}); | |
} | |
/** | |
* Create a viewer for the list of debug options that are traceable in the product. | |
* | |
* @param parent | |
* The parent composite | |
*/ | |
protected void addBundleViewerSection(Composite parent) { | |
tracingTreeTitleLabel = new Label(parent, SWT.NONE); | |
tracingTreeTitleLabel.setText(Messages.tracingTreeTile); | |
filterTree = new TracingComponentTreeViewer(parent); | |
GridDataFactory.fillDefaults().grab(true, true).applyTo(getViewerTree()); | |
getViewer().setUseHashlookup(true); | |
getViewerTree().setHeaderVisible(false); | |
getViewer().setLabelProvider(new TracingComponentLabelProvider()); | |
getViewer().setContentProvider(new TracingComponentContentProvider()); | |
getViewer().setComparator(new TracingComponentComparator()); | |
getViewerTree().setLinesVisible(true); | |
getViewer().addDoubleClickListener(new TracingDoubleClickListener()); | |
// change the layout of the tree's composite to TreeColumnLayout so we can setup the columns | |
Composite treeViewerComposite = getViewerTree().getParent(); | |
TreeColumnLayout treeViewerCompositeLayout = new TreeColumnLayout(); | |
treeViewerComposite.setLayout(treeViewerCompositeLayout); | |
GridDataFactory.fillDefaults().grab(true, true).applyTo(treeViewerComposite); | |
// there will be 2 columns. (1) trace string (2) value (which will only be populated when it is a non-boolean | |
// value) | |
// [1] Add the label column (75% column width) | |
TreeViewerColumn labelColumn = new TreeViewerColumn(getViewer(), SWT.NONE); | |
labelColumn.getColumn().setResizable(true); | |
labelColumn.getColumn().setText(Messages.columnHeaderTracingString); | |
labelColumn.setLabelProvider(new TracingComponentColumnLabelProvider(TracingConstants.LABEL_COLUMN_INDEX)); | |
treeViewerCompositeLayout.setColumnData(getViewerTree().getColumn(0), new ColumnWeightData(75)); | |
// [2] Add the value column (25% column width) | |
TreeViewerColumn valueColumn = new TreeViewerColumn(getViewer(), SWT.NONE); | |
valueColumn.getColumn().setResizable(true); | |
valueColumn.getColumn().setText(Messages.columnHeaderTracingValue); | |
valueColumn.setLabelProvider(new TracingComponentColumnLabelProvider(TracingConstants.VALUE_COLUMN_INDEX)); | |
valueColumn.setEditingSupport(new TracingComponentColumnEditingSupport(getViewer(), TracingConstants.VALUE_COLUMN_INDEX)); | |
treeViewerCompositeLayout.setColumnData(getViewerTree().getColumn(1), new ColumnWeightData(25)); | |
// install focus cell and cell editor activation for keyboard access (Bug 385100) | |
TreeViewerFocusCellManager focusCellManager = new TreeViewerFocusCellManager(getViewer(), new FocusCellOwnerDrawHighlighter(getViewer())); | |
ColumnViewerEditorActivationStrategy actSupport = new ColumnViewerEditorActivationStrategy(getViewer()) { | |
@Override | |
protected boolean isEditorActivationEvent(ColumnViewerEditorActivationEvent event) { | |
return (event.eventType == KEY_PRESSED && event.keyCode == VALUE_EDITOR_ACTIVATION_KEY) // | |
|| event.eventType == TRAVERSAL // | |
|| event.eventType == MOUSE_CLICK_SELECTION // | |
|| event.eventType == PROGRAMMATIC; | |
} | |
}; | |
TreeViewerEditor.create(getViewer(), focusCellManager, actSupport, // | |
TABBING_HORIZONTAL | TABBING_MOVE_TO_ROW_NEIGHBOR | TABBING_VERTICAL | KEYBOARD_ACTIVATION); | |
} | |
/** | |
* Create a section for displaying the tracing file options (i.e. maximum size of each file, number of historical | |
* files, etc). | |
* | |
* @param parent | |
* The parent composite | |
*/ | |
protected void addTracingOptionsSection(Composite parent) { | |
tracingOptionsGroup = new Group(parent, SWT.NONE); | |
tracingOptionsGroup.setText(Messages.tracingOptionsGroup); | |
GridDataFactory.fillDefaults().grab(true, false).applyTo(tracingOptionsGroup); | |
GridLayoutFactory.fillDefaults().margins(5, 5).applyTo(tracingOptionsGroup); | |
Composite outputComp = new Composite(tracingOptionsGroup, SWT.NONE); | |
GridDataFactory.fillDefaults().grab(true, false).applyTo(outputComp); | |
GridLayoutFactory.fillDefaults().numColumns(3).equalWidth(false).margins(0, 0).applyTo(outputComp); | |
// add the 'tracing file' group | |
tracingOutputFileButton = new Button(outputComp, SWT.RADIO); | |
tracingOutputFileButton.setText(Messages.tracingFileLabel); | |
tracingOutputFileButton.setSelection(true); // during creation - select this option | |
tracingOutputFileButton.addSelectionListener(new SelectionAdapter() { | |
@Override | |
public void widgetSelected(SelectionEvent e) { | |
setEnableTracingOutputFile(true); | |
standardOutputStreamButton.setSelection(false); | |
} | |
}); | |
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).applyTo(tracingOutputFileButton); | |
// add the 'tracing file' input field | |
tracingFileText = new Text(outputComp, SWT.SINGLE | SWT.BORDER); | |
tracingFileText.addListener(SWT.Verify, new Listener() { | |
public void handleEvent(Event e) { | |
String newInput = TracingPreferencePage.this.getInput(e); | |
if ((newInput == null) || newInput.equals(TracingConstants.EMPTY_STRING)) { | |
TracingPreferencePage.this.setValid(false); | |
TracingPreferencePage.this.setErrorMessage(Messages.tracingFileInvalid); | |
} else { | |
TracingPreferencePage.this.setValid(true); | |
TracingPreferencePage.this.setErrorMessage(null); | |
} | |
} | |
}); | |
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).grab(true, false).applyTo(tracingFileText); | |
// add the 'tracing file' browse button | |
tracingFileBrowseButton = new Button(outputComp, SWT.PUSH); | |
tracingFileBrowseButton.setText(Messages.tracingFileBrowseButton); | |
tracingFileBrowseButton.addSelectionListener(new SelectionAdapter() { | |
@Override | |
public void widgetSelected(SelectionEvent e) { | |
FileDialog dialog = new FileDialog(tracingOptionsGroup.getShell(), SWT.SAVE); | |
dialog.setFileName(tracingFileText.getText()); | |
String result = dialog.open(); | |
if (result != null) { | |
tracingFileText.setText(result); | |
} | |
} | |
}); | |
setButtonLayoutData(tracingFileBrowseButton); | |
Composite detailsComp = new Composite(tracingOptionsGroup, SWT.NONE); | |
GridLayoutFactory.fillDefaults().numColumns(5).equalWidth(false).margins(0, 0).applyTo(detailsComp); | |
GridDataFactory.fillDefaults().grab(true, false).applyTo(detailsComp); | |
// add the 'max count' label | |
tracingFileMaxCountLabel = new Label(detailsComp, SWT.NONE); | |
tracingFileMaxCountLabel.setText(Messages.tracingFileMaxCountLabel); | |
// put horizontal indentation | |
GridData gridData = new GridData(); | |
gridData.horizontalIndent = 20; | |
tracingFileMaxCountLabel.setLayoutData(gridData); | |
// add the 'max count' input field | |
maximumFileCountSpinner = new Spinner(detailsComp, SWT.SINGLE | SWT.BORDER); | |
maximumFileCountSpinner.setValues(10, 10, 100, 0, 5, 10); | |
maximumFileCountSpinner.addListener(SWT.Verify, new Listener() { | |
public void handleEvent(Event e) { | |
TracingPreferencePage.this.verifyIntInput(e, Messages.tracingFileInvalidMaxCount); | |
} | |
}); | |
GridDataFactory.fillDefaults().applyTo(maximumFileCountSpinner); | |
Label spacer = new Label(detailsComp, SWT.NONE); | |
GridDataFactory.fillDefaults().hint(10, 10).applyTo(spacer); | |
// add the 'max size' label | |
tracingFileMaxSizeLabel = new Label(detailsComp, SWT.NONE); | |
tracingFileMaxSizeLabel.setText(Messages.tracingFileMaxSizeLabel); | |
// add the 'max size' input field | |
maximumFileSizeSpinner = new Spinner(detailsComp, SWT.SINGLE | SWT.BORDER); | |
maximumFileSizeSpinner.setValues(100, 100, 10000, 0, 100, 1000); | |
maximumFileSizeSpinner.addListener(SWT.Verify, new Listener() { | |
public void handleEvent(Event e) { | |
TracingPreferencePage.this.verifyIntInput(e, Messages.tracingFileInvalidMaxSize); | |
} | |
}); | |
GridDataFactory.fillDefaults().applyTo(maximumFileSizeSpinner); | |
standardOutputStreamButton = new Button(tracingOptionsGroup, SWT.RADIO); | |
standardOutputStreamButton.setText(Messages.TracingPreferencePageStandardOutput); | |
standardOutputStreamButton.addSelectionListener(new SelectionAdapter() { | |
@Override | |
public void widgetSelected(SelectionEvent e) { | |
setEnableTracingOutputFile(false); | |
standardOutputStreamButton.setSelection(true); | |
} | |
}); | |
} | |
/** | |
* select the outputFileButton and enable rest of the widgets if enable true | |
* deselect the outputFileButton and disable rest of the widgets if enable false | |
*/ | |
private void setEnableTracingOutputFile(boolean enable) { | |
tracingOutputFileButton.setSelection(enable); | |
tracingFileText.setEnabled(enable); | |
maximumFileSizeSpinner.setEnabled(enable); | |
maximumFileCountSpinner.setEnabled(enable); | |
tracingFileBrowseButton.setEnabled(enable); | |
tracingFileMaxCountLabel.setEnabled(enable); | |
tracingFileMaxSizeLabel.setEnabled(enable); | |
} | |
/** | |
* Set the default state and value of all the UI elements based on the value in the preferences. This can only be | |
* called after all the UI elements have been constructed. | |
*/ | |
protected void setUIValuesFromPreferences() { | |
// If in debug mode, tracing defaults to disabled | |
if (!DebugOptionsHandler.isLaunchInDebugMode()) { | |
// acquire the preferences service | |
boolean tracingEnabled = PreferenceHandler.isTracingEnabled(); | |
// HACK: because there is no way for me to enable tracing during preference import (??) - I am doing it here. | |
if (tracingEnabled && !DebugOptionsHandler.getDebugOptions().isDebugEnabled()) { | |
// the preferences say that tracing should be enabled | |
DebugOptionsHandler.getDebugOptions().setDebugEnabled(true); | |
} | |
// set enablement button | |
enableTracingButton.setSelection(tracingEnabled); | |
} else { | |
enableTracingButton.setSelection(false); | |
} | |
tracingOutputFileButton.setSelection(!Boolean.parseBoolean(PreferenceHandler.getOutputToStandardStream())); | |
// set the tracing file name. | |
tracingFileText.setText(PreferenceHandler.getFilePath()); | |
// default location needs to be put in preference store once ( fringe scenario) | |
final IEclipsePreferences preferences = PreferenceHandler.getPreferences(); | |
preferences.put(TracingConstants.PREFERENCE_FILE_PATH, PreferenceHandler.getFilePath()); | |
// set the max counter field | |
maximumFileCountSpinner.setSelection(PreferenceHandler.getMaxFileCount()); | |
// set the max file size field | |
maximumFileSizeSpinner.setSelection(PreferenceHandler.getMaxFileSize()); | |
// update the enablement state of all the UI elements | |
enableTracingButtonSelected(false); | |
standardOutputStreamButton.setSelection(Boolean.parseBoolean(PreferenceHandler.getOutputToStandardStream())); | |
} | |
/** | |
* Retrieve the input | |
*/ | |
protected String getInput(Event ev) { | |
String input = null; | |
if ((ev.keyCode == SWT.DEL) || (ev.keyCode == SWT.BS)) { | |
String currentValue = ((Text) ev.widget).getText(); | |
String begin = currentValue.substring(0, ev.start); | |
String end = currentValue.substring(ev.start + 1, currentValue.length()); | |
input = begin + end; | |
} else { | |
input = ev.text; | |
} | |
return input; | |
} | |
/** | |
* Verify that the user input is a valid int field | |
* | |
* @param errorMessage to display if the input is not a valid int field | |
*/ | |
protected void verifyIntInput(Event ev, String errorMessage) { | |
String input = getInput(ev); | |
// value the input | |
if (input.length() <= 0) { | |
setValid(false); | |
setErrorMessage(errorMessage); | |
return; | |
} | |
// ensure the characters in the string are numbers between 0 - 9 | |
char[] chars = new char[input.length()]; | |
input.getChars(0, chars.length, chars, 0); | |
for (int i = 0; i < chars.length; i++) { | |
if (!(('0' <= chars[i]) && (chars[i] <= '9'))) { | |
setValid(false); | |
setErrorMessage(errorMessage); | |
return; | |
} | |
} | |
// everything is OK! | |
setValid(true); | |
setErrorMessage(null); | |
} | |
/** | |
* This method is used to react to the enablement button ('Enable Tracing') state changing. | |
* | |
* @param updateModel | |
* Should the model be modified for this call? or should only the enablement state of the UI widgets be | |
* modified? | |
*/ | |
protected void enableTracingButtonSelected(boolean updateModel) { | |
boolean enableTracing = enableTracingButton.getSelection(); | |
if (updateModel) { | |
// populate the table | |
if (enableTracing) { | |
// rebuild the model | |
buildDisplayableComponents(); | |
// set the viewers input | |
Collection<TracingComponent> components = displayableTracingComponents.values(); | |
TracingComponent[] componentsArray = components.toArray(new TracingComponent[components.size()]); | |
getViewer().setInput(componentsArray); | |
} else { | |
// destroy the model | |
purgeModel(); | |
// set the viewers input to null | |
getViewer().setInput(null); | |
} | |
} | |
tracingTreeTitleLabel.setEnabled(enableTracing); | |
filterTree.setEnabled(enableTracing); | |
// only enable the tracing options if tracing is enabled | |
tracingOptionsGroup.setEnabled(enableTracing); | |
tracingFileText.setEnabled(enableTracing); | |
maximumFileSizeSpinner.setEnabled(enableTracing); | |
maximumFileCountSpinner.setEnabled(enableTracing); | |
tracingFileBrowseButton.setEnabled(enableTracing); | |
tracingOutputFileButton.setEnabled(enableTracing); | |
tracingFileMaxCountLabel.setEnabled(enableTracing); | |
tracingFileMaxSizeLabel.setEnabled(enableTracing); | |
standardOutputStreamButton.setEnabled(enableTracing); | |
} | |
/** | |
* This method will build the list of tracing components that will be used as input to the tree viewer. | |
*/ | |
private void buildDisplayableComponents() { | |
// ensure the model is destroyed (start from scratch) | |
if (displayableTracingComponents != null) { | |
purgeModel(); | |
} | |
displayableTracingComponents = new HashMap<String, TracingComponent>(); | |
// look for extension points | |
IExtensionRegistry registry = Platform.getExtensionRegistry(); | |
IConfigurationElement[] cf = registry.getConfigurationElementsFor(TracingConstants.BUNDLE_ID, TracingConstants.TRACING_EXTENSION_POINT_NAME); | |
TracingComponent[] components = new TracingComponent[cf.length]; | |
// populate the full list of tracing components | |
for (int i = 0; i < cf.length; i++) { | |
components[i] = TracingCollections.getInstance().getTracingComponent(cf[i]); | |
// if this component already exists or consumed then do not add it to the displayable list | |
if (!displayableTracingComponents.containsKey(components[i].getId()) && !components[i].isConsumed()) { | |
displayableTracingComponents.put(components[i].getId(), components[i]); | |
} | |
} | |
// now that the components are created - populate the debug options for each component | |
Iterator<TracingComponent> componentIterator = displayableTracingComponents.values().iterator(); | |
while (componentIterator.hasNext()) { | |
componentIterator.next().initialize(); | |
} | |
// update any TracingComponentDebugOption entries if their value differs from the preference value | |
mergePrefsWithDebugOptions(); | |
} | |
/** | |
* This method will merge the value of the options stored in the preferences with the value in the debug options. | |
*/ | |
private void mergePrefsWithDebugOptions() { | |
Map<String, String> prefDebugOptions = PreferenceHandler.getPreferenceProperties(); | |
// get all debug options (this ensures that the disabled debug options are used when populating) | |
Map<String, String> debugOptions = DebugOptionsHandler.getDebugOptions().getOptions(); | |
Iterator<Map.Entry<String, String>> prefDebugOptionsIterator = prefDebugOptions.entrySet().iterator(); | |
while (prefDebugOptionsIterator.hasNext()) { | |
Map.Entry<String, String> prefDebugOption = prefDebugOptionsIterator.next(); | |
String debugOptionsValue = debugOptions.get(prefDebugOption.getValue()); | |
boolean updateDebugOption = true; | |
if (debugOptionsValue != null) { | |
if (TracingUtils.isValueBoolean(debugOptionsValue) && TracingUtils.isValueBoolean(prefDebugOption.getValue())) { | |
// pick the one that is 'true' | |
boolean optionValue = Boolean.valueOf(debugOptionsValue).booleanValue(); | |
boolean prefValue = Boolean.valueOf(prefDebugOption.getValue()).booleanValue(); | |
if (prefValue != optionValue) { | |
// if the preference value is 'true' then use it... otherwise do nothing since the value | |
// in the debug options will be used. | |
updateDebugOption = prefValue; | |
} | |
} else { | |
// non-boolean values: pick the one in the preferences if they do not equal | |
if (!debugOptionsValue.equals(prefDebugOption.getValue())) { | |
updateDebugOption = true; | |
} | |
} | |
} | |
if (updateDebugOption) { | |
// find identical debug options and update them (this will include 'this' debug option that | |
// was modified) | |
TracingComponentDebugOption[] identicalOptions = TracingCollections.getInstance().getTracingDebugOptions(prefDebugOption.getKey()); | |
for (int identicalOptionsIndex = 0; identicalOptionsIndex < identicalOptions.length; identicalOptionsIndex++) { | |
identicalOptions[identicalOptionsIndex].setOptionPathValue(prefDebugOption.getValue()); | |
} | |
} | |
} | |
} | |
@Override | |
protected void performDefaults() { | |
super.performDefaults(); | |
// set the options to be an empty set | |
DebugOptionsHandler.getDebugOptions().setOptions(new HashMap<String, String>()); | |
// destroy the model so that it can be re-built. | |
purgeModel(); | |
// set the viewers input to null | |
getViewer().setInput(null); | |
// set the UI back to the default (tracing off, etc). | |
PreferenceHandler.setDefaultPreferences(); | |
TracingCollections.getInstance().getModifiedDebugOptions().clear(); | |
setUIValuesFromPreferences(); | |
} | |
@Override | |
public boolean performOk() { | |
boolean result = super.performOk(); | |
// get the enablement state | |
boolean enableTracing = enableTracingButton.getSelection(); | |
if (DebugOptionsHandler.isLaunchInDebugMode()) { | |
if (enableTracing) { | |
// User wants to override current settings | |
DebugOptionsHandler.setLaunchInDebugMode(false); | |
} else { | |
// Don't change tracing options | |
return result; | |
} | |
} | |
// save the preferences | |
savePreferences(enableTracing); | |
DebugOptionsHandler.setDebugEnabled(enableTracing); | |
DebugOptionsHandler.getDebugOptions().setFile(standardOutputStreamButton.getSelection() ? null : new File(tracingFileText.getText())); | |
if (enableTracing) { | |
Map<String, String> newOptions = new HashMap<String, String>(); | |
// get the set of options available | |
Map<String, String> currentOptions = DebugOptionsHandler.getDebugOptions().getOptions(); | |
newOptions.putAll(currentOptions); | |
// iterate over the list of added debug options and add them | |
TracingComponentDebugOption[] optionsToAdd = TracingCollections.getInstance().getModifiedDebugOptions().getDebugOptionsToAdd(); | |
for (int i = 0; i < optionsToAdd.length; i++) { | |
newOptions.put(optionsToAdd[i].getOptionPath(), optionsToAdd[i].getOptionPathValue()); | |
} | |
// iterate over the list of removed debug options and remove them | |
TracingComponentDebugOption[] optionsToRemove = TracingCollections.getInstance().getModifiedDebugOptions().getDebugOptionsToRemove(); | |
for (int i = 0; i < optionsToRemove.length; i++) { | |
newOptions.remove(optionsToRemove[i].getOptionPath()); | |
} | |
// update the debug options | |
DebugOptionsHandler.getDebugOptions().setOptions(newOptions); | |
TracingCollections.getInstance().getModifiedDebugOptions().clear(); | |
// save the tracing file options | |
if (DebugOptionsHandler.getDebugOptions().getFile() != null) { | |
String defaultFile = DebugOptionsHandler.getDebugOptions().getFile().getAbsolutePath(); | |
String newFile = tracingFileText.getText(); | |
if (!defaultFile.equals(newFile)) { | |
DebugOptionsHandler.getDebugOptions().setFile(new File(newFile)); | |
} | |
} | |
// maximum file size | |
int newMaxSize = maximumFileSizeSpinner.getSelection(); | |
// property defined in org.eclipse.osgi.framework.debug.EclipseDebugTrace#PROP_TRACE_SIZE_MAX | |
System.setProperty(TracingConstants.PROP_TRACE_SIZE_MAX, String.valueOf(newMaxSize)); | |
// maximum file count | |
int newMaxCount = maximumFileCountSpinner.getSelection(); | |
// property defined in org.eclipse.osgi.framework.debug.EclipseDebugTrace#PROP_TRACE_FILE_MAX | |
System.setProperty(TracingConstants.PROP_TRACE_FILE_MAX, String.valueOf(newMaxCount)); | |
} | |
return result; | |
} | |
/** | |
* Save the property page preferences. | |
*/ | |
protected void savePreferences(boolean tracingEnabled) { | |
Map<String, String> prefValues = new HashMap<String, String>(5); | |
prefValues.put(TracingConstants.PREFERENCE_ENABLEMENT_IDENTIFIER, Boolean.toString(tracingEnabled)); | |
prefValues.put(TracingConstants.PREFERENCE_MAX_FILE_COUNT_IDENTIFIER, Integer.toString(maximumFileCountSpinner.getSelection())); | |
prefValues.put(TracingConstants.PREFERENCE_MAX_FILE_SIZE_IDENTIFIER, Integer.toString(maximumFileSizeSpinner.getSelection())); | |
prefValues.put(TracingConstants.PREFERENCE_FILE_PATH, tracingFileText.getText()); | |
prefValues.put(TracingConstants.PREFERENCE_OUTPUT_STANDARD_STREAM, Boolean.toString(standardOutputStreamButton.getSelection())); | |
// iterate over the displayable components and store their debug options (all trace strings should be saved) | |
StringBuffer optionsAsString = new StringBuffer(); | |
if (displayableTracingComponents != null) { | |
Iterator<Map.Entry<String, TracingComponent>> componentIterator = displayableTracingComponents.entrySet().iterator(); | |
while (componentIterator.hasNext()) { | |
TracingComponent component = componentIterator.next().getValue(); | |
if (component.hasChildren()) { | |
StringBuffer result = getAllUniqueDebugOptions(component); | |
if (result != null) { | |
optionsAsString.append(result); | |
} | |
} | |
} | |
} else { | |
optionsAsString.append(TracingConstants.EMPTY_STRING); | |
} | |
prefValues.put(TracingConstants.PREFERENCE_ENTRIES_IDENTIFIER, optionsAsString.toString()); | |
PreferenceHandler.savePreferences(prefValues); | |
} | |
private StringBuffer getAllUniqueDebugOptions(TracingNode node) { | |
StringBuffer buffer = null; | |
if (node.hasChildren()) { | |
buffer = new StringBuffer(); | |
TracingNode[] children = node.getChildren(); | |
for (int i = 0; i < children.length; i++) { | |
// add this child node (all child nodes will be of type TracingComponentDebugOption) | |
String debugOptionAsString = TracingUtils.convertToString((TracingComponentDebugOption) children[i]); | |
buffer.append(debugOptionAsString); | |
// add all of this childs nodes | |
StringBuffer result = getAllUniqueDebugOptions(children[i]); | |
if (result != null) { | |
buffer.append(result); | |
} | |
} | |
} | |
return buffer; | |
} | |
/** | |
* The {@link TreeViewer} for the tracing page | |
* | |
* @return The {@link TreeViewer} for the tracing page | |
*/ | |
private TreeViewer getViewer() { | |
return filterTree.getViewer(); | |
} | |
/** | |
* Accessor for the {@link Tree} of the {@link CheckboxTreeViewer} | |
* | |
* @return The {@link Tree} of the {@link CheckboxTreeViewer} | |
*/ | |
private Tree getViewerTree() { | |
return filterTree.getViewer().getTree(); | |
} | |
} |