• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*******************************************************************************
2  * Copyright (c) 2000, 2009 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package org.eclipse.test.internal.performance.results.ui;
12 
13 
14 import java.io.File;
15 import java.io.PrintWriter;
16 import java.io.StringWriter;
17 import java.lang.reflect.InvocationTargetException;
18 import java.util.Comparator;
19 
20 import org.eclipse.core.runtime.IProgressMonitor;
21 import org.eclipse.core.runtime.IStatus;
22 import org.eclipse.core.runtime.preferences.InstanceScope;
23 import org.eclipse.jface.action.Action;
24 import org.eclipse.jface.action.IMenuManager;
25 import org.eclipse.jface.action.Separator;
26 import org.eclipse.jface.dialogs.MessageDialog;
27 import org.eclipse.jface.dialogs.ProgressMonitorDialog;
28 import org.eclipse.jface.operation.IRunnableWithProgress;
29 import org.eclipse.jface.resource.JFaceResources;
30 import org.eclipse.jface.viewers.IStructuredSelection;
31 import org.eclipse.jface.viewers.LabelProvider;
32 import org.eclipse.jface.viewers.SelectionChangedEvent;
33 import org.eclipse.jface.viewers.TreeViewer;
34 import org.eclipse.jface.viewers.Viewer;
35 import org.eclipse.jface.viewers.ViewerSorter;
36 import org.eclipse.swt.SWT;
37 import org.eclipse.swt.graphics.Color;
38 import org.eclipse.swt.graphics.Font;
39 import org.eclipse.swt.graphics.FontData;
40 import org.eclipse.swt.widgets.Composite;
41 import org.eclipse.test.internal.performance.results.db.DB_Results;
42 import org.eclipse.test.internal.performance.results.model.BuildResultsElement;
43 import org.eclipse.test.internal.performance.results.model.ResultsElement;
44 import org.eclipse.test.internal.performance.results.utils.IPerformancesConstants;
45 import org.eclipse.test.internal.performance.results.utils.Util;
46 import org.eclipse.test.performance.ui.GenerateResults;
47 import org.eclipse.ui.PlatformUI;
48 import org.eclipse.ui.dialogs.ElementListSelectionDialog;
49 import org.eclipse.ui.model.WorkbenchContentProvider;
50 import org.eclipse.ui.model.WorkbenchLabelProvider;
51 
52 
53 /**
54  * View to see all the builds which have performance results stored in the database.
55  * <p>
56  * Typical actions from this view are update local data files with builds results
57  * and generated the HTML pages.
58  * </p>
59  */
60 public class BuildsView extends PerformancesView {
61 
62 	/**
63 	 * Action to generate results.
64 	 */
65 	final class GenerateAction extends Action {
66 		IStatus status;
67 
run()68 		public void run() {
69 
70 			// Ask for output directory
71 			String resultGenerationDir = BuildsView.this.preferences.get(IPerformancesConstants.PRE_RESULTS_GENERATION_DIR, "");
72 			String pathFilter = (BuildsView.this.outputDir == null) ? resultGenerationDir : BuildsView.this.outputDir.getPath();
73 			File dir = changeDir(pathFilter, "Select directory to write comparison files");
74 			if (dir == null) {
75 				return;
76 			}
77 			BuildsView.this.outputDir = dir;
78 			BuildsView.this.preferences.put(IPerformancesConstants.PRE_RESULTS_GENERATION_DIR, dir.getAbsolutePath());
79 
80 			// Select the reference
81 			String[] baselines = BuildsView.this.results.getBaselines();
82 			int bLength = baselines.length;
83 			String selectedBaseline;
84 			switch (bLength) {
85 				case 0:
86 					// no baseline, nothing to do...
87 					selectedBaseline = BuildsView.this.results.getPerformanceResults().getBaselineName();
88 					break;
89 				case 1:
90 					// only one baseline, no selection to do
91 					selectedBaseline = baselines[0];
92 					break;
93 				default:
94 					// select the baseline from list
95 					ElementListSelectionDialog dialog = new ElementListSelectionDialog(getSite().getShell(), new LabelProvider());
96 					dialog.setTitle(getTitleToolTip());
97 					dialog.setMessage("Select the baseline to use while generating results:");
98 					String[] defaultBaseline = new String[] { baselines[baselines.length - 1] };
99 					dialog.setInitialSelections(defaultBaseline);
100 					dialog.setElements(baselines);
101 					dialog.open();
102 					Object[] selected = dialog.getResult();
103 					if (selected == null)
104 						return;
105 					selectedBaseline = (String) selected[0];
106 					break;
107 			}
108 			final String baselineName = selectedBaseline;
109 			BuildsView.this.results.getPerformanceResults().setBaselineName(baselineName);
110 
111 			// Ask for fingerprints
112 			final boolean fingerprints = MessageDialog.openQuestion(BuildsView.this.shell, getTitleToolTip(), "Generate only fingerprints?");
113 
114 			// Generate all selected builds
115 			int length = BuildsView.this.buildsResults.length;
116 			for (int i = 0; i < length; i++) {
117 				generate(i, baselineName, fingerprints);
118 			}
119 		}
120 
121 		/*
122 		 * Generate the HTML pages.
123 		 */
generate(int i, final String baselineName, final boolean fingerprints)124 		private void generate(int i, final String baselineName, final boolean fingerprints) {
125 			// Create output directory
126 			final String buildName = BuildsView.this.buildsResults[i].getName();
127 			final File genDir = new File(BuildsView.this.outputDir, buildName);
128 			if (!genDir.exists() && !genDir.mkdir()) {
129 				MessageDialog.openError(BuildsView.this.shell, getTitleToolTip(), "Cannot create " + genDir.getPath() + " to generate results!");
130 				return;
131 			}
132 
133 			// Create runnable
134 			IRunnableWithProgress runnable = new IRunnableWithProgress() {
135 
136 				public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
137 					try {
138 						monitor.beginTask("Generate performance results", 10000);
139 						GenerateResults generation = new GenerateResults(BuildsView.this.results.getPerformanceResults(),
140 						    buildName,
141 						    baselineName,
142 						    fingerprints,
143 						    BuildsView.this.dataDir,
144 						    genDir);
145 						GenerateAction.this.status = generation.run(monitor);
146 						monitor.done();
147 					} catch (Exception e) {
148 						e.printStackTrace();
149 					}
150 				}
151 			};
152 
153 			// Run with progress monitor
154 			ProgressMonitorDialog readProgress = new ProgressMonitorDialog(getSite().getShell());
155 			try {
156 				readProgress.run(true, true, runnable);
157 			} catch (InvocationTargetException e) {
158 				// skip
159 			} catch (InterruptedException e) {
160 				// skip
161 			}
162 
163 			// Results
164 			if (!this.status.isOK()) {
165 				StringWriter swriter = new StringWriter();
166 				PrintWriter pwriter = new PrintWriter(swriter);
167 				swriter.write(this.status.getMessage());
168 				Throwable ex = this.status.getException();
169 				if (ex != null) {
170 					swriter.write(": ");
171 					swriter.write(ex.getMessage());
172 					swriter.write('\n');
173 					ex.printStackTrace(pwriter);
174 				}
175 				MessageDialog.open(this.status.getSeverity(),
176 				    BuildsView.this.shell,
177 				    getTitleToolTip(),
178 				    swriter.toString(),
179 				    SWT.NONE);
180 			}
181 		}
182 	}
183 
184 	/**
185 	 * Action to update local data files with the performance results of a build.
186 	 *
187 	 * This may be done lazily (i.e. not done if the local data already knows
188 	 * the build) or forced (i.e. done whatever the local data files contain).
189 	 */
190 	class UpdateBuildAction extends Action {
191 
192 		boolean force;
193 
UpdateBuildAction(boolean force)194 		UpdateBuildAction(boolean force) {
195 			super();
196 			this.force = force;
197 		}
198 
run()199 		public void run() {
200 
201 			// Verify that directories are set
202 			if (BuildsView.this.dataDir == null) {
203 				if (changeDataDir() == null) {
204 					if (!MessageDialog.openConfirm(BuildsView.this.shell, getTitleToolTip(), "No local files directory is set, hence the update could not be written! OK to continue?")) {
205 						return;
206 					}
207 				}
208 			}
209 
210 			// Progress dialog
211 			IRunnableWithProgress runnable = new IRunnableWithProgress() {
212 
213 				public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
214 					try {
215 						updateBuilds(monitor);
216 					} catch (Exception e) {
217 						e.printStackTrace();
218 					}
219 				}
220 			};
221 			ProgressMonitorDialog readProgress = new ProgressMonitorDialog(getSite().getShell());
222 			try {
223 				readProgress.run(true, true, runnable);
224 			} catch (InvocationTargetException e) {
225 				return;
226 			} catch (InterruptedException e) {
227 				return;
228 			}
229 
230 			// Reset Components and Builds views input
231 			refreshInput();
232 			getSiblingView().refreshInput();
233 		}
234 
updateBuilds(IProgressMonitor monitor)235 		void updateBuilds(IProgressMonitor monitor) {
236 			BuildsView.this.updateBuilds(monitor, this.force);
237 		}
238 	}
239 
240 	/**
241 	 * Action to update local data files with the performance results of all builds.
242 	 *
243 	 * This may be done lazily (i.e. not done if the local data already knows
244 	 * the build) or forced (i.e. done whatever the local data files contain).
245 	 */
246 	class UpdateAllBuildsAction extends UpdateBuildAction {
247 
UpdateAllBuildsAction(boolean force)248 		UpdateAllBuildsAction(boolean force) {
249 			super(force);
250 		}
251 //
252 //		public boolean isEnabled() {
253 //			String[] elements = buildsToUpdate();
254 //			return elements != null;
255 //		}
256 
updateBuilds(IProgressMonitor monitor)257 		void updateBuilds(IProgressMonitor monitor) {
258 			BuildsView.this.updateAllBuilds(monitor, this.force);
259 		}
260 	}
261 
262 	/**
263 	 * Class to compare builds regarding their date instead of their name.
264 	 *
265 	 * @see Util#getBuildDate(String)
266 	 */
267 	class BuildDateComparator implements Comparator {
compare(Object o1, Object o2)268 		public int compare(Object o1, Object o2) {
269 	        String s1 = (String) o1;
270 	        String s2 = (String) o2;
271 	        return Util.getBuildDate(s1).compareTo(Util.getBuildDate(s2));
272 	    }
273 	}
274 
275 	// Views
276 	PerformancesView componentsView;
277 
278 	// Results model
279 	BuildResultsElement[] buildsResults;
280 
281 	// Generation info
282 	File outputDir;
283 
284 	// Actions
285 	Action generate;
286 	UpdateBuildAction updateBuild, updateAllBuilds;
287 //	UpdateBuildAction forceUpdateBuild, forceUpdateAllBuilds;
288 
289 	// SWT resources
290 	Font italicFont;
291 
292 /*
293  * Default constructor.
294  */
BuildsView()295 public BuildsView() {
296 	this.preferences = new InstanceScope().getNode(IPerformancesConstants.PLUGIN_ID);
297 	this.preferences.addPreferenceChangeListener(this);
298 }
299 
300 /*
301  * Compute the list of builds to update based on their status.
302  */
buildsToUpdate()303 String[] buildsToUpdate() {
304 	Object[] elements = this.results.getBuilds();
305 	int length = elements.length;
306 	String[] buildsToUpdate = new String[length];
307 	int count = 0;
308 	for (int i=0; i<length; i++) {
309 		BuildResultsElement element = (BuildResultsElement) elements[i];
310 		if (element.getStatus() == 0) {
311 	        buildsToUpdate[count++] = element.getName();
312 		}
313 	}
314 	if (count == 0) return null;
315 	if (count < length) {
316 		System.arraycopy(buildsToUpdate, 0, buildsToUpdate = new String[count], 0, count);
317 	}
318 	return buildsToUpdate;
319 }
320 
321 /* (non-Javadoc)
322  * @see org.eclipse.test.internal.performance.results.ui.PerformancesView#createPartControl(org.eclipse.swt.widgets.Composite)
323  */
createPartControl(Composite parent)324 public void createPartControl(Composite parent) {
325 	super.createPartControl(parent);
326 
327 	// Create the viewer
328 	this.viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
329 
330 	// Set the content provider: first level is builds list
331 	WorkbenchContentProvider contentProvider = new WorkbenchContentProvider() {
332 		public Object[] getElements(Object o) {
333 			return getBuilds();
334 		}
335 	};
336 	this.viewer.setContentProvider(contentProvider);
337 
338 	// Set the label provider
339 	WorkbenchLabelProvider labelProvider = new WorkbenchLabelProvider() {
340 
341 		// Set an italic font when no local data have been read
342 		public Font getFont(Object element) {
343 			Font font = super.getFont(element);
344 			if (element instanceof BuildResultsElement) {
345 				if (((BuildResultsElement) element).isUnknown()) {
346 					if (BuildsView.this.italicFont == null) {
347 						FontData[] defaultFont = JFaceResources.getDefaultFont().getFontData();
348 						FontData italicFontData = new FontData(defaultFont[0].getName(), defaultFont[0].getHeight(), SWT.ITALIC);
349 						BuildsView.this.italicFont = new Font(DEFAULT_DISPLAY, italicFontData);
350 					}
351 					return BuildsView.this.italicFont;
352 				}
353 			}
354 			return font;
355 		}
356 
357 		// Set font in gray when no local data is available (i.e. local data needs to be updated)
358 		public Color getForeground(Object element) {
359 			Color color = super.getForeground(element);
360 			if (element instanceof BuildResultsElement) {
361 				if (!((BuildResultsElement) element).isRead()) {
362 					color = DARK_GRAY;
363 				}
364 			}
365 			return color;
366 		}
367 	};
368 	this.viewer.setLabelProvider(labelProvider);
369 
370 	// Set the children sorter
371 	ViewerSorter nameSorter = new ViewerSorter() {
372 
373 		// Sort children using specific comparison (see the implementation
374 		// of the #compareTo(Object) in the ResultsElement hierarchy
375 		public int compare(Viewer view, Object e1, Object e2) {
376 			if (e2 instanceof ResultsElement) {
377 				return ((ResultsElement) e2).compareTo(e1);
378 			}
379 			return super.compare(view, e1, e2);
380 		}
381 	};
382 	this.viewer.setSorter(nameSorter);
383 
384 	// Finalize viewer initialization
385 	PlatformUI.getWorkbench().getHelpSystem().setHelp(this.viewer.getControl(), "org.eclipse.test.performance.ui.builds");
386 	finalizeViewerCreation();
387 }
388 
389 /* (non-Javadoc)
390  * @see org.eclipse.ui.part.WorkbenchPart#dispose()
391  */
dispose()392 public void dispose() {
393 	if (this.italicFont != null) {
394 		this.italicFont.dispose();
395 	}
396 	super.dispose();
397 }
398 
399 /*
400  * (non-Javadoc)
401  * @see org.eclipse.test.internal.performance.results.ui.PerformancesView#fillContextMenu(org.eclipse.jface.action.IMenuManager)
402  */
fillContextMenu(IMenuManager manager)403 void fillContextMenu(IMenuManager manager) {
404 	super.fillContextMenu(manager);
405 	manager.add(this.generate);
406 	manager.add(this.updateBuild);
407 //	manager.add(this.forceUpdateBuild);
408 }
409 
410 /*
411  * (non-Javadoc)
412  * @see org.eclipse.test.internal.performance.results.ui.PerformancesView#fillLocalPullDown(org.eclipse.jface.action.IMenuManager)
413  */
fillFiltersDropDown(IMenuManager manager)414 void fillFiltersDropDown(IMenuManager manager) {
415 	super.fillFiltersDropDown(manager);
416 	manager.add(this.filterLastBuilds);
417 }
418 
419 /*
420  * Fill the local data drop-down menu
421  */
fillLocalDataDropDown(IMenuManager manager)422 void fillLocalDataDropDown(IMenuManager manager) {
423 	super.fillLocalDataDropDown(manager);
424 	manager.add(new Separator());
425 	manager.add(this.updateAllBuilds);
426 //	manager.add(this.forceUpdateAllBuilds);
427 }
428 
429 /*
430  * Get all builds from the model.
431  */
getBuilds()432 Object[] getBuilds() {
433 	if (this.results == null) {
434 		initResults();
435 	}
436 	return this.results.getBuilds();
437 }
438 
439 /*
440  * Return the components view.
441  */
getSiblingView()442 PerformancesView getSiblingView() {
443 	if (this.componentsView == null) {
444 		this.componentsView = (PerformancesView) getWorkbenchView("org.eclipse.test.internal.performance.results.ui.ComponentsView");
445 	}
446 	return this.componentsView;
447 }
448 
449 /*
450  * (non-Javadoc)
451  * @see org.eclipse.test.internal.performance.results.ui.PerformancesView#makeActions()
452  */
makeActions()453 void makeActions() {
454 
455 	super.makeActions();
456 
457 	// Generate action
458 	this.generate = new GenerateAction();
459 	this.generate.setText("&Generate");
460 
461 	// Update build actions
462 	boolean connected = this.preferences.getBoolean(IPerformancesConstants.PRE_DATABASE_CONNECTION, IPerformancesConstants.DEFAULT_DATABASE_CONNECTION);
463 	this.updateBuild = new UpdateBuildAction(false);
464 	this.updateBuild.setText("&Update from DB");
465 	this.updateBuild.setEnabled(connected);
466 //	this.forceUpdateBuild = new UpdateBuildAction(true);
467 //	this.forceUpdateBuild.setText("Force Update");
468 
469 	// Update build action
470 	this.updateAllBuilds = new UpdateAllBuildsAction(false);
471 	this.updateAllBuilds.setText("&Update from DB (all)");
472 	this.updateAllBuilds.setEnabled(connected);
473 //	this.forceUpdateAllBuilds = new UpdateAllBuildsAction(true);
474 //	this.forceUpdateAllBuilds.setText("Force Update all");
475 
476 	// Set filters default
477 	this.filterBaselineBuilds.setChecked(false);
478 	this.filterNightlyBuilds.setChecked(false);
479 }
480 
481 /**
482  * Reset the views.
483  */
resetView()484 public void resetView() {
485 
486 	boolean debug = true;
487 
488 	// Look whether database constants has changed or not
489 	int eclipseVersion = this.preferences.getInt(IPerformancesConstants.PRE_ECLIPSE_VERSION, IPerformancesConstants.DEFAULT_ECLIPSE_VERSION);
490 	boolean connected = this.preferences.getBoolean(IPerformancesConstants.PRE_DATABASE_CONNECTION, IPerformancesConstants.DEFAULT_DATABASE_CONNECTION);
491 	String databaseLocation = this.preferences.get(IPerformancesConstants.PRE_DATABASE_LOCATION, IPerformancesConstants.NETWORK_DATABASE_LOCATION);
492 	String lastBuild = this.preferences.get(IPerformancesConstants.PRE_LAST_BUILD, null);
493 	boolean noLastBuild = lastBuild.length() == 0;
494 	if (debug) {
495 		System.out.println("Reset View:");
496 		System.out.println("	- eclispe version = "+eclipseVersion);
497 		System.out.println("	- connected       = "+connected);
498 		System.out.println("	- db location     = "+databaseLocation);
499 		System.out.println("	- last build      = "+(noLastBuild?"<none>":lastBuild));
500 	}
501 	final boolean sameVersion = DB_Results.getDbVersion().endsWith(Integer.toString(eclipseVersion));
502 	final boolean sameConnection = connected == DB_Results.DB_CONNECTION;
503 	final boolean sameDB = sameVersion && databaseLocation.equals(DB_Results.getDbLocation());
504 	boolean sameLastBuild = (noLastBuild && LAST_BUILD == null) || lastBuild.equals(LAST_BUILD);
505 	if (debug) {
506 		System.out.println("	- same version:    "+sameVersion);
507 		System.out.println("	- same connection: "+sameConnection);
508 		System.out.println("	- same DB:         "+sameDB);
509 		System.out.println("	- same last build: "+sameLastBuild);
510 	}
511 	final PerformancesView siblingView = getSiblingView();
512 	if (sameConnection && sameDB) {
513 		if (!sameLastBuild) {
514 			// Set last build
515 			LAST_BUILD = noLastBuild ? null : lastBuild;
516 			this.results.setLastBuildName(LAST_BUILD);
517 			siblingView.results.setLastBuildName(LAST_BUILD);
518 
519 			// Reset views content
520 			resetInput();
521 			siblingView.resetInput();
522 
523 			// May be read local data now
524 			File newDataDir = changeDataDir();
525 			if (newDataDir == null) {
526 				this.dataDir = null;
527 				siblingView.dataDir = null;
528 			}
529 		}
530 		// No database preferences has changed do nothing
531 		return;
532 	}
533 
534 	// Update database constants
535 	boolean updated = DB_Results.updateDbConstants(connected, eclipseVersion, databaseLocation);
536 	if (debug) {
537 		System.out.println("	- updated:         "+updated);
538 	}
539 	if (!connected) {
540 		if (!updated) {
541 			MessageDialog.openError(this.shell, getTitleToolTip(), "Error while updating database results constants!\nOpen error log to see more details on this error");
542 		}
543 	} else if (updated) {
544 		StringBuffer message = new StringBuffer("Database connection has been correctly ");
545 		message.append( connected ? "opened." : "closed.");
546 		MessageDialog.openInformation(this.shell, getTitleToolTip(), message.toString());
547 	} else {
548 		MessageDialog.openError(this.shell, getTitleToolTip(), "The database connection cannot be established!\nOpen error log to see more details on this error");
549 		DB_Results.updateDbConstants(false, eclipseVersion, databaseLocation);
550 	}
551 	setTitleToolTip();
552 	siblingView.setTitleToolTip();
553 
554 	// Refresh view
555 	if (sameVersion && sameLastBuild) {
556 		// Refresh only builds view as the sibling view (Components) contents is based on local data files contents
557 		this.results.resetBuildNames();
558 		refreshInput();
559 	} else {
560 		// Reset views content
561 		resetInput();
562 		siblingView.resetInput();
563 
564 		// May be read local data now
565 		if (MessageDialog.openQuestion(this.shell, getTitleToolTip(), "Do you want to read local data right now?")) {
566 			changeDataDir();
567 		} else {
568 			this.dataDir = null;
569 			siblingView.dataDir = null;
570 		}
571 	}
572 
573 	// Update actions
574 	this.updateBuild.setEnabled(connected);
575 	this.updateAllBuilds.setEnabled(connected);
576 }
577 
578 /*
579  * (non-Javadoc)
580  * @see org.eclipse.test.internal.performance.results.ui.PerformancesView#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
581  */
selectionChanged(SelectionChangedEvent event)582 public void selectionChanged(SelectionChangedEvent event) {
583 	super.selectionChanged(event);
584 
585 	// Update selected element
586 	Object selection = this.viewer.getSelection();
587 	int length = 0;
588 	if (selection instanceof IStructuredSelection) {
589 		Object[] elements = ((IStructuredSelection)selection).toArray();
590 		length = elements == null ? 0 : elements.length;
591 		this.buildsResults = new BuildResultsElement[length];
592 		if (length == 0) {
593 			this.updateAllBuilds.setText("&Update from DB (all)");
594 			return;
595 		}
596 		for (int i=0; i<length; i++) {
597 			this.buildsResults[i] = (BuildResultsElement) elements[i];
598 		}
599 	} else {
600 		return;
601 	}
602 
603 	// Update update build action
604 //	boolean enableUpdateBuild = true;
605 //	boolean enableGenerate = true;
606 	int readBuilds = 0;
607 	for (int i=0; i<length; i++) {
608 		if (this.buildsResults[i].isRead()) {
609 //			enableUpdateBuild = false;
610 			readBuilds++;
611 		} else {
612 //			enableGenerate = false;
613 		}
614 	}
615 //	this.updateBuild.setEnabled(enableUpdateBuild);
616 //	this.forceUpdateBuild.setEnabled(!enableUpdateBuild);
617 	final boolean force = readBuilds < length;
618 	this.updateBuild.force = force;
619 	this.updateAllBuilds.force = force;
620 	this.updateAllBuilds.setText("&Update from DB");
621 
622 	// Update generate action
623 	boolean enableGenerate = true;
624 	if (enableGenerate) {
625 		for (int i=0; i<length; i++) {
626 			if (this.buildsResults[i].getName().startsWith(DB_Results.getDbBaselinePrefix())) {
627 				enableGenerate = false;
628 				break;
629 			}
630 		}
631 	}
632 	this.generate.setEnabled(enableGenerate);
633 }
634 
635 void updateAllBuilds(IProgressMonitor monitor, boolean force) {
636 	if (this.dataDir == null) {
637 		changeDataDir();
638 	}
639 	String[] builds = buildsToUpdate();
640 	if (builds == null) {
641 		this.results.updateBuild(null, true, this.dataDir, monitor);
642 	} else {
643 		this.results.updateBuilds(builds, force, this.dataDir, monitor);
644 	}
645 }
646 
647 void updateBuilds(IProgressMonitor monitor, boolean force) {
648 	if (this.dataDir == null) {
649 		changeDataDir();
650 	}
651 	int length = this.buildsResults.length;
652 	String[] builds = new String[length];
653 	for (int i = 0; i < length; i++) {
654 		builds[i] = this.buildsResults[i].getName();
655 	}
656 	this.results.updateBuilds(builds, force, this.dataDir, monitor);
657 }
658 
659 }