creatorextension/com.nokia.s60tools.creator/src/com/nokia/s60tools/creator/job/RunInDeviceJob.java
/*
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:
*
*/
package com.nokia.s60tools.creator.job;
import java.io.File;
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.dialogs.IDialogConstants;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import com.nokia.s60tools.creator.CreatorActivator;
import com.nokia.s60tools.creator.common.ProductInfoRegistry;
import com.nokia.s60tools.creator.preferences.CreatorPreferences;
import com.nokia.s60tools.creator.resources.Messages;
import com.nokia.s60tools.creator.util.CreatorEditorConsole;
import com.nokia.s60tools.hticonnection.services.AppStatus;
import com.nokia.s60tools.hticonnection.services.HTIServiceFactory;
import com.nokia.s60tools.hticonnection.services.IApplicationControlService;
import com.nokia.s60tools.hticonnection.services.IConnectionTestService;
import com.nokia.s60tools.hticonnection.services.IFTPListener;
import com.nokia.s60tools.hticonnection.services.IFTPRequestManager;
import com.nokia.s60tools.hticonnection.services.IFTPService;
import com.nokia.s60tools.util.exceptions.JobCancelledByUserException;
import com.nokia.s60tools.util.resource.FileUtils;
/**
* Job for uploading files
*/
public class RunInDeviceJob extends Job implements IManageableJob, IFTPListener {
private static final String CREATOR_EXE_NAME = ProductInfoRegistry.getCreatorSymbianExcecutableName();
private String srcFilePath;
private String destFilePath;
private static int timeout = 30*1000; // Default timeout 30 s.
private IProgressMonitor monitor;
private String destFileName;
private int confirmDialogSelection = -1;
private IFTPRequestManager FTPReguestManager;
/**
* Constructor
* @param name Name for job
* @param srcFilePath Source file path
* @param destFilePath Destination file path
*/
public RunInDeviceJob(String name, String srcFilePath, String destFilePath, String destFileName ) {
super(name);
this.srcFilePath = srcFilePath;
this.destFilePath = destFilePath;
this.destFileName = destFileName;
setUser(true);
setTimeOut();
}
/**
* Setting the timeout for operation.
*/
private void setTimeOut() {
File srcFile = new File(srcFilePath);
Long bytes = new Long( srcFile.length());
//Setting time out to be 10 ms for byte, e.g script with few element is 300 bytes long, then timeout will be 30s
int countTimeOut = bytes.intValue() * 10;
//
int maxTimeOut = 2*60*1000;
//If we count longer than default time out, and it does not reach maximum time out, we set new timeout
if(countTimeOut > timeout && countTimeOut < maxTimeOut ){
timeout = countTimeOut;
}
//if we count longer than max timeout, using max timeout
else if(countTimeOut > maxTimeOut){
timeout = maxTimeOut;
}
}
/* (non-Javadoc)
* @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
*/
protected IStatus run(IProgressMonitor monitor) {
this.monitor = monitor;
try{
CreatorJobManager.getInstance().registerJob(this);
//First check if HTI is running
IFTPService service = HTIServiceFactory
.createFTPService(CreatorEditorConsole.getInstance());
IConnectionTestService connService = HTIServiceFactory
.createConnectionTestService(CreatorEditorConsole.getInstance());
checkCancel();
//If HTI is not running, returning error
if(!connService.isReady()){
String msg = Messages.getString("RunInDeviceJob.HTINotRunning_ErrMsg");
CreatorEditorConsole.getInstance().println(
msg, CreatorEditorConsole.MSG_ERROR); //$NON-NLS-1$
return new Status(
Status.ERROR,
CreatorActivator.PLUGIN_ID,
msg); //$NON-NLS-1$
}
checkCancel();
//Then upload file
try {
monitor.beginTask(getName(), IProgressMonitor.UNKNOWN); //$NON-NLS-1$
boolean replace = CreatorPreferences.getDontAskFileReplaceInDevice();
if(!replace){
monitor.subTask(Messages.getString("RunInDeviceJob.CheckFileExistence_TaskName")); //$NON-NLS-1$
replace = true;
//Before load, check if there is file allready
checkCancel();
String deviceSaveFolded = CreatorPreferences.getDeviceSaveFolded();
String[] files = service.listFiles(deviceSaveFolded, 0);
if(files != null && files.length > 0){
for (int i = 0; i < files.length; i++) {
if(destFileName.equalsIgnoreCase(files[i])){
//File allready exist
replace = showReplaceFileDialog();
break;
}
}
}
}
//If replacing (or file does not exist) uploading file to device,
//if user does not upload file, existing file will be executed in device.
if(replace){
checkCancel();
monitor.subTask(Messages.getString("RunInDeviceJob.Upload_File_SubTaskName")); //$NON-NLS-1$
StringBuffer buf = FileUtils.loadDataFromFile(srcFilePath);
if (buf != null) {
String fileString = buf.toString();
checkCancel();
service.uploadFile(fileString.getBytes(), destFilePath, this, timeout);
}
}
}
catch(JobCancelledByUserException e){
return Status.CANCEL_STATUS;
}
catch (Exception e) {
String msg = Messages.getString("RunInDeviceJob.Upload_Failed_ConsoleErrorMsg");
return returnErrorStatus(e, msg);
}
checkCancel();
try {
IApplicationControlService appService = HTIServiceFactory.createApplicationControlService(CreatorEditorConsole.getInstance());
String programName = CREATOR_EXE_NAME;
String parameters = destFilePath;
//Checking Creator application status in device
checkCancel();
monitor.subTask(Messages.getString("RunInDeviceJob.CheckIfRunning_SubTaskName")); //$NON-NLS-1$
AppStatus status = appService.getApplicationStatusByName(programName, timeout);
//If creator is running, stopping it
checkCancel();
if(status.getStatus() == AppStatus.RUNNING){
//Showing dialog to as if user wants to shutdown creator
//If user selects Cancel, JobCancelledByUserException is thrown
showShutdownDialog();
monitor.subTask(Messages.getString("RunInDeviceJob.StopCreator_SubTaskName")); //$NON-NLS-1$
appService.stopApplicationByName(programName, timeout);
}
//Showing user that he/she should follow progress in device/emulator
showInformation();
//Start to run script
checkCancel();
monitor.subTask(Messages.getString("RunInDeviceJob.Run_File_SubTaskName")); //$NON-NLS-1$
appService.startProcess(programName, parameters, timeout);
}
catch(JobCancelledByUserException e){
return Status.CANCEL_STATUS;
}
catch (Exception e){
String msg = Messages.getString("RunInDeviceJob.Run_Failed_ConsoleErrorMsg");
return returnErrorStatus(e, msg);
}
}
catch(JobCancelledByUserException e){
return Status.CANCEL_STATUS;
}
finally {
finished();
}
return Status.OK_STATUS;
}
/**
* Showing user a dialog to shutdown Creator in device or not,
* @throws JobCancelledByUserException if user selects Cancel
*/
private void showShutdownDialog() throws JobCancelledByUserException {
if(!CreatorPreferences.getDontAskShutdownCreator()){
Runnable runDlg = new Runnable(){
public void run() {
//
ShutdownCreatorInDeviceDialog dlg = new ShutdownCreatorInDeviceDialog(CreatorActivator.getCurrentlyActiveWbWindowShell());
dlg.open();
confirmDialogSelection = dlg.getSelection();
}
};
Display.getDefault().syncExec(runDlg);
if(confirmDialogSelection == IDialogConstants.CANCEL_ID){
throwJobCancelledException();
}
}
}
/**
* Shows user an information dialog to follow execution in device.
*/
private void showInformation() {
if(!CreatorPreferences.getDontAskShowInformation()){
Runnable showInfo = new Runnable(){
public void run() {
WatchDeviceInformationDialog dlg = new WatchDeviceInformationDialog(
CreatorActivator.getCurrentlyActiveWbWindowShell(),
destFileName);
dlg.open();
}
};
Display.getDefault().asyncExec(showInfo);
}
}
/**
* Check if job is canceled, and throws an exception if it's.
* @throws JobCancelledByUserException
*/
private void checkCancel() throws JobCancelledByUserException {
if(monitor.isCanceled()){
if(FTPReguestManager != null){
FTPReguestManager.cancel();
}
throwJobCancelledException();
}
}
/**
* Throw cancel exception
* @throws JobCancelledByUserException
*/
private void throwJobCancelledException() throws JobCancelledByUserException {
throw new JobCancelledByUserException(Messages.getString("RunInDeviceJob.JobCanceledByUser_Msg"));
}
/**
* Check if user wants to replace existing file
* @return <code>true</code> if replace, <code>false</code> otherwise.
* @throws JobCancelledByUserException
*/
private boolean showReplaceFileDialog() throws JobCancelledByUserException {
Runnable runDlg = new Runnable(){
public void run() {
//
Shell shell = CreatorActivator.getCurrentlyActiveWbWindowShell();
ConfirmFileReplaceDialog dlg = new ConfirmFileReplaceDialog(
shell, destFilePath);
dlg.open();
confirmDialogSelection = dlg.getSelection();
}
};
Display.getDefault().syncExec(runDlg);
if(confirmDialogSelection == IDialogConstants.CANCEL_ID){
throwJobCancelledException();
}
boolean replace = confirmDialogSelection == IDialogConstants.YES_ID ? true : false;
return replace;
}
/**
* Returns Error status
* @param e
* @param msg
* @return {@link Status} with {@link Status#ERROR}
*/
private IStatus returnErrorStatus(Exception e, String msg) {
CreatorEditorConsole.getInstance().println(
msg, CreatorEditorConsole.MSG_ERROR); //$NON-NLS-1$
e.printStackTrace();
return new Status(
Status.ERROR,
CreatorActivator.PLUGIN_ID,
msg, e); //$NON-NLS-1$
}
/**
* Done and unregister job
*/
private void finished() {
monitor.done();
CreatorJobManager.getInstance().unregisterJob(this);
}
/* (non-Javadoc)
* @see com.nokia.s60tools.remotecontrol.job.IManageableJob#forcedShutdown()
*/
public void forcedShutdown() {
cancel();
}
/* (non-Javadoc)
* @see com.nokia.s60tools.hticonnection.services.IFTPListener#requestEnded(com.nokia.s60tools.hticonnection.services.IFTPRequestManager)
*/
public void requestEnded(IFTPRequestManager manager) {
// not needed
}
/* (non-Javadoc)
* @see com.nokia.s60tools.hticonnection.services.IFTPListener#requestInQueue(com.nokia.s60tools.hticonnection.services.IFTPRequestManager)
*/
public void requestInQueue(IFTPRequestManager manager) {
// not needed
}
/* (non-Javadoc)
* @see com.nokia.s60tools.hticonnection.services.IFTPListener#requestStarted(com.nokia.s60tools.hticonnection.services.IFTPRequestManager)
*/
public void requestStarted(IFTPRequestManager manager) {
FTPReguestManager = manager;
}
}