Commit | Line | Data |
---|---|---|
d04ec5a7 MK |
1 | /******************************************************************************* |
2 | * Copyright (c) 2013 Ericsson | |
3 | * | |
4 | * All rights reserved. This program and the accompanying materials are | |
5 | * made available under the terms of the Eclipse Public License v1.0 which | |
6 | * accompanies this distribution, and is available at | |
7 | * http://www.eclipse.org/legal/epl-v10.html | |
8 | * | |
9 | * Contributors: | |
10 | * Matthew Khouzam - Initial API and implementation | |
4196e938 | 11 | * Marc-Andre Laperle - Log some exceptions |
d04ec5a7 MK |
12 | *******************************************************************************/ |
13 | ||
14 | package org.eclipse.linuxtools.tmf.ui.project.wizards.importtrace; | |
15 | ||
16 | import java.io.File; | |
a2d29ca1 | 17 | import java.io.FileInputStream; |
d04ec5a7 MK |
18 | import java.lang.reflect.InvocationTargetException; |
19 | import java.util.ArrayList; | |
a2d29ca1 MK |
20 | import java.util.Collections; |
21 | import java.util.Comparator; | |
d04ec5a7 | 22 | import java.util.HashMap; |
11c9462b | 23 | import java.util.HashSet; |
9b48d94c | 24 | import java.util.Iterator; |
d04ec5a7 MK |
25 | import java.util.List; |
26 | import java.util.Map; | |
27 | import java.util.Set; | |
28 | import java.util.TreeSet; | |
29 | import java.util.concurrent.BlockingQueue; | |
30 | ||
31 | import org.eclipse.core.resources.IFile; | |
32 | import org.eclipse.core.resources.IFolder; | |
33 | import org.eclipse.core.resources.IResource; | |
d04ec5a7 MK |
34 | import org.eclipse.core.resources.ResourcesPlugin; |
35 | import org.eclipse.core.runtime.CoreException; | |
d04ec5a7 MK |
36 | import org.eclipse.core.runtime.IPath; |
37 | import org.eclipse.core.runtime.IProgressMonitor; | |
38 | import org.eclipse.core.runtime.IStatus; | |
9b48d94c | 39 | import org.eclipse.core.runtime.NullProgressMonitor; |
d04ec5a7 MK |
40 | import org.eclipse.core.runtime.Path; |
41 | import org.eclipse.core.runtime.Status; | |
42 | import org.eclipse.core.runtime.SubMonitor; | |
43 | import org.eclipse.jface.dialogs.ErrorDialog; | |
44 | import org.eclipse.jface.dialogs.IDialogSettings; | |
45 | import org.eclipse.jface.operation.IRunnableWithProgress; | |
46 | import org.eclipse.jface.viewers.IStructuredSelection; | |
47 | import org.eclipse.jface.wizard.IWizardPage; | |
ac645886 | 48 | import org.eclipse.jface.wizard.Wizard; |
d04ec5a7 MK |
49 | import org.eclipse.jface.wizard.WizardDialog; |
50 | import org.eclipse.linuxtools.internal.tmf.ui.Activator; | |
76fccfb0 | 51 | import org.eclipse.linuxtools.internal.tmf.ui.project.model.TmfImportHelper; |
a2d29ca1 | 52 | import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; |
d04ec5a7 MK |
53 | import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectElement; |
54 | import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectRegistry; | |
55 | import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement; | |
9b48d94c | 56 | import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceFolder; |
d04ec5a7 | 57 | import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceType; |
26e33e67 | 58 | import org.eclipse.linuxtools.tmf.ui.project.model.TraceTypeHelper; |
d04ec5a7 | 59 | import org.eclipse.linuxtools.tmf.ui.project.model.TraceValidationHelper; |
ac645886 | 60 | import org.eclipse.ui.IImportWizard; |
d04ec5a7 MK |
61 | import org.eclipse.ui.IWorkbench; |
62 | import org.eclipse.ui.dialogs.IOverwriteQuery; | |
63 | import org.eclipse.ui.wizards.datatransfer.FileSystemStructureProvider; | |
64 | import org.eclipse.ui.wizards.datatransfer.ImportOperation; | |
65 | ||
66 | /** | |
67 | * Batch Import trace wizard. | |
68 | * | |
69 | * @author Matthew Khouzam | |
70 | * @since 2.0 | |
71 | */ | |
ac645886 | 72 | public class BatchImportTraceWizard extends Wizard implements IImportWizard { |
d04ec5a7 | 73 | |
11c9462b MK |
74 | private static final int WIN_HEIGHT = 400; |
75 | private static final int WIN_WIDTH = 800; | |
76 | private static final Status CANCEL_STATUS = new Status(IStatus.CANCEL, Activator.PLUGIN_ID, ""); //$NON-NLS-1$ | |
d04ec5a7 MK |
77 | private static final int TOTALWORK = 65536; |
78 | // ----------------- | |
79 | // Constants | |
80 | // ----------------- | |
81 | ||
82 | private static final int MAX_FILES = TOTALWORK - 1; | |
d04ec5a7 MK |
83 | private static final String BATCH_IMPORT_WIZARD = "BatchImportTraceWizard"; //$NON-NLS-1$ |
84 | ||
85 | // ------------------ | |
86 | // Fields | |
87 | // ------------------ | |
88 | ||
89 | private IWizardPage fSelectDirectoriesPage; | |
ba486486 | 90 | private ImportTraceWizardScanPage fScanPage; |
d04ec5a7 | 91 | private IWizardPage fSelectTypePage; |
a2d29ca1 | 92 | private IWizardPage fOptions; |
d04ec5a7 | 93 | |
507b1336 AM |
94 | private final List<String> fTraceTypesToScan = new ArrayList<>(); |
95 | private final Set<String> fParentFilesToScan = new HashSet<>(); | |
d04ec5a7 | 96 | |
ba486486 | 97 | private ImportTraceContentProvider fScannedTraces = new ImportTraceContentProvider(fTraceTypesToScan, fParentFilesToScan); |
d04ec5a7 | 98 | |
507b1336 | 99 | private final Map<TraceValidationHelper, Boolean> fResults = new HashMap<>(); |
d04ec5a7 MK |
100 | private boolean fOverwrite = true; |
101 | private boolean fLinked = true; | |
102 | ||
103 | private BlockingQueue<TraceValidationHelper> fTracesToScan; | |
507b1336 | 104 | private final Set<FileAndName> fTraces = new TreeSet<>(); |
11c9462b | 105 | |
507b1336 | 106 | private Map<String, Set<String>> fParentFiles = new HashMap<>(); |
11c9462b | 107 | |
d04ec5a7 MK |
108 | // Target import directory ('Traces' folder) |
109 | private IFolder fTargetFolder; | |
110 | ||
111 | /** | |
112 | * Returns the ScannedTraces model | |
113 | * | |
114 | * @return the ScannedTraces model | |
115 | */ | |
116 | public ImportTraceContentProvider getScannedTraces() { | |
117 | return fScannedTraces; | |
118 | } | |
119 | ||
120 | /** | |
121 | * Constructor | |
122 | */ | |
123 | public BatchImportTraceWizard() { | |
124 | IDialogSettings workbenchSettings = Activator.getDefault().getDialogSettings(); | |
125 | IDialogSettings section = workbenchSettings.getSection(BATCH_IMPORT_WIZARD); | |
126 | if (section == null) { | |
127 | section = workbenchSettings.addNewSection(BATCH_IMPORT_WIZARD); | |
128 | } | |
129 | setDialogSettings(section); | |
130 | setNeedsProgressMonitor(true); | |
131 | } | |
132 | ||
133 | @Override | |
134 | public void init(IWorkbench workbench, IStructuredSelection selection) { | |
135 | ||
136 | fSelectDirectoriesPage = new ImportTraceWizardSelectDirectoriesPage(workbench, selection); | |
137 | fScanPage = new ImportTraceWizardScanPage(workbench, selection); | |
138 | fSelectTypePage = new ImportTraceWizardSelectTraceTypePage(workbench, selection); | |
a2d29ca1 | 139 | fOptions = new ImportTraceWizardPageOptions(workbench, selection); |
d04ec5a7 | 140 | // keep in case it's called later |
9b48d94c MK |
141 | Iterator<?> iter = selection.iterator(); |
142 | while (iter.hasNext()) { | |
143 | Object selected = iter.next(); | |
144 | if (selected instanceof TmfTraceFolder) { | |
145 | fTargetFolder = ((TmfTraceFolder) selected).getResource(); | |
146 | break; | |
147 | } | |
148 | } | |
d04ec5a7 MK |
149 | fResults.clear(); |
150 | } | |
151 | ||
152 | @Override | |
153 | public void addPages() { | |
154 | addPage(fSelectTypePage); | |
155 | addPage(fSelectDirectoriesPage); | |
156 | addPage(fScanPage); | |
a2d29ca1 | 157 | addPage(fOptions); |
11c9462b MK |
158 | final WizardDialog container = (WizardDialog) getContainer(); |
159 | if (container != null) { | |
160 | container.setPageSize(WIN_WIDTH, WIN_HEIGHT); | |
d04ec5a7 | 161 | } |
d04ec5a7 MK |
162 | } |
163 | ||
164 | /** | |
165 | * Add a file to scan | |
166 | * | |
167 | * @param fileName | |
168 | * the file to scan | |
169 | */ | |
170 | public void addFileToScan(final String fileName) { | |
91e941e8 MAL |
171 | String absolutePath = new File(fileName).getAbsolutePath(); |
172 | if (!fParentFiles.containsKey(absolutePath)) { | |
173 | fParentFiles.put(absolutePath, new HashSet<String>()); | |
174 | startUpdateTask(Messages.BatchImportTraceWizardAdd + ' ' + absolutePath, absolutePath); | |
11c9462b MK |
175 | |
176 | } | |
177 | ||
d04ec5a7 MK |
178 | } |
179 | ||
180 | /** | |
181 | * Remove files from selection | |
182 | * | |
183 | * @param fileName | |
184 | * the name of the file to remove | |
185 | */ | |
186 | public void removeFile(final String fileName) { | |
11c9462b | 187 | fParentFiles.remove(fileName); |
d04ec5a7 | 188 | fParentFilesToScan.remove(fileName); |
97c6e624 | 189 | startUpdateTask(Messages.BatchImportTraceWizardRemove + ' ' + fileName, null); |
d04ec5a7 MK |
190 | } |
191 | ||
91e941e8 | 192 | private void startUpdateTask(final String taskName, final String fileAbsolutePath) { |
d04ec5a7 | 193 | try { |
11c9462b | 194 | this.getContainer().run(true, true, new IRunnableWithProgress() { |
d04ec5a7 MK |
195 | |
196 | @Override | |
197 | public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { | |
198 | synchronized (BatchImportTraceWizard.this) { // this should | |
199 | // only run one | |
200 | // at a time | |
201 | SubMonitor sm; | |
202 | sm = SubMonitor.convert(monitor); | |
203 | sm.setTaskName(taskName); | |
204 | sm.setWorkRemaining(TOTALWORK); | |
91e941e8 | 205 | updateFiles(sm, fileAbsolutePath); |
d04ec5a7 MK |
206 | sm.done(); |
207 | } | |
208 | } | |
209 | }); | |
210 | } catch (InvocationTargetException e) { | |
4196e938 | 211 | Activator.getDefault().logError(Messages.ImportTraceWizardImportProblem, e); |
d04ec5a7 | 212 | } catch (InterruptedException e) { |
d04ec5a7 MK |
213 | } |
214 | } | |
215 | ||
216 | /** | |
217 | * The set of names of the selected files | |
218 | * | |
219 | * @return the set of names of the selected files | |
220 | */ | |
221 | public Set<String> getFileNames() { | |
222 | return fParentFilesToScan; | |
223 | } | |
224 | ||
225 | /** | |
226 | * Reset the trace list to import | |
227 | */ | |
228 | public void clearTraces() { | |
229 | fTraces.clear(); | |
230 | } | |
231 | ||
232 | @Override | |
233 | public boolean performFinish() { | |
234 | if (fTraces.isEmpty()) { | |
235 | return false; | |
236 | } | |
237 | // if this turns out to be too slow, put in a progress monitor. Does not | |
238 | // appear to be slow for the moment. | |
239 | boolean success = importTraces(); | |
240 | return success; | |
241 | } | |
242 | ||
243 | private boolean importTraces() { | |
244 | boolean success = false; | |
245 | IOverwriteQuery overwriteQuery = new IOverwriteQuery() { | |
246 | @Override | |
247 | public String queryOverwrite(String file) { | |
248 | return fOverwrite ? IOverwriteQuery.ALL : IOverwriteQuery.NO_ALL; | |
249 | } | |
250 | }; | |
251 | FileSystemStructureProvider fileSystemStructureProvider = FileSystemStructureProvider.INSTANCE; | |
252 | ||
253 | for (FileAndName traceToImport : fTraces) { | |
254 | try { | |
255 | if (fLinked) { | |
82cefbfe | 256 | if (TmfImportHelper.createLink(fTargetFolder, Path.fromOSString(traceToImport.getFile().getAbsolutePath()), traceToImport.getName()) == null) { |
76fccfb0 MK |
257 | success = false; |
258 | } | |
259 | else { | |
260 | success = setTraceType(traceToImport).isOK(); | |
261 | } | |
d04ec5a7 MK |
262 | } |
263 | else { | |
507b1336 | 264 | List<File> subList = new ArrayList<>(); |
a2d29ca1 MK |
265 | IPath path = fTargetFolder.getFullPath(); |
266 | File parentFile = traceToImport.getFile(); | |
267 | final boolean isFile = parentFile.isFile(); | |
268 | if (isFile) { | |
269 | IFile resource = ResourcesPlugin.getWorkspace().getRoot().getFile(path.append(traceToImport.getName())); | |
270 | if (fOverwrite || !resource.exists()) { | |
271 | subList.add(parentFile); | |
272 | parentFile = parentFile.getParentFile(); | |
507b1336 AM |
273 | try (final FileInputStream source = new FileInputStream(traceToImport.getFile());) { |
274 | if (resource.exists()) { | |
275 | resource.delete(IResource.FORCE, new NullProgressMonitor()); | |
276 | } | |
277 | resource.create(source, true, new NullProgressMonitor()); | |
a2d29ca1 | 278 | } |
a2d29ca1 MK |
279 | setTraceType(traceToImport); |
280 | success = true; | |
281 | } | |
282 | } else { | |
2e622f00 BH |
283 | // Add trace directory |
284 | subList.add(traceToImport.getFile()); | |
285 | // Add all files in trace directory | |
a2d29ca1 MK |
286 | File[] fileList = traceToImport.getFile().listFiles(); |
287 | for (File child : fileList) { | |
288 | subList.add(child); | |
289 | } | |
290 | ||
291 | Collections.sort(subList, new Comparator<File>() { | |
292 | @Override | |
293 | public int compare(File o1, File o2) { | |
294 | return o1.getAbsolutePath().compareTo(o2.getAbsolutePath()); | |
295 | } | |
296 | }); | |
a2d29ca1 MK |
297 | ImportOperation operation = new ImportOperation( |
298 | path, | |
2e622f00 | 299 | parentFile.getParentFile(), |
a2d29ca1 MK |
300 | fileSystemStructureProvider, |
301 | overwriteQuery, | |
302 | subList); | |
303 | operation.setContext(getShell()); | |
304 | operation.setCreateContainerStructure(false); | |
305 | if (executeImportOperation(operation)) { | |
306 | setTraceType(traceToImport); | |
307 | success = true; | |
308 | } | |
d04ec5a7 | 309 | } |
a2d29ca1 | 310 | |
d04ec5a7 MK |
311 | } |
312 | } catch (Exception e) { | |
313 | } | |
314 | } | |
315 | return success; | |
316 | } | |
317 | ||
9b48d94c | 318 | private IStatus setTraceType(FileAndName traceToImport) { |
a2d29ca1 | 319 | IStatus validate = Status.OK_STATUS; |
d04ec5a7 MK |
320 | IPath path = fTargetFolder.getFullPath().append(traceToImport.getName()); |
321 | IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(path); | |
322 | if (resource != null) { | |
323 | try { | |
26e33e67 MAL |
324 | // Set the trace type for this resource |
325 | String traceTypeId = traceToImport.getTraceTypeId(); | |
326 | TraceTypeHelper traceType = TmfTraceType.getInstance().getTraceType(traceTypeId); | |
327 | if (traceType != null) { | |
328 | TmfTraceType.setTraceType(path, traceType); | |
d04ec5a7 | 329 | } |
26e33e67 | 330 | |
d04ec5a7 MK |
331 | TmfProjectElement tmfProject = |
332 | TmfProjectRegistry.getProject(resource.getProject()); | |
333 | if (tmfProject != null) { | |
a2d29ca1 MK |
334 | final TmfTraceFolder tracesFolder = tmfProject.getTracesFolder(); |
335 | tracesFolder.refresh(); | |
336 | ||
337 | List<TmfTraceElement> traces = tracesFolder.getTraces(); | |
338 | boolean found = false; | |
339 | for (TmfTraceElement traceElement : traces) { | |
d04ec5a7 MK |
340 | if (traceElement.getName().equals(resource.getName())) { |
341 | traceElement.refreshTraceType(); | |
a2d29ca1 | 342 | found = true; |
d04ec5a7 MK |
343 | break; |
344 | } | |
345 | } | |
a2d29ca1 MK |
346 | if (!found) { |
347 | TmfTraceElement te = new TmfTraceElement(traceToImport.getName(), resource, tracesFolder); | |
348 | te.refreshTraceType(); | |
349 | traces = tracesFolder.getTraces(); | |
350 | for (TmfTraceElement traceElement : traces) { | |
351 | if (traceElement.getName().equals(resource.getName())) { | |
352 | traceElement.refreshTraceType(); | |
353 | ITmfTrace tmfTrace = null; | |
354 | try { | |
355 | tmfTrace = traceElement.instantiateTrace(); | |
356 | if (tmfTrace != null) { | |
357 | validate = tmfTrace.validate(tmfProject.getResource(), traceElement.getLocation().getPath()); | |
358 | } else { | |
359 | return new Status(IStatus.ERROR, traceElement.getName(), "File does not exist : " + traceElement.getLocation().getPath()); //$NON-NLS-1$ | |
360 | } | |
361 | } finally { | |
362 | if (tmfTrace != null) { | |
363 | tmfTrace.dispose(); | |
364 | } | |
365 | } | |
366 | break; | |
367 | } | |
368 | } | |
369 | ||
370 | } | |
371 | ||
d04ec5a7 MK |
372 | } |
373 | } catch (CoreException e) { | |
97c6e624 | 374 | Activator.getDefault().logError(Messages.BatchImportTraceWizardErrorImportingTraceResource |
32a0863e | 375 | + ' ' + resource.getName(), e); |
d04ec5a7 MK |
376 | } |
377 | } | |
a2d29ca1 | 378 | return validate; |
d04ec5a7 MK |
379 | } |
380 | ||
381 | @Override | |
382 | public boolean canFinish() { | |
a2d29ca1 | 383 | return super.canFinish() && hasTracesToImport() && !hasConflicts() && (fTargetFolder != null); |
d04ec5a7 MK |
384 | } |
385 | ||
386 | /** | |
387 | * Returns if a trace to import is selected | |
11c9462b | 388 | * |
d04ec5a7 MK |
389 | * @return if there are traces to import |
390 | */ | |
391 | public boolean hasTracesToImport() { | |
392 | return fTraces.size() > 0; | |
393 | } | |
394 | ||
395 | /** | |
396 | * Reset the files to scan | |
397 | */ | |
398 | public void clearFilesToScan() { | |
399 | fTracesToScan.clear(); | |
400 | } | |
401 | ||
402 | /** | |
403 | * Set the trace types to scan | |
404 | * | |
405 | * @param tracesToScan | |
406 | * a list of trace types to scan for | |
407 | */ | |
408 | public void setTraceTypesToScan(List<String> tracesToScan) { | |
409 | // intersection to know if there's a diff. | |
410 | // if there's a diff, we need to re-enque everything | |
507b1336 | 411 | List<String> added = new ArrayList<>(); |
9b48d94c MK |
412 | for (String traceLoc : tracesToScan) { |
413 | if (!fTraceTypesToScan.contains(traceLoc)) { | |
414 | added.add(traceLoc); | |
415 | } | |
416 | } | |
d04ec5a7 MK |
417 | fTraceTypesToScan.clear(); |
418 | fTraceTypesToScan.addAll(tracesToScan); | |
9b48d94c | 419 | updateTracesToScan(added); |
d04ec5a7 MK |
420 | } |
421 | ||
422 | /** | |
423 | * Get the trace types to scan | |
424 | * | |
425 | * @return a list of traces to Scan for | |
426 | */ | |
427 | public List<String> getTraceTypesToScan() { | |
428 | return fTraceTypesToScan; | |
429 | } | |
430 | ||
431 | /** | |
432 | * Add files to Import | |
433 | * | |
434 | * @param element | |
435 | * add the file and tracetype to import | |
436 | */ | |
437 | public void addFileToImport(FileAndName element) { | |
438 | fTraces.add(element); | |
439 | updateConflicts(); | |
440 | } | |
441 | ||
442 | /** | |
443 | * Remove the file to scan | |
444 | * | |
445 | * @param element | |
446 | * the element to remove | |
447 | */ | |
448 | public void removeFileToImport(FileAndName element) { | |
449 | fTraces.remove(element); | |
450 | element.setConflictingName(false); | |
451 | updateConflicts(); | |
452 | } | |
453 | ||
454 | /** | |
455 | * Updates the trace to see if there are conflicts. | |
456 | */ | |
457 | public void updateConflicts() { | |
458 | final FileAndName[] fChildren = fTraces.toArray(new FileAndName[0]); | |
459 | for (int i = 0; i < fChildren.length; i++) { | |
460 | fChildren[i].setConflictingName(false); | |
461 | } | |
462 | for (int i = 1; i < fChildren.length; i++) { | |
463 | for (int j = 0; j < i; j++) { | |
464 | if (fChildren[i].getName().equals(fChildren[j].getName())) { | |
465 | fChildren[i].setConflictingName(true); | |
466 | fChildren[j].setConflictingName(true); | |
467 | } | |
468 | } | |
469 | } | |
470 | getContainer().updateButtons(); | |
471 | } | |
472 | ||
473 | /** | |
474 | * Is there a name conflict | |
475 | */ | |
476 | boolean hasConflicts() { | |
477 | boolean conflict = false; | |
478 | for (FileAndName child : fTraces) { | |
479 | conflict |= child.isConflictingName(); | |
480 | } | |
481 | return conflict; | |
482 | } | |
483 | ||
484 | private boolean executeImportOperation(ImportOperation op) { | |
485 | initializeOperation(op); | |
486 | ||
487 | try { | |
488 | getContainer().run(true, true, op); | |
489 | } catch (InterruptedException e) { | |
490 | return false; | |
491 | } catch (InvocationTargetException e) { | |
4196e938 | 492 | Activator.getDefault().logError(Messages.ImportTraceWizardImportProblem, e); |
d04ec5a7 MK |
493 | return false; |
494 | } | |
495 | ||
496 | IStatus status = op.getStatus(); | |
497 | if (!status.isOK()) { | |
97c6e624 | 498 | ErrorDialog.openError(getContainer().getShell(), Messages.ImportTraceWizardImportProblem, null, status); |
d04ec5a7 MK |
499 | return false; |
500 | } | |
501 | ||
502 | return true; | |
503 | } | |
504 | ||
505 | private static void initializeOperation(ImportOperation op) { | |
506 | op.setCreateContainerStructure(false); | |
507 | op.setOverwriteResources(false); | |
d04ec5a7 MK |
508 | op.setVirtualFolders(false); |
509 | } | |
510 | ||
511 | /** | |
512 | * Override existing resources | |
513 | * | |
514 | * @param selection | |
515 | * true or false | |
516 | */ | |
517 | public void setOverwrite(boolean selection) { | |
518 | fOverwrite = selection; | |
519 | } | |
520 | ||
521 | /** | |
522 | * Is the trace linked? | |
523 | * | |
524 | * @param isLink | |
525 | * true or false | |
526 | */ | |
527 | public void setLinked(boolean isLink) { | |
528 | fLinked = isLink; | |
529 | } | |
530 | ||
531 | /** | |
532 | * @param tracesToScan | |
533 | * sets the common traces to scan | |
534 | */ | |
535 | public void setTracesToScan(BlockingQueue<TraceValidationHelper> tracesToScan) { | |
536 | fTracesToScan = tracesToScan; | |
537 | } | |
538 | ||
539 | /** | |
540 | * @param traceToScan | |
541 | * The trace to scan | |
542 | * @return if the trace has been scanned yet or not | |
543 | */ | |
544 | public boolean hasScanned(TraceValidationHelper traceToScan) { | |
545 | return fResults.containsKey(traceToScan); | |
546 | } | |
547 | ||
548 | /** | |
549 | * Add a result to a cache | |
550 | * | |
551 | * @param traceToScan | |
552 | * The trace that has been scanned | |
553 | * @param validate | |
554 | * if the trace is valid | |
555 | */ | |
556 | public void addResult(TraceValidationHelper traceToScan, boolean validate) { | |
557 | fResults.put(traceToScan, validate); | |
558 | } | |
559 | ||
560 | /** | |
561 | * Gets if the trace has been scanned or not | |
562 | * | |
563 | * @param traceToScan | |
564 | * the scanned trace | |
565 | * @return whether it passes or not | |
566 | */ | |
567 | public Boolean getResult(TraceValidationHelper traceToScan) { | |
568 | return fResults.get(traceToScan); | |
569 | } | |
570 | ||
571 | /** | |
572 | * Returns the amount of files scanned | |
573 | * | |
574 | * @return the amount of files scanned | |
575 | */ | |
576 | public int getNumberOfResults() { | |
577 | return fResults.size(); | |
578 | } | |
579 | ||
9b48d94c MK |
580 | private void updateTracesToScan(final List<String> added) { |
581 | // Treeset is used instead of a hashset since the traces should be read | |
582 | // in the order they were added. | |
507b1336 | 583 | final Set<String> filesToScan = new TreeSet<>(); |
9b48d94c MK |
584 | for (String name : fParentFiles.keySet()) { |
585 | filesToScan.addAll(fParentFiles.get(name)); | |
586 | } | |
587 | IProgressMonitor pm = new NullProgressMonitor(); | |
588 | try { | |
589 | updateScanQueue(pm, filesToScan, added); | |
590 | } catch (InterruptedException e) { | |
591 | } | |
ba486486 | 592 | |
9b48d94c MK |
593 | } |
594 | ||
d04ec5a7 MK |
595 | /* |
596 | * I am a job. Make me work | |
597 | */ | |
91e941e8 | 598 | private synchronized IStatus updateFiles(IProgressMonitor monitor, String traceToScanAbsPath) { |
507b1336 | 599 | final Set<String> filesToScan = new TreeSet<>(); |
9b48d94c | 600 | |
d04ec5a7 | 601 | int workToDo = 1; |
11c9462b | 602 | for (String name : fParentFiles.keySet()) { |
d04ec5a7 MK |
603 | |
604 | final File file = new File(name); | |
605 | final File[] listFiles = file.listFiles(); | |
606 | if (listFiles != null) { | |
607 | workToDo += listFiles.length; | |
608 | } | |
609 | } | |
610 | int step = TOTALWORK / workToDo; | |
611 | try { | |
11c9462b | 612 | for (String name : fParentFiles.keySet()) { |
d04ec5a7 | 613 | final File fileToAdd = new File(name); |
11c9462b MK |
614 | final Set<String> parentFilesToScan = fParentFiles.get(fileToAdd.getAbsolutePath()); |
615 | recurse(parentFilesToScan, fileToAdd, monitor, step); | |
616 | if (monitor.isCanceled()) { | |
91e941e8 MAL |
617 | fParentFilesToScan.remove(traceToScanAbsPath); |
618 | fParentFiles.remove(traceToScanAbsPath); | |
11c9462b MK |
619 | return CANCEL_STATUS; |
620 | } | |
621 | } | |
622 | filesToScan.clear(); | |
623 | for (String name : fParentFiles.keySet()) { | |
624 | filesToScan.addAll(fParentFiles.get(name)); | |
625 | fParentFilesToScan.add(name); | |
d04ec5a7 | 626 | } |
9b48d94c MK |
627 | IStatus cancelled = updateScanQueue(monitor, filesToScan, fTraceTypesToScan); |
628 | if (cancelled.matches(IStatus.CANCEL)) { | |
91e941e8 MAL |
629 | fParentFilesToScan.remove(traceToScanAbsPath); |
630 | fParentFiles.remove(traceToScanAbsPath); | |
d04ec5a7 MK |
631 | } |
632 | } catch (InterruptedException e) { | |
633 | monitor.done(); | |
634 | return new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), e); | |
635 | } | |
636 | ||
637 | monitor.done(); | |
638 | return Status.OK_STATUS; | |
639 | } | |
640 | ||
9b48d94c MK |
641 | private IStatus updateScanQueue(IProgressMonitor monitor, final Set<String> filesToScan, final List<String> traceTypes) throws InterruptedException { |
642 | for (String fileToScan : filesToScan) { | |
643 | for (String traceCat : traceTypes) { | |
644 | TraceValidationHelper tv = new TraceValidationHelper(fileToScan, traceCat); | |
645 | // for thread safety, keep checks in this order. | |
646 | if (!fResults.containsKey(tv)) { | |
647 | if (!fTracesToScan.contains(tv)) { | |
648 | fTracesToScan.put(tv); | |
649 | monitor.subTask(tv.getTraceToScan()); | |
650 | if (monitor.isCanceled()) { | |
ba486486 | 651 | fScanPage.refresh(); |
9b48d94c MK |
652 | return CANCEL_STATUS; |
653 | } | |
654 | } | |
655 | } | |
656 | } | |
657 | } | |
ba486486 | 658 | fScanPage.refresh(); |
9b48d94c MK |
659 | return Status.OK_STATUS; |
660 | } | |
661 | ||
11c9462b | 662 | private IStatus recurse(Set<String> filesToScan, File fileToAdd, IProgressMonitor monitor, int step) { |
d04ec5a7 MK |
663 | final String absolutePath = fileToAdd.getAbsolutePath(); |
664 | if (!filesToScan.contains(absolutePath) && (filesToScan.size() < MAX_FILES)) { | |
665 | filesToScan.add(absolutePath); | |
666 | final File[] listFiles = fileToAdd.listFiles(); | |
667 | if (null != listFiles) { | |
668 | for (File child : listFiles) { | |
669 | monitor.subTask(child.getName()); | |
11c9462b MK |
670 | if (monitor.isCanceled()) { |
671 | return CANCEL_STATUS; | |
672 | } | |
673 | IStatus retVal = recurse(filesToScan, child, monitor); | |
9b48d94c | 674 | if (retVal.matches(IStatus.CANCEL)) { |
11c9462b MK |
675 | return retVal; |
676 | } | |
d04ec5a7 MK |
677 | monitor.worked(step); |
678 | } | |
679 | } | |
680 | } | |
11c9462b | 681 | return Status.OK_STATUS; |
d04ec5a7 MK |
682 | } |
683 | ||
11c9462b | 684 | private IStatus recurse(Set<String> filesToScan, File fileToAdd, IProgressMonitor monitor) { |
d04ec5a7 MK |
685 | final String absolutePath = fileToAdd.getAbsolutePath(); |
686 | if (!filesToScan.contains(absolutePath) && (filesToScan.size() < MAX_FILES)) { | |
687 | filesToScan.add(absolutePath); | |
688 | final File[] listFiles = fileToAdd.listFiles(); | |
689 | if (null != listFiles) { | |
690 | for (File child : listFiles) { | |
11c9462b MK |
691 | if (monitor.isCanceled()) { |
692 | return CANCEL_STATUS; | |
693 | } | |
694 | IStatus retVal = recurse(filesToScan, child, monitor); | |
9b48d94c | 695 | if (retVal.matches(IStatus.CANCEL)) { |
11c9462b MK |
696 | return retVal; |
697 | } | |
d04ec5a7 MK |
698 | } |
699 | } | |
700 | } | |
11c9462b | 701 | return Status.OK_STATUS; |
d04ec5a7 MK |
702 | } |
703 | ||
704 | /** | |
705 | * Gets the folder in the resource (project) | |
706 | * | |
707 | * @param targetFolder | |
708 | * the folder to import to | |
709 | */ | |
710 | public void setTraceFolder(IFolder targetFolder) { | |
711 | fTargetFolder = targetFolder; | |
a2d29ca1 MK |
712 | if (this.getContainer() != null && this.getContainer().getCurrentPage() != null) { |
713 | this.getContainer().updateButtons(); | |
714 | } | |
715 | } | |
716 | ||
717 | /** | |
718 | * Gets the target folder | |
719 | * | |
720 | * @return the target folder | |
721 | */ | |
722 | public IFolder getTargetFolder() { | |
723 | return fTargetFolder; | |
d04ec5a7 MK |
724 | } |
725 | ||
726 | } |