diff options
Diffstat (limited to 'basebuilder-3.6.2/org.eclipse.releng.basebuilder/plugins/org.eclipse.test.performance.ui/src/org/eclipse/test/internal/performance/results/ui/BuildsView.java')
-rw-r--r-- | basebuilder-3.6.2/org.eclipse.releng.basebuilder/plugins/org.eclipse.test.performance.ui/src/org/eclipse/test/internal/performance/results/ui/BuildsView.java | 659 |
1 files changed, 659 insertions, 0 deletions
diff --git a/basebuilder-3.6.2/org.eclipse.releng.basebuilder/plugins/org.eclipse.test.performance.ui/src/org/eclipse/test/internal/performance/results/ui/BuildsView.java b/basebuilder-3.6.2/org.eclipse.releng.basebuilder/plugins/org.eclipse.test.performance.ui/src/org/eclipse/test/internal/performance/results/ui/BuildsView.java new file mode 100644 index 0000000..3dabb41 --- /dev/null +++ b/basebuilder-3.6.2/org.eclipse.releng.basebuilder/plugins/org.eclipse.test.performance.ui/src/org/eclipse/test/internal/performance/results/ui/BuildsView.java @@ -0,0 +1,659 @@ +/******************************************************************************* + * Copyright (c) 2000, 2009 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 + *******************************************************************************/ +package org.eclipse.test.internal.performance.results.ui; + + +import java.io.File; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.lang.reflect.InvocationTargetException; +import java.util.Comparator; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.dialogs.ProgressMonitorDialog; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerSorter; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.test.internal.performance.results.db.DB_Results; +import org.eclipse.test.internal.performance.results.model.BuildResultsElement; +import org.eclipse.test.internal.performance.results.model.ResultsElement; +import org.eclipse.test.internal.performance.results.utils.IPerformancesConstants; +import org.eclipse.test.internal.performance.results.utils.Util; +import org.eclipse.test.performance.ui.GenerateResults; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.dialogs.ElementListSelectionDialog; +import org.eclipse.ui.model.WorkbenchContentProvider; +import org.eclipse.ui.model.WorkbenchLabelProvider; + + +/** + * View to see all the builds which have performance results stored in the database. + * <p> + * Typical actions from this view are update local data files with builds results + * and generated the HTML pages. + * </p> + */ +public class BuildsView extends PerformancesView { + + /** + * Action to generate results. + */ + final class GenerateAction extends Action { + IStatus status; + + public void run() { + + // Ask for output directory + String resultGenerationDir = BuildsView.this.preferences.get(IPerformancesConstants.PRE_RESULTS_GENERATION_DIR, ""); + String pathFilter = (BuildsView.this.outputDir == null) ? resultGenerationDir : BuildsView.this.outputDir.getPath(); + File dir = changeDir(pathFilter, "Select directory to write comparison files"); + if (dir == null) { + return; + } + BuildsView.this.outputDir = dir; + BuildsView.this.preferences.put(IPerformancesConstants.PRE_RESULTS_GENERATION_DIR, dir.getAbsolutePath()); + + // Select the reference + String[] baselines = BuildsView.this.results.getBaselines(); + int bLength = baselines.length; + String selectedBaseline; + switch (bLength) { + case 0: + // no baseline, nothing to do... + selectedBaseline = BuildsView.this.results.getPerformanceResults().getBaselineName(); + break; + case 1: + // only one baseline, no selection to do + selectedBaseline = baselines[0]; + break; + default: + // select the baseline from list + ElementListSelectionDialog dialog = new ElementListSelectionDialog(getSite().getShell(), new LabelProvider()); + dialog.setTitle(getTitleToolTip()); + dialog.setMessage("Select the baseline to use while generating results:"); + String[] defaultBaseline = new String[] { baselines[baselines.length - 1] }; + dialog.setInitialSelections(defaultBaseline); + dialog.setElements(baselines); + dialog.open(); + Object[] selected = dialog.getResult(); + if (selected == null) + return; + selectedBaseline = (String) selected[0]; + break; + } + final String baselineName = selectedBaseline; + BuildsView.this.results.getPerformanceResults().setBaselineName(baselineName); + + // Ask for fingerprints + final boolean fingerprints = MessageDialog.openQuestion(BuildsView.this.shell, getTitleToolTip(), "Generate only fingerprints?"); + + // Generate all selected builds + int length = BuildsView.this.buildsResults.length; + for (int i = 0; i < length; i++) { + generate(i, baselineName, fingerprints); + } + } + + /* + * Generate the HTML pages. + */ + private void generate(int i, final String baselineName, final boolean fingerprints) { + // Create output directory + final String buildName = BuildsView.this.buildsResults[i].getName(); + final File genDir = new File(BuildsView.this.outputDir, buildName); + if (!genDir.exists() && !genDir.mkdir()) { + MessageDialog.openError(BuildsView.this.shell, getTitleToolTip(), "Cannot create " + genDir.getPath() + " to generate results!"); + return; + } + + // Create runnable + IRunnableWithProgress runnable = new IRunnableWithProgress() { + + public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { + try { + monitor.beginTask("Generate performance results", 10000); + GenerateResults generation = new GenerateResults(BuildsView.this.results.getPerformanceResults(), + buildName, + baselineName, + fingerprints, + BuildsView.this.dataDir, + genDir); + GenerateAction.this.status = generation.run(monitor); + monitor.done(); + } catch (Exception e) { + e.printStackTrace(); + } + } + }; + + // Run with progress monitor + ProgressMonitorDialog readProgress = new ProgressMonitorDialog(getSite().getShell()); + try { + readProgress.run(true, true, runnable); + } catch (InvocationTargetException e) { + // skip + } catch (InterruptedException e) { + // skip + } + + // Results + if (!this.status.isOK()) { + StringWriter swriter = new StringWriter(); + PrintWriter pwriter = new PrintWriter(swriter); + swriter.write(this.status.getMessage()); + Throwable ex = this.status.getException(); + if (ex != null) { + swriter.write(": "); + swriter.write(ex.getMessage()); + swriter.write('\n'); + ex.printStackTrace(pwriter); + } + MessageDialog.open(this.status.getSeverity(), + BuildsView.this.shell, + getTitleToolTip(), + swriter.toString(), + SWT.NONE); + } + } + } + + /** + * Action to update local data files with the performance results of a build. + * + * This may be done lazily (i.e. not done if the local data already knows + * the build) or forced (i.e. done whatever the local data files contain). + */ + class UpdateBuildAction extends Action { + + boolean force; + + UpdateBuildAction(boolean force) { + super(); + this.force = force; + } + + public void run() { + + // Verify that directories are set + if (BuildsView.this.dataDir == null) { + if (changeDataDir() == null) { + if (!MessageDialog.openConfirm(BuildsView.this.shell, getTitleToolTip(), "No local files directory is set, hence the update could not be written! OK to continue?")) { + return; + } + } + } + + // Progress dialog + IRunnableWithProgress runnable = new IRunnableWithProgress() { + + public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { + try { + updateBuilds(monitor); + } catch (Exception e) { + e.printStackTrace(); + } + } + }; + ProgressMonitorDialog readProgress = new ProgressMonitorDialog(getSite().getShell()); + try { + readProgress.run(true, true, runnable); + } catch (InvocationTargetException e) { + return; + } catch (InterruptedException e) { + return; + } + + // Reset Components and Builds views input + refreshInput(); + getSiblingView().refreshInput(); + } + + void updateBuilds(IProgressMonitor monitor) { + BuildsView.this.updateBuilds(monitor, this.force); + } + } + + /** + * Action to update local data files with the performance results of all builds. + * + * This may be done lazily (i.e. not done if the local data already knows + * the build) or forced (i.e. done whatever the local data files contain). + */ + class UpdateAllBuildsAction extends UpdateBuildAction { + + UpdateAllBuildsAction(boolean force) { + super(force); + } +// +// public boolean isEnabled() { +// String[] elements = buildsToUpdate(); +// return elements != null; +// } + + void updateBuilds(IProgressMonitor monitor) { + BuildsView.this.updateAllBuilds(monitor, this.force); + } + } + + /** + * Class to compare builds regarding their date instead of their name. + * + * @see Util#getBuildDate(String) + */ + class BuildDateComparator implements Comparator { + public int compare(Object o1, Object o2) { + String s1 = (String) o1; + String s2 = (String) o2; + return Util.getBuildDate(s1).compareTo(Util.getBuildDate(s2)); + } + } + + // Views + PerformancesView componentsView; + + // Results model + BuildResultsElement[] buildsResults; + + // Generation info + File outputDir; + + // Actions + Action generate; + UpdateBuildAction updateBuild, updateAllBuilds; +// UpdateBuildAction forceUpdateBuild, forceUpdateAllBuilds; + + // SWT resources + Font italicFont; + +/* + * Default constructor. + */ +public BuildsView() { + this.preferences = new InstanceScope().getNode(IPerformancesConstants.PLUGIN_ID); + this.preferences.addPreferenceChangeListener(this); +} + +/* + * Compute the list of builds to update based on their status. + */ +String[] buildsToUpdate() { + Object[] elements = this.results.getBuilds(); + int length = elements.length; + String[] buildsToUpdate = new String[length]; + int count = 0; + for (int i=0; i<length; i++) { + BuildResultsElement element = (BuildResultsElement) elements[i]; + if (element.getStatus() == 0) { + buildsToUpdate[count++] = element.getName(); + } + } + if (count == 0) return null; + if (count < length) { + System.arraycopy(buildsToUpdate, 0, buildsToUpdate = new String[count], 0, count); + } + return buildsToUpdate; +} + +/* (non-Javadoc) + * @see org.eclipse.test.internal.performance.results.ui.PerformancesView#createPartControl(org.eclipse.swt.widgets.Composite) + */ +public void createPartControl(Composite parent) { + super.createPartControl(parent); + + // Create the viewer + this.viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); + + // Set the content provider: first level is builds list + WorkbenchContentProvider contentProvider = new WorkbenchContentProvider() { + public Object[] getElements(Object o) { + return getBuilds(); + } + }; + this.viewer.setContentProvider(contentProvider); + + // Set the label provider + WorkbenchLabelProvider labelProvider = new WorkbenchLabelProvider() { + + // Set an italic font when no local data have been read + public Font getFont(Object element) { + Font font = super.getFont(element); + if (element instanceof BuildResultsElement) { + if (((BuildResultsElement) element).isUnknown()) { + if (BuildsView.this.italicFont == null) { + FontData[] defaultFont = JFaceResources.getDefaultFont().getFontData(); + FontData italicFontData = new FontData(defaultFont[0].getName(), defaultFont[0].getHeight(), SWT.ITALIC); + BuildsView.this.italicFont = new Font(DEFAULT_DISPLAY, italicFontData); + } + return BuildsView.this.italicFont; + } + } + return font; + } + + // Set font in gray when no local data is available (i.e. local data needs to be updated) + public Color getForeground(Object element) { + Color color = super.getForeground(element); + if (element instanceof BuildResultsElement) { + if (!((BuildResultsElement) element).isRead()) { + color = DARK_GRAY; + } + } + return color; + } + }; + this.viewer.setLabelProvider(labelProvider); + + // Set the children sorter + ViewerSorter nameSorter = new ViewerSorter() { + + // Sort children using specific comparison (see the implementation + // of the #compareTo(Object) in the ResultsElement hierarchy + public int compare(Viewer view, Object e1, Object e2) { + if (e2 instanceof ResultsElement) { + return ((ResultsElement) e2).compareTo(e1); + } + return super.compare(view, e1, e2); + } + }; + this.viewer.setSorter(nameSorter); + + // Finalize viewer initialization + PlatformUI.getWorkbench().getHelpSystem().setHelp(this.viewer.getControl(), "org.eclipse.test.performance.ui.builds"); + finalizeViewerCreation(); +} + +/* (non-Javadoc) + * @see org.eclipse.ui.part.WorkbenchPart#dispose() + */ +public void dispose() { + if (this.italicFont != null) { + this.italicFont.dispose(); + } + super.dispose(); +} + +/* + * (non-Javadoc) + * @see org.eclipse.test.internal.performance.results.ui.PerformancesView#fillContextMenu(org.eclipse.jface.action.IMenuManager) + */ +void fillContextMenu(IMenuManager manager) { + super.fillContextMenu(manager); + manager.add(this.generate); + manager.add(this.updateBuild); +// manager.add(this.forceUpdateBuild); +} + +/* + * (non-Javadoc) + * @see org.eclipse.test.internal.performance.results.ui.PerformancesView#fillLocalPullDown(org.eclipse.jface.action.IMenuManager) + */ +void fillFiltersDropDown(IMenuManager manager) { + super.fillFiltersDropDown(manager); + manager.add(this.filterLastBuilds); +} + +/* + * Fill the local data drop-down menu + */ +void fillLocalDataDropDown(IMenuManager manager) { + super.fillLocalDataDropDown(manager); + manager.add(new Separator()); + manager.add(this.updateAllBuilds); +// manager.add(this.forceUpdateAllBuilds); +} + +/* + * Get all builds from the model. + */ +Object[] getBuilds() { + if (this.results == null) { + initResults(); + } + return this.results.getBuilds(); +} + +/* + * Return the components view. + */ +PerformancesView getSiblingView() { + if (this.componentsView == null) { + this.componentsView = (PerformancesView) getWorkbenchView("org.eclipse.test.internal.performance.results.ui.ComponentsView"); + } + return this.componentsView; +} + +/* + * (non-Javadoc) + * @see org.eclipse.test.internal.performance.results.ui.PerformancesView#makeActions() + */ +void makeActions() { + + super.makeActions(); + + // Generate action + this.generate = new GenerateAction(); + this.generate.setText("&Generate"); + + // Update build actions + boolean connected = this.preferences.getBoolean(IPerformancesConstants.PRE_DATABASE_CONNECTION, IPerformancesConstants.DEFAULT_DATABASE_CONNECTION); + this.updateBuild = new UpdateBuildAction(false); + this.updateBuild.setText("&Update from DB"); + this.updateBuild.setEnabled(connected); +// this.forceUpdateBuild = new UpdateBuildAction(true); +// this.forceUpdateBuild.setText("Force Update"); + + // Update build action + this.updateAllBuilds = new UpdateAllBuildsAction(false); + this.updateAllBuilds.setText("&Update from DB (all)"); + this.updateAllBuilds.setEnabled(connected); +// this.forceUpdateAllBuilds = new UpdateAllBuildsAction(true); +// this.forceUpdateAllBuilds.setText("Force Update all"); + + // Set filters default + this.filterBaselineBuilds.setChecked(false); + this.filterNightlyBuilds.setChecked(false); +} + +/** + * Reset the views. + */ +public void resetView() { + + boolean debug = true; + + // Look whether database constants has changed or not + int eclipseVersion = this.preferences.getInt(IPerformancesConstants.PRE_ECLIPSE_VERSION, IPerformancesConstants.DEFAULT_ECLIPSE_VERSION); + boolean connected = this.preferences.getBoolean(IPerformancesConstants.PRE_DATABASE_CONNECTION, IPerformancesConstants.DEFAULT_DATABASE_CONNECTION); + String databaseLocation = this.preferences.get(IPerformancesConstants.PRE_DATABASE_LOCATION, IPerformancesConstants.NETWORK_DATABASE_LOCATION); + String lastBuild = this.preferences.get(IPerformancesConstants.PRE_LAST_BUILD, null); + boolean noLastBuild = lastBuild.length() == 0; + if (debug) { + System.out.println("Reset View:"); + System.out.println(" - eclispe version = "+eclipseVersion); + System.out.println(" - connected = "+connected); + System.out.println(" - db location = "+databaseLocation); + System.out.println(" - last build = "+(noLastBuild?"<none>":lastBuild)); + } + final boolean sameVersion = DB_Results.getDbVersion().endsWith(Integer.toString(eclipseVersion)); + final boolean sameConnection = connected == DB_Results.DB_CONNECTION; + final boolean sameDB = sameVersion && databaseLocation.equals(DB_Results.getDbLocation()); + boolean sameLastBuild = (noLastBuild && LAST_BUILD == null) || lastBuild.equals(LAST_BUILD); + if (debug) { + System.out.println(" - same version: "+sameVersion); + System.out.println(" - same connection: "+sameConnection); + System.out.println(" - same DB: "+sameDB); + System.out.println(" - same last build: "+sameLastBuild); + } + final PerformancesView siblingView = getSiblingView(); + if (sameConnection && sameDB) { + if (!sameLastBuild) { + // Set last build + LAST_BUILD = noLastBuild ? null : lastBuild; + this.results.setLastBuildName(LAST_BUILD); + siblingView.results.setLastBuildName(LAST_BUILD); + + // Reset views content + resetInput(); + siblingView.resetInput(); + + // May be read local data now + File newDataDir = changeDataDir(); + if (newDataDir == null) { + this.dataDir = null; + siblingView.dataDir = null; + } + } + // No database preferences has changed do nothing + return; + } + + // Update database constants + boolean updated = DB_Results.updateDbConstants(connected, eclipseVersion, databaseLocation); + if (debug) { + System.out.println(" - updated: "+updated); + } + if (!connected) { + if (!updated) { + MessageDialog.openError(this.shell, getTitleToolTip(), "Error while updating database results constants!\nOpen error log to see more details on this error"); + } + } else if (updated) { + StringBuffer message = new StringBuffer("Database connection has been correctly "); + message.append( connected ? "opened." : "closed."); + MessageDialog.openInformation(this.shell, getTitleToolTip(), message.toString()); + } else { + MessageDialog.openError(this.shell, getTitleToolTip(), "The database connection cannot be established!\nOpen error log to see more details on this error"); + DB_Results.updateDbConstants(false, eclipseVersion, databaseLocation); + } + setTitleToolTip(); + siblingView.setTitleToolTip(); + + // Refresh view + if (sameVersion && sameLastBuild) { + // Refresh only builds view as the sibling view (Components) contents is based on local data files contents + this.results.resetBuildNames(); + refreshInput(); + } else { + // Reset views content + resetInput(); + siblingView.resetInput(); + + // May be read local data now + if (MessageDialog.openQuestion(this.shell, getTitleToolTip(), "Do you want to read local data right now?")) { + changeDataDir(); + } else { + this.dataDir = null; + siblingView.dataDir = null; + } + } + + // Update actions + this.updateBuild.setEnabled(connected); + this.updateAllBuilds.setEnabled(connected); +} + +/* + * (non-Javadoc) + * @see org.eclipse.test.internal.performance.results.ui.PerformancesView#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent) + */ +public void selectionChanged(SelectionChangedEvent event) { + super.selectionChanged(event); + + // Update selected element + Object selection = this.viewer.getSelection(); + int length = 0; + if (selection instanceof IStructuredSelection) { + Object[] elements = ((IStructuredSelection)selection).toArray(); + length = elements == null ? 0 : elements.length; + this.buildsResults = new BuildResultsElement[length]; + if (length == 0) { + this.updateAllBuilds.setText("&Update from DB (all)"); + return; + } + for (int i=0; i<length; i++) { + this.buildsResults[i] = (BuildResultsElement) elements[i]; + } + } else { + return; + } + + // Update update build action +// boolean enableUpdateBuild = true; +// boolean enableGenerate = true; + int readBuilds = 0; + for (int i=0; i<length; i++) { + if (this.buildsResults[i].isRead()) { +// enableUpdateBuild = false; + readBuilds++; + } else { +// enableGenerate = false; + } + } +// this.updateBuild.setEnabled(enableUpdateBuild); +// this.forceUpdateBuild.setEnabled(!enableUpdateBuild); + final boolean force = readBuilds < length; + this.updateBuild.force = force; + this.updateAllBuilds.force = force; + this.updateAllBuilds.setText("&Update from DB"); + + // Update generate action + boolean enableGenerate = true; + if (enableGenerate) { + for (int i=0; i<length; i++) { + if (this.buildsResults[i].getName().startsWith(DB_Results.getDbBaselinePrefix())) { + enableGenerate = false; + break; + } + } + } + this.generate.setEnabled(enableGenerate); +} + +void updateAllBuilds(IProgressMonitor monitor, boolean force) { + if (this.dataDir == null) { + changeDataDir(); + } + String[] builds = buildsToUpdate(); + if (builds == null) { + this.results.updateBuild(null, true, this.dataDir, monitor); + } else { + this.results.updateBuilds(builds, force, this.dataDir, monitor); + } +} + +void updateBuilds(IProgressMonitor monitor, boolean force) { + if (this.dataDir == null) { + changeDataDir(); + } + int length = this.buildsResults.length; + String[] builds = new String[length]; + for (int i = 0; i < length; i++) { + builds[i] = this.buildsResults[i].getName(); + } + this.results.updateBuilds(builds, force, this.dataDir, monitor); +} + +}
\ No newline at end of file |