|
1 /* |
|
2 * Copyright (c) 2008 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.crashanalyser.ui.wizards; |
|
19 |
|
20 import org.eclipse.core.runtime.IConfigurationElement; |
|
21 import org.eclipse.core.runtime.IExtension; |
|
22 import org.eclipse.core.runtime.IExtensionPoint; |
|
23 import org.eclipse.core.runtime.IExtensionRegistry; |
|
24 import org.eclipse.core.runtime.IProgressMonitor; |
|
25 import org.eclipse.core.runtime.Platform; |
|
26 import org.eclipse.jface.dialogs.MessageDialog; |
|
27 import org.eclipse.jface.operation.IRunnableWithProgress; |
|
28 import org.eclipse.jface.resource.ImageDescriptor; |
|
29 import org.eclipse.jface.viewers.IStructuredSelection; |
|
30 import org.eclipse.jface.wizard.IWizardPage; |
|
31 import org.eclipse.swt.widgets.Display; |
|
32 import org.eclipse.ui.IWorkbench; |
|
33 import com.nokia.s60tools.ui.wizards.S60ToolsWizard; |
|
34 import com.nokia.s60tools.crashanalyser.model.*; |
|
35 import com.nokia.s60tools.crashanalyser.plugin.CrashAnalyserPlugin; |
|
36 import com.nokia.s60tools.crashanalyser.resources.*; |
|
37 import com.nokia.s60tools.crashanalyser.ui.views.*; |
|
38 import com.nokia.s60tools.crashanalyser.data.*; |
|
39 import com.nokia.s60tools.crashanalyser.export.ICrashFileProvider; |
|
40 |
|
41 import java.util.*; |
|
42 |
|
43 /** |
|
44 * Crash Analyser Wizard is used for collecting required data from user so that CrashAnalyser.exe |
|
45 * can be executed. |
|
46 * |
|
47 */ |
|
48 public class CrashAnalyserWizard extends S60ToolsWizard { |
|
49 |
|
50 static private final ImageDescriptor bannerImgDescriptor = ImageResourceManager.getImageDescriptor(ImageKeys.WIZARD_BANNER); |
|
51 List<CrashFileBundle> filesToDecode = null; |
|
52 IWizardPage returnPage = null; |
|
53 ErrorLibrary errorLibrary; |
|
54 FileOrPathSelectionPage crashFileOrFolderSelectionPage = null; |
|
55 FilesSelectionPage filesSelectionPage = null; |
|
56 ParameterFilesPage parameterFilesPage = null; |
|
57 DecoderEngine engine; |
|
58 String userProvidedCrashFileOrFolder; |
|
59 boolean crashAnalyserExeExecutionSuccess = false; |
|
60 boolean readCrashFileFromDevice = false; |
|
61 String providedFileOrFolder = ""; |
|
62 String errorMessage = ""; |
|
63 String[] filesToBeSelectedOnSecondPage = null; |
|
64 final String EXTENSION_FILE_PROVIDER = "fileprovider"; //$NON-NLS-1$ |
|
65 ICrashFileProvider fileProvider = null; |
|
66 /** |
|
67 * Constructor |
|
68 * @param filesToBeDecoded list of files to be decoded. If null is passed, wizard will start from the beginning. |
|
69 * If list contains files, then wizard is started from the 3rd page |
|
70 * @param library error library |
|
71 */ |
|
72 public CrashAnalyserWizard(List<CrashFileBundle> filesToBeDecoded, ErrorLibrary library) { |
|
73 super(bannerImgDescriptor); |
|
74 engine = new DecoderEngine(); |
|
75 filesToDecode = filesToBeDecoded; |
|
76 errorLibrary = library; |
|
77 readFileProvider(); |
|
78 } |
|
79 |
|
80 /** |
|
81 * Constructor (used in drag&drop cases) |
|
82 * @param prefilledFileOrFolder single file or folder which is filled to 1st wizard page |
|
83 * @param filesToSelect only these files should be shown in 2nd wizard page |
|
84 * @param library error library |
|
85 */ |
|
86 public CrashAnalyserWizard(String prefilledFileOrFolder, String[] filesToSelect, ErrorLibrary library) { |
|
87 super(bannerImgDescriptor); |
|
88 engine = new DecoderEngine(); |
|
89 filesToDecode = null; |
|
90 errorLibrary = library; |
|
91 providedFileOrFolder = prefilledFileOrFolder; |
|
92 filesToBeSelectedOnSecondPage = filesToSelect; |
|
93 readFileProvider(); |
|
94 } |
|
95 |
|
96 public void init(IWorkbench arg0, IStructuredSelection arg1) { |
|
97 // No implementation needed |
|
98 } |
|
99 |
|
100 |
|
101 @Override |
|
102 public boolean needsProgressMonitor() { |
|
103 return true; |
|
104 } |
|
105 |
|
106 @Override |
|
107 public void addPages() { |
|
108 // we are doing a full import, add all pages |
|
109 if (filesToDecode == null) { |
|
110 crashFileOrFolderSelectionPage = |
|
111 new FileOrPathSelectionPage(engine, |
|
112 errorLibrary, |
|
113 providedFileOrFolder, |
|
114 this, |
|
115 fileProvider); |
|
116 addPage(crashFileOrFolderSelectionPage); |
|
117 |
|
118 filesSelectionPage = new FilesSelectionPage(engine, filesToBeSelectedOnSecondPage); |
|
119 addPage(filesSelectionPage); |
|
120 |
|
121 parameterFilesPage = new ParameterFilesPage(engine, false); |
|
122 addPage(parameterFilesPage); |
|
123 |
|
124 setWindowTitle("Crash Analyser - Crash File Import Wizard"); |
|
125 |
|
126 // files were drag&dropped, "press next automatically" |
|
127 if (!"".equals(providedFileOrFolder)) |
|
128 moveToSecondPage(); |
|
129 |
|
130 // we are re-decoding files provided by user, show only "3rd" page |
|
131 } else { |
|
132 parameterFilesPage = new ParameterFilesPage(engine, true); |
|
133 addPage(parameterFilesPage); |
|
134 |
|
135 engine.setCrashFiles(filesToDecode); |
|
136 |
|
137 setWindowTitle("Crash Analyser - Re-Decoding Selected Files"); |
|
138 } |
|
139 } |
|
140 |
|
141 public void moveToSecondPageRequest(String[] showOnlyTheseFiles) { |
|
142 filesSelectionPage.showOnlyTheseFiles(showOnlyTheseFiles); |
|
143 moveToSecondPage(); |
|
144 } |
|
145 |
|
146 public void moveToSecondPageRequest(boolean readFilesFromDevice) { |
|
147 readCrashFileFromDevice = readFilesFromDevice; |
|
148 moveToSecondPage(); |
|
149 } |
|
150 |
|
151 /** |
|
152 * When user has drag&dropped files, we "automatically press next" |
|
153 * in the first wizard page. |
|
154 */ |
|
155 void moveToSecondPage() { |
|
156 Runnable showWizardRunnable = new Runnable(){ |
|
157 public void run(){ |
|
158 IWizardPage nextPage = getNextPage(crashFileOrFolderSelectionPage); |
|
159 if (nextPage != null) |
|
160 getContainer().showPage(nextPage); |
|
161 } |
|
162 }; |
|
163 |
|
164 Display.getDefault().asyncExec(showWizardRunnable); |
|
165 } |
|
166 |
|
167 |
|
168 @Override |
|
169 public boolean performFinish() { |
|
170 boolean fullImport = crashFileOrFolderSelectionPage != null; |
|
171 |
|
172 // full import is the case when wizard is started from page 1 |
|
173 if (fullImport) { |
|
174 // if Finish was pressed in 2nd wizard page, symbol page (3rd page) was not used |
|
175 // false here would mean that only "decoded" files (.crashxml) files were selected. |
|
176 boolean symbolPageWasUsed = this.getContainer().getCurrentPage() != filesSelectionPage; |
|
177 |
|
178 DecodingData decodingData = new DecodingData(); |
|
179 decodingData.importingFiles = true; |
|
180 |
|
181 // save 1st page |
|
182 crashFileOrFolderSelectionPage.saveUserEnteredData(); |
|
183 |
|
184 decodingData.crashFileIndexes = filesSelectionPage.getFileIndexes(); |
|
185 |
|
186 if (symbolPageWasUsed) { |
|
187 // save 3rd page |
|
188 parameterFilesPage.saveUserEnteredData(); |
|
189 decodingData.symbolFiles = parameterFilesPage.getSymbolFiles(); |
|
190 decodingData.mapFilesFolder = parameterFilesPage.getMapFilesFolder(); |
|
191 decodingData.mapFilesZip = parameterFilesPage.getMapFilesZip(); |
|
192 decodingData.imageFiles = parameterFilesPage.getImageFiles(); |
|
193 } |
|
194 |
|
195 decodingData.errorLibrary = errorLibrary; |
|
196 |
|
197 engine.setDecodingData(decodingData); |
|
198 |
|
199 // not full import is the case when files are Re-Decoded via MainView |
|
200 } else { |
|
201 DecodingData decodingData = new DecodingData(); |
|
202 decodingData.importingFiles = false; |
|
203 |
|
204 // save 3rd page |
|
205 parameterFilesPage.saveUserEnteredData(); |
|
206 decodingData.symbolFiles = parameterFilesPage.getSymbolFiles(); |
|
207 decodingData.mapFilesFolder = parameterFilesPage.getMapFilesFolder(); |
|
208 decodingData.mapFilesZip = parameterFilesPage.getMapFilesZip(); |
|
209 decodingData.imageFiles = parameterFilesPage.getImageFiles(); |
|
210 |
|
211 decodingData.errorLibrary = errorLibrary; |
|
212 |
|
213 engine.setDecodingData(decodingData); |
|
214 } |
|
215 |
|
216 MainView mainView = MainView.showAndReturnYourself(); |
|
217 if (mainView != null) { |
|
218 mainView.startDecoding(engine); |
|
219 } |
|
220 |
|
221 return true; |
|
222 } |
|
223 |
|
224 public boolean canFinish() |
|
225 { |
|
226 if (this.getContainer().getCurrentPage() == filesSelectionPage) { |
|
227 return filesSelectionPage.canFinish(); |
|
228 } else if (this.getContainer().getCurrentPage() == parameterFilesPage) { |
|
229 return parameterFilesPage.canFinish(); |
|
230 } else { |
|
231 return false; |
|
232 } |
|
233 } |
|
234 |
|
235 public IWizardPage getNextPage(IWizardPage page) { |
|
236 // We are moving from 1st page to 2nd page. |
|
237 // We need to run CrashAnalyser.exe to get summary data for crash files |
|
238 if(page.equals(crashFileOrFolderSelectionPage)){ |
|
239 returnPage = null; |
|
240 userProvidedCrashFileOrFolder = crashFileOrFolderSelectionPage.getSelectedFileOrFolder(); |
|
241 crashAnalyserExeExecutionSuccess = false; |
|
242 try { |
|
243 getContainer().run(true, false, new IRunnableWithProgress() { |
|
244 public void run(IProgressMonitor monitor) { |
|
245 errorMessage = ""; |
|
246 // run CrashAnalyser.exe for summary information for selected file(s). |
|
247 if (readCrashFileFromDevice && fileProvider != null) { |
|
248 errorMessage = fileProvider.executeFunctionality(DecoderEngine.getTemporaryCrashFileFolder(true)); |
|
249 userProvidedCrashFileOrFolder = DecoderEngine.getTemporaryCrashFileFolder(false); |
|
250 } |
|
251 crashAnalyserExeExecutionSuccess = |
|
252 engine.processSummaryInfoForFiles(userProvidedCrashFileOrFolder, errorLibrary, monitor); |
|
253 } |
|
254 } |
|
255 ); |
|
256 } catch (Exception e) { |
|
257 e.printStackTrace(); |
|
258 } |
|
259 |
|
260 // CrashAnalyser.exe execution was successful -> return next wizard page |
|
261 if (crashAnalyserExeExecutionSuccess) { |
|
262 crashFileOrFolderSelectionPage.errorInProcessingNextPress(false); |
|
263 filesSelectionPage.loadTable(); |
|
264 returnPage = filesSelectionPage; |
|
265 // CrashAnalyser.exe execution was unsuccessful, don't proceed to next |
|
266 // wizard page -> return current page |
|
267 } else { |
|
268 if (readCrashFileFromDevice) { |
|
269 if ("".equals(errorMessage)) { |
|
270 showMessage("The device did not contain any crash files"); |
|
271 } else { |
|
272 showMessage("Could not read crash files. Please check PC Suite connection.\n\nError:\n" + errorMessage); |
|
273 } |
|
274 } else { |
|
275 crashFileOrFolderSelectionPage.errorInProcessingNextPress(true); |
|
276 } |
|
277 returnPage = crashFileOrFolderSelectionPage; |
|
278 filesSelectionPage.showOnlyTheseFiles(null); |
|
279 } |
|
280 |
|
281 readCrashFileFromDevice = false; |
|
282 |
|
283 return returnPage; |
|
284 } |
|
285 // We are moving from 2nd page to 3rd/4th page. |
|
286 else if (page.equals(filesSelectionPage)) { |
|
287 // only (already "decoded") output.crashxml files have been selected in 2nd page. |
|
288 // Skip parameterFiles page and go to additionalSettingsPage, because we don't have |
|
289 // to query for symbols etc. because there is nothing to decode. |
|
290 return parameterFilesPage; |
|
291 } |
|
292 |
|
293 return null; |
|
294 } |
|
295 |
|
296 /** |
|
297 * Shows a message box with given message |
|
298 * @param message |
|
299 */ |
|
300 private void showMessage(String message) { |
|
301 MessageDialog.openInformation( |
|
302 getShell(), |
|
303 "Crash Analyser", |
|
304 message); |
|
305 } |
|
306 |
|
307 @Override |
|
308 public boolean performCancel() { |
|
309 DecoderEngine.getTemporaryCrashFileFolder(true); |
|
310 return super.performCancel(); |
|
311 } |
|
312 |
|
313 /** |
|
314 * Tries to find plugins which are File Providers. Selectes the first found |
|
315 * File provider plugin. |
|
316 */ |
|
317 void readFileProvider() { |
|
318 try { |
|
319 IExtensionRegistry er = Platform.getExtensionRegistry(); |
|
320 IExtensionPoint ep = |
|
321 er.getExtensionPoint(CrashAnalyserPlugin.PLUGIN_ID, EXTENSION_FILE_PROVIDER); |
|
322 IExtension[] extensions = ep.getExtensions(); |
|
323 |
|
324 // if plug-ins were found. |
|
325 if (extensions != null && extensions.length > 0) { |
|
326 |
|
327 // read all found trace providers |
|
328 for (int i = 0; i < extensions.length; i++) { |
|
329 IConfigurationElement[] ce = extensions[i].getConfigurationElements(); |
|
330 if (ce != null && ce.length > 0) { |
|
331 try { |
|
332 ICrashFileProvider provider = (ICrashFileProvider)ce[0].createExecutableExtension("class"); |
|
333 // we support only one trace provider |
|
334 if (provider != null) { |
|
335 fileProvider = provider; |
|
336 break; |
|
337 } |
|
338 } catch (Exception e) { |
|
339 e.printStackTrace(); |
|
340 } |
|
341 } |
|
342 } |
|
343 } |
|
344 } catch (Exception e) { |
|
345 e.printStackTrace(); |
|
346 } |
|
347 } |
|
348 } |