|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 package com.nokia.s60tools.creator.job; |
|
19 |
|
20 import java.io.File; |
|
21 |
|
22 import org.eclipse.core.runtime.IProgressMonitor; |
|
23 import org.eclipse.core.runtime.IStatus; |
|
24 import org.eclipse.core.runtime.Status; |
|
25 import org.eclipse.core.runtime.jobs.Job; |
|
26 import org.eclipse.jface.dialogs.IDialogConstants; |
|
27 import org.eclipse.swt.widgets.Display; |
|
28 import org.eclipse.swt.widgets.Shell; |
|
29 |
|
30 import com.nokia.s60tools.creator.CreatorActivator; |
|
31 import com.nokia.s60tools.creator.common.ProductInfoRegistry; |
|
32 import com.nokia.s60tools.creator.preferences.CreatorPreferences; |
|
33 import com.nokia.s60tools.creator.resources.Messages; |
|
34 import com.nokia.s60tools.creator.util.CreatorEditorConsole; |
|
35 import com.nokia.s60tools.hticonnection.services.AppStatus; |
|
36 import com.nokia.s60tools.hticonnection.services.HTIServiceFactory; |
|
37 import com.nokia.s60tools.hticonnection.services.IApplicationControlService; |
|
38 import com.nokia.s60tools.hticonnection.services.IConnectionTestService; |
|
39 import com.nokia.s60tools.hticonnection.services.IFTPListener; |
|
40 import com.nokia.s60tools.hticonnection.services.IFTPRequestManager; |
|
41 import com.nokia.s60tools.hticonnection.services.IFTPService; |
|
42 import com.nokia.s60tools.util.exceptions.JobCancelledByUserException; |
|
43 import com.nokia.s60tools.util.resource.FileUtils; |
|
44 |
|
45 /** |
|
46 * Job for uploading files |
|
47 */ |
|
48 public class RunInDeviceJob extends Job implements IManageableJob, IFTPListener { |
|
49 |
|
50 private static final String CREATOR_EXE_NAME = ProductInfoRegistry.getCreatorSymbianExcecutableName(); |
|
51 private String srcFilePath; |
|
52 private String destFilePath; |
|
53 private static int timeout = 30*1000; // Default timeout 30 s. |
|
54 private IProgressMonitor monitor; |
|
55 private String destFileName; |
|
56 private int confirmDialogSelection = -1; |
|
57 private IFTPRequestManager FTPReguestManager; |
|
58 |
|
59 |
|
60 /** |
|
61 * Constructor |
|
62 * @param name Name for job |
|
63 * @param srcFilePath Source file path |
|
64 * @param destFilePath Destination file path |
|
65 */ |
|
66 public RunInDeviceJob(String name, String srcFilePath, String destFilePath, String destFileName ) { |
|
67 super(name); |
|
68 this.srcFilePath = srcFilePath; |
|
69 this.destFilePath = destFilePath; |
|
70 this.destFileName = destFileName; |
|
71 setUser(true); |
|
72 setTimeOut(); |
|
73 } |
|
74 |
|
75 /** |
|
76 * Setting the timeout for operation. |
|
77 */ |
|
78 private void setTimeOut() { |
|
79 File srcFile = new File(srcFilePath); |
|
80 Long bytes = new Long( srcFile.length()); |
|
81 //Setting time out to be 10 ms for byte, e.g script with few element is 300 bytes long, then timeout will be 30s |
|
82 int countTimeOut = bytes.intValue() * 10; |
|
83 // |
|
84 int maxTimeOut = 2*60*1000; |
|
85 //If we count longer than default time out, and it does not reach maximum time out, we set new timeout |
|
86 if(countTimeOut > timeout && countTimeOut < maxTimeOut ){ |
|
87 timeout = countTimeOut; |
|
88 } |
|
89 //if we count longer than max timeout, using max timeout |
|
90 else if(countTimeOut > maxTimeOut){ |
|
91 timeout = maxTimeOut; |
|
92 } |
|
93 |
|
94 } |
|
95 |
|
96 /* (non-Javadoc) |
|
97 * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor) |
|
98 */ |
|
99 protected IStatus run(IProgressMonitor monitor) { |
|
100 |
|
101 this.monitor = monitor; |
|
102 try{ |
|
103 |
|
104 CreatorJobManager.getInstance().registerJob(this); |
|
105 |
|
106 //First check if HTI is running |
|
107 IFTPService service = HTIServiceFactory |
|
108 .createFTPService(CreatorEditorConsole.getInstance()); |
|
109 IConnectionTestService connService = HTIServiceFactory |
|
110 .createConnectionTestService(CreatorEditorConsole.getInstance()); |
|
111 checkCancel(); |
|
112 //If HTI is not running, returning error |
|
113 if(!connService.isReady()){ |
|
114 String msg = Messages.getString("RunInDeviceJob.HTINotRunning_ErrMsg"); |
|
115 CreatorEditorConsole.getInstance().println( |
|
116 msg, CreatorEditorConsole.MSG_ERROR); //$NON-NLS-1$ |
|
117 |
|
118 return new Status( |
|
119 Status.ERROR, |
|
120 CreatorActivator.PLUGIN_ID, |
|
121 msg); //$NON-NLS-1$ |
|
122 } |
|
123 |
|
124 checkCancel(); |
|
125 |
|
126 //Then upload file |
|
127 try { |
|
128 monitor.beginTask(getName(), IProgressMonitor.UNKNOWN); //$NON-NLS-1$ |
|
129 |
|
130 boolean replace = CreatorPreferences.getDontAskFileReplaceInDevice(); |
|
131 if(!replace){ |
|
132 monitor.subTask(Messages.getString("RunInDeviceJob.CheckFileExistence_TaskName")); //$NON-NLS-1$ |
|
133 replace = true; |
|
134 //Before load, check if there is file allready |
|
135 checkCancel(); |
|
136 String deviceSaveFolded = CreatorPreferences.getDeviceSaveFolded(); |
|
137 String[] files = service.listFiles(deviceSaveFolded, 0); |
|
138 if(files != null && files.length > 0){ |
|
139 for (int i = 0; i < files.length; i++) { |
|
140 if(destFileName.equalsIgnoreCase(files[i])){ |
|
141 //File allready exist |
|
142 replace = showReplaceFileDialog(); |
|
143 break; |
|
144 } |
|
145 } |
|
146 } |
|
147 } |
|
148 |
|
149 |
|
150 //If replacing (or file does not exist) uploading file to device, |
|
151 //if user does not upload file, existing file will be executed in device. |
|
152 if(replace){ |
|
153 |
|
154 checkCancel(); |
|
155 monitor.subTask(Messages.getString("RunInDeviceJob.Upload_File_SubTaskName")); //$NON-NLS-1$ |
|
156 |
|
157 StringBuffer buf = FileUtils.loadDataFromFile(srcFilePath); |
|
158 if (buf != null) { |
|
159 String fileString = buf.toString(); |
|
160 |
|
161 checkCancel(); |
|
162 service.uploadFile(fileString.getBytes(), destFilePath, this, timeout); |
|
163 |
|
164 |
|
165 } |
|
166 } |
|
167 |
|
168 } |
|
169 catch(JobCancelledByUserException e){ |
|
170 return Status.CANCEL_STATUS; |
|
171 } |
|
172 catch (Exception e) { |
|
173 String msg = Messages.getString("RunInDeviceJob.Upload_Failed_ConsoleErrorMsg"); |
|
174 return returnErrorStatus(e, msg); |
|
175 } |
|
176 |
|
177 checkCancel(); |
|
178 |
|
179 try { |
|
180 |
|
181 IApplicationControlService appService = HTIServiceFactory.createApplicationControlService(CreatorEditorConsole.getInstance()); |
|
182 String programName = CREATOR_EXE_NAME; |
|
183 String parameters = destFilePath; |
|
184 |
|
185 //Checking Creator application status in device |
|
186 checkCancel(); |
|
187 monitor.subTask(Messages.getString("RunInDeviceJob.CheckIfRunning_SubTaskName")); //$NON-NLS-1$ |
|
188 AppStatus status = appService.getApplicationStatusByName(programName, timeout); |
|
189 |
|
190 //If creator is running, stopping it |
|
191 checkCancel(); |
|
192 if(status.getStatus() == AppStatus.RUNNING){ |
|
193 |
|
194 //Showing dialog to as if user wants to shutdown creator |
|
195 //If user selects Cancel, JobCancelledByUserException is thrown |
|
196 showShutdownDialog(); |
|
197 monitor.subTask(Messages.getString("RunInDeviceJob.StopCreator_SubTaskName")); //$NON-NLS-1$ |
|
198 appService.stopApplicationByName(programName, timeout); |
|
199 } |
|
200 |
|
201 //Showing user that he/she should follow progress in device/emulator |
|
202 showInformation(); |
|
203 |
|
204 //Start to run script |
|
205 checkCancel(); |
|
206 monitor.subTask(Messages.getString("RunInDeviceJob.Run_File_SubTaskName")); //$NON-NLS-1$ |
|
207 appService.startProcess(programName, parameters, timeout); |
|
208 } |
|
209 catch(JobCancelledByUserException e){ |
|
210 return Status.CANCEL_STATUS; |
|
211 } |
|
212 catch (Exception e){ |
|
213 String msg = Messages.getString("RunInDeviceJob.Run_Failed_ConsoleErrorMsg"); |
|
214 return returnErrorStatus(e, msg); |
|
215 |
|
216 } |
|
217 |
|
218 } |
|
219 catch(JobCancelledByUserException e){ |
|
220 return Status.CANCEL_STATUS; |
|
221 } |
|
222 finally { |
|
223 finished(); |
|
224 } |
|
225 |
|
226 return Status.OK_STATUS; |
|
227 } |
|
228 |
|
229 /** |
|
230 * Showing user a dialog to shutdown Creator in device or not, |
|
231 * @throws JobCancelledByUserException if user selects Cancel |
|
232 */ |
|
233 private void showShutdownDialog() throws JobCancelledByUserException { |
|
234 |
|
235 if(!CreatorPreferences.getDontAskShutdownCreator()){ |
|
236 |
|
237 Runnable runDlg = new Runnable(){ |
|
238 |
|
239 public void run() { |
|
240 // |
|
241 ShutdownCreatorInDeviceDialog dlg = new ShutdownCreatorInDeviceDialog(CreatorActivator.getCurrentlyActiveWbWindowShell()); |
|
242 |
|
243 dlg.open(); |
|
244 confirmDialogSelection = dlg.getSelection(); |
|
245 } |
|
246 }; |
|
247 |
|
248 Display.getDefault().syncExec(runDlg); |
|
249 |
|
250 if(confirmDialogSelection == IDialogConstants.CANCEL_ID){ |
|
251 throwJobCancelledException(); |
|
252 } |
|
253 } |
|
254 } |
|
255 |
|
256 /** |
|
257 * Shows user an information dialog to follow execution in device. |
|
258 */ |
|
259 private void showInformation() { |
|
260 |
|
261 if(!CreatorPreferences.getDontAskShowInformation()){ |
|
262 Runnable showInfo = new Runnable(){ |
|
263 |
|
264 public void run() { |
|
265 WatchDeviceInformationDialog dlg = new WatchDeviceInformationDialog( |
|
266 CreatorActivator.getCurrentlyActiveWbWindowShell(), |
|
267 destFileName); |
|
268 dlg.open(); |
|
269 |
|
270 } |
|
271 }; |
|
272 |
|
273 Display.getDefault().asyncExec(showInfo); |
|
274 } |
|
275 } |
|
276 |
|
277 /** |
|
278 * Check if job is canceled, and throws an exception if it's. |
|
279 * @throws JobCancelledByUserException |
|
280 */ |
|
281 private void checkCancel() throws JobCancelledByUserException { |
|
282 |
|
283 if(monitor.isCanceled()){ |
|
284 if(FTPReguestManager != null){ |
|
285 FTPReguestManager.cancel(); |
|
286 } |
|
287 throwJobCancelledException(); |
|
288 } |
|
289 |
|
290 } |
|
291 |
|
292 /** |
|
293 * Throw cancel exception |
|
294 * @throws JobCancelledByUserException |
|
295 */ |
|
296 private void throwJobCancelledException() throws JobCancelledByUserException { |
|
297 throw new JobCancelledByUserException(Messages.getString("RunInDeviceJob.JobCanceledByUser_Msg")); |
|
298 } |
|
299 |
|
300 /** |
|
301 * Check if user wants to replace existing file |
|
302 * @return <code>true</code> if replace, <code>false</code> otherwise. |
|
303 * @throws JobCancelledByUserException |
|
304 */ |
|
305 private boolean showReplaceFileDialog() throws JobCancelledByUserException { |
|
306 |
|
307 Runnable runDlg = new Runnable(){ |
|
308 |
|
309 public void run() { |
|
310 // |
|
311 Shell shell = CreatorActivator.getCurrentlyActiveWbWindowShell(); |
|
312 ConfirmFileReplaceDialog dlg = new ConfirmFileReplaceDialog( |
|
313 shell, destFilePath); |
|
314 |
|
315 dlg.open(); |
|
316 confirmDialogSelection = dlg.getSelection(); |
|
317 } |
|
318 }; |
|
319 |
|
320 Display.getDefault().syncExec(runDlg); |
|
321 |
|
322 if(confirmDialogSelection == IDialogConstants.CANCEL_ID){ |
|
323 throwJobCancelledException(); |
|
324 } |
|
325 boolean replace = confirmDialogSelection == IDialogConstants.YES_ID ? true : false; |
|
326 |
|
327 return replace; |
|
328 } |
|
329 |
|
330 /** |
|
331 * Returns Error status |
|
332 * @param e |
|
333 * @param msg |
|
334 * @return {@link Status} with {@link Status#ERROR} |
|
335 */ |
|
336 private IStatus returnErrorStatus(Exception e, String msg) { |
|
337 CreatorEditorConsole.getInstance().println( |
|
338 msg, CreatorEditorConsole.MSG_ERROR); //$NON-NLS-1$ |
|
339 e.printStackTrace(); |
|
340 return new Status( |
|
341 Status.ERROR, |
|
342 CreatorActivator.PLUGIN_ID, |
|
343 msg, e); //$NON-NLS-1$ |
|
344 } |
|
345 |
|
346 /** |
|
347 * Done and unregister job |
|
348 */ |
|
349 private void finished() { |
|
350 monitor.done(); |
|
351 CreatorJobManager.getInstance().unregisterJob(this); |
|
352 } |
|
353 |
|
354 /* (non-Javadoc) |
|
355 * @see com.nokia.s60tools.remotecontrol.job.IManageableJob#forcedShutdown() |
|
356 */ |
|
357 public void forcedShutdown() { |
|
358 cancel(); |
|
359 } |
|
360 |
|
361 /* (non-Javadoc) |
|
362 * @see com.nokia.s60tools.hticonnection.services.IFTPListener#requestEnded(com.nokia.s60tools.hticonnection.services.IFTPRequestManager) |
|
363 */ |
|
364 public void requestEnded(IFTPRequestManager manager) { |
|
365 // not needed |
|
366 } |
|
367 |
|
368 /* (non-Javadoc) |
|
369 * @see com.nokia.s60tools.hticonnection.services.IFTPListener#requestInQueue(com.nokia.s60tools.hticonnection.services.IFTPRequestManager) |
|
370 */ |
|
371 public void requestInQueue(IFTPRequestManager manager) { |
|
372 // not needed |
|
373 } |
|
374 |
|
375 /* (non-Javadoc) |
|
376 * @see com.nokia.s60tools.hticonnection.services.IFTPListener#requestStarted(com.nokia.s60tools.hticonnection.services.IFTPRequestManager) |
|
377 */ |
|
378 public void requestStarted(IFTPRequestManager manager) { |
|
379 FTPReguestManager = manager; |
|
380 } |
|
381 |
|
382 } |