/*******************************************************************************
* Copyright (c) 2006 RadRails.org and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.radrails.rails.internal.ui.autotest;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.ToolBarContributionItem;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.swt.graphics.Point;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWindowActionDelegate;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.OverlayIcon;
import org.radrails.rails.core.RailsLog;
import org.radrails.rails.internal.core.RailsPlugin;
import org.radrails.rails.internal.ui.RailsUIMessages;
import org.radrails.rails.ui.RailsUILog;
import org.radrails.rails.ui.RailsUIPlugin;
/**
* Toolbar action to run the selected autotest suite.
*
* @author mkent
*
*/
public class RunAutotestSuiteActionDelegate implements
IWorkbenchWindowActionDelegate, IAutotestRunListener {
private static final String AUTOTEST_TEMPORARY_FILE = "autotest_listing.rb";
private IWorkbenchWindow fWindow;
private IAction fAction;
private BlinkThread fBlinkThread;
public void dispose() {
fWindow = null;
RailsUIPlugin.getInstance().getAutotestManager()
.removeRunListener(this);
}
public void init(IWorkbenchWindow window) {
fWindow = window;
RailsUIPlugin.getInstance().getAutotestManager().addRunListener(this);
}
public void run(IAction action) {
// Create a new job
Job j = new Job("Autotest") {
protected IStatus run(IProgressMonitor monitor) {
monitor.beginTask("Running autotest suite", 3);
monitor.worked(1);
IFile activeEditorFile = AutotestHelper.getActiveEditorFile();
if (activeEditorFile != null) {
if(fBlinkThread != null) {
fBlinkThread.stopBlinking();
}
AutotestManager manager = new AutotestManager();
manager.attemptTestLaunch(activeEditorFile);
} else{
openErrorDialog(RailsUIMessages.OpenRubyEditor_message);
}
monitor.worked(1);
monitor.done();
return Status.OK_STATUS;
}
};
j.setUser(true);
j.schedule();
}
private void openErrorDialog(final String message) {
PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {
public void run() {
MessageDialog.openError(fWindow.getShell(),
"Error running tests", message);
}
});
}
public void selectionChanged(IAction action, ISelection selection) {
}
public void suiteError() {
getAction().setToolTipText("(Error) Manually Run Autotest Suite");
notifySuite("at_error.gif");
}
public void suiteFail() {
getAction().setToolTipText("(Failed) Manually Run Autotest Suite");
notifySuite("at_fail.gif");
}
public void suitePass() {
getAction().setToolTipText("(Passed) Manually Run Autotest Suite");
notifySuite("at_pass.gif");
}
private void notifySuite(String iconName) {
ImageDescriptor icon = RailsUIPlugin.getImageDescriptor("icons/" + iconName);
fBlinkThread = new BlinkThread(icon);
fBlinkThread.start();
}
private class BlinkThread extends Thread {
private boolean keepBlinking;
private ImageDescriptor fIcon;
private ImageDescriptor fBlinkIcon;
public BlinkThread(ImageDescriptor icon) {
keepBlinking = true;
fIcon = icon;
ImageDescriptor blink = RailsUIPlugin.getImageDescriptor("icons/blink_ovr.gif");
fBlinkIcon = new OverlayIcon(icon, blink, new Point(16, 16));
}
public void run() {
// blink 5 times and return to normal
for(int i = 0; (i < 11) && keepBlinking; i++) {
if(i % 2 == 0) {
getAction().setImageDescriptor(fIcon);
}
else {
getAction().setImageDescriptor(fBlinkIcon);
}
try {
sleep(500);
} catch (InterruptedException e) {
RailsUILog.logError("Error sleeping during icon blink", e);
}
}
}
public void stopBlinking() {
keepBlinking = false;
getAction().setImageDescriptor(fIcon);
}
}
private IAction getAction() {
if (fAction == null) {
ApplicationWindow aw = (ApplicationWindow) fWindow;
ToolBarContributionItem tbcItem = (ToolBarContributionItem) aw
.getCoolBarManager().find(
"org.radrails.rails.ui.railsActions");
ActionContributionItem acItem = (ActionContributionItem) tbcItem
.getToolBarManager().find(
"org.radrails.rails.ui.test.RunAutotestSuite");
if (acItem != null) {
fAction = acItem.getAction();
}
}
return fAction;
}
private String writeTemporaryTestListing(List tests) {
String rubyFile = AUTOTEST_TEMPORARY_FILE;
String directoryFile = RailsPlugin.getInstance().getStateLocation()
.toOSString()
+ File.separator + rubyFile;
File pluginDirFile = new File(directoryFile);
try {
pluginDirFile.createNewFile();
FileWriter output = new FileWriter(pluginDirFile);
Iterator i = tests.iterator();
while (i.hasNext()) {
output.write("require '" + i.next().toString() + "'");
output.write('\n');
}
output.flush();
output.close();
} catch (IOException e) {
RailsLog.logError("Error writing plugin script to metadata", e);
}
String path = "";
try {
path = pluginDirFile.getCanonicalPath();
} catch (IOException e) {
RailsLog.logError("Error getting file path", e);
}
return path;
}
}