tmf: Rework trace import wizard
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / tmf / ui / project / wizards / importtrace / ImportTraceWizardPage.java
1 /*******************************************************************************
2 * Copyright (c) 2009, 2014 Ericsson and others.
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 * Francois Chouinard - Initial API and implementation
11 * Francois Chouinard - Got rid of dependency on internal platform class
12 * Francois Chouinard - Complete re-design
13 * Anna Dushistova(Montavista) - [383047] NPE while importing a CFT trace
14 * Matthew Khouzam - Moved out some common functions
15 * Patrick Tasse - Add sorting of file system elements
16 * Bernd Hufmann - Re-design of trace selection and trace validation
17 *******************************************************************************/
18
19 package org.eclipse.linuxtools.tmf.ui.project.wizards.importtrace;
20
21 import java.io.File;
22 import java.lang.reflect.InvocationTargetException;
23 import java.text.MessageFormat;
24 import java.util.ArrayList;
25 import java.util.HashMap;
26 import java.util.Iterator;
27 import java.util.List;
28 import java.util.Map;
29
30 import org.eclipse.core.resources.IContainer;
31 import org.eclipse.core.resources.IFolder;
32 import org.eclipse.core.resources.IProject;
33 import org.eclipse.core.resources.IResource;
34 import org.eclipse.core.resources.ResourcesPlugin;
35 import org.eclipse.core.runtime.CoreException;
36 import org.eclipse.core.runtime.IPath;
37 import org.eclipse.core.runtime.IProgressMonitor;
38 import org.eclipse.core.runtime.IStatus;
39 import org.eclipse.core.runtime.NullProgressMonitor;
40 import org.eclipse.core.runtime.Path;
41 import org.eclipse.core.runtime.Platform;
42 import org.eclipse.core.runtime.Status;
43 import org.eclipse.core.runtime.SubMonitor;
44 import org.eclipse.core.runtime.SubProgressMonitor;
45 import org.eclipse.jface.dialogs.IDialogSettings;
46 import org.eclipse.jface.operation.IRunnableWithProgress;
47 import org.eclipse.jface.operation.ModalContext;
48 import org.eclipse.jface.viewers.IStructuredSelection;
49 import org.eclipse.jface.viewers.ITreeContentProvider;
50 import org.eclipse.linuxtools.internal.tmf.ui.Activator;
51 import org.eclipse.linuxtools.tmf.core.TmfCommonConstants;
52 import org.eclipse.linuxtools.tmf.core.TmfProjectNature;
53 import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceImportException;
54 import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceType;
55 import org.eclipse.linuxtools.tmf.core.project.model.TraceTypeHelper;
56 import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectRegistry;
57 import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceFolder;
58 import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceTypeUIUtils;
59 import org.eclipse.linuxtools.tmf.ui.project.wizards.Messages;
60 import org.eclipse.swt.SWT;
61 import org.eclipse.swt.custom.BusyIndicator;
62 import org.eclipse.swt.events.FocusEvent;
63 import org.eclipse.swt.events.FocusListener;
64 import org.eclipse.swt.events.KeyEvent;
65 import org.eclipse.swt.events.KeyListener;
66 import org.eclipse.swt.events.SelectionAdapter;
67 import org.eclipse.swt.events.SelectionEvent;
68 import org.eclipse.swt.events.SelectionListener;
69 import org.eclipse.swt.layout.GridData;
70 import org.eclipse.swt.layout.GridLayout;
71 import org.eclipse.swt.widgets.Button;
72 import org.eclipse.swt.widgets.Combo;
73 import org.eclipse.swt.widgets.Composite;
74 import org.eclipse.swt.widgets.DirectoryDialog;
75 import org.eclipse.swt.widgets.Event;
76 import org.eclipse.swt.widgets.Group;
77 import org.eclipse.swt.widgets.Label;
78 import org.eclipse.ui.IWorkbench;
79 import org.eclipse.ui.dialogs.FileSystemElement;
80 import org.eclipse.ui.dialogs.IOverwriteQuery;
81 import org.eclipse.ui.dialogs.WizardResourceImportPage;
82 import org.eclipse.ui.model.AdaptableList;
83 import org.eclipse.ui.model.WorkbenchContentProvider;
84 import org.eclipse.ui.wizards.datatransfer.FileSystemStructureProvider;
85 import org.eclipse.ui.wizards.datatransfer.IImportStructureProvider;
86 import org.eclipse.ui.wizards.datatransfer.ImportOperation;
87
88 /**
89 * A variant of the standard resource import wizard for importing traces
90 * to given tracing project. If no project or tracing project was selected
91 * the wizard imports it to the default tracing project which is created
92 * if necessary.
93 *
94 * In our case traces could be files or a directory structure. This wizard
95 * supports both cases. It imports traces for a selected trace type or, if
96 * no trace type is selected, it tries to detect the trace type automatically.
97 * However, the automatic detection is a best-effort and cannot guarantee
98 * that the detection is successful. The reason for this is that there might
99 * be multiple trace types that can be assigned to a single trace.
100 *
101 *
102 * @author Francois Chouinard
103 * @since 2.0
104 */
105 public class ImportTraceWizardPage extends WizardResourceImportPage {
106
107 // ------------------------------------------------------------------------
108 // Constants
109 // ------------------------------------------------------------------------
110 private static final String IMPORT_WIZARD_PAGE = "ImportTraceWizardPage"; //$NON-NLS-1$
111 private static final String IMPORT_WIZARD_IMPORT_UNRECOGNIZED_ID = IMPORT_WIZARD_PAGE + ".import_unrecognized_traces_id"; //$NON-NLS-1$
112 private static final String SEPARATOR = ":"; //$NON-NLS-1$
113 private static final String AUTO_DETECT = Messages.ImportTraceWizard_AutoDetection;
114
115 // ------------------------------------------------------------------------
116 // Attributes
117 // ------------------------------------------------------------------------
118
119 // Folder navigation start point (saved between invocations)
120 private static String fRootDirectory = null;
121 // Target import directory ('Traces' folder)
122 private IFolder fTargetFolder;
123 // Flag to handle destination folder change event
124 private Boolean fIsDestinationChanged = false;
125 // Combo box containing trace types
126 private Combo fTraceTypes;
127 // Button to ignore unrecognized traces or not
128 private Button fImportUnrecognizedButton;
129 // Button to overwrite existing resources or not
130 private Button fOverwriteExistingResourcesCheckbox;
131 // Button to link or copy traces to workspace
132 private Button fCreateLinksInWorkspaceButton;
133 private boolean entryChanged = false;
134 /** The directory name field */
135 protected Combo directoryNameField;
136 /** The directory browse button. */
137 protected Button directoryBrowseButton;
138
139 // ------------------------------------------------------------------------
140 // Constructors
141 // ------------------------------------------------------------------------
142
143 /**
144 * Constructor. Creates the trace wizard page.
145 *
146 * @param name
147 * The name of the page.
148 * @param selection
149 * The current selection
150 */
151 protected ImportTraceWizardPage(String name, IStructuredSelection selection) {
152 super(name, selection);
153 }
154
155 /**
156 * Constructor
157 *
158 * @param workbench
159 * The workbench reference.
160 * @param selection
161 * The current selection
162 */
163 public ImportTraceWizardPage(IWorkbench workbench, IStructuredSelection selection) {
164 this(IMPORT_WIZARD_PAGE, selection);
165 setTitle(Messages.ImportTraceWizard_FileSystemTitle);
166 setDescription(Messages.ImportTraceWizard_ImportTrace);
167
168 // Locate the target trace folder
169 IFolder traceFolder = null;
170 Object element = selection.getFirstElement();
171
172 if (element instanceof TmfTraceFolder) {
173 TmfTraceFolder tmfTraceFolder = (TmfTraceFolder) element;
174 tmfTraceFolder.getProject().getResource();
175 traceFolder = tmfTraceFolder.getResource();
176 } else if (element instanceof IProject) {
177 IProject project = (IProject) element;
178 try {
179 if (project.hasNature(TmfProjectNature.ID)) {
180 traceFolder = project.getFolder(TmfTraceFolder.TRACE_FOLDER_NAME);
181 }
182 } catch (CoreException e) {
183 }
184 }
185
186 /*
187 * If no tracing project was selected or trace folder doesn't exist use
188 */
189 if (traceFolder == null) {
190 IProject project = TmfProjectRegistry.createProject(
191 TmfCommonConstants.DEFAULT_TRACE_PROJECT_NAME, null, new NullProgressMonitor());
192 traceFolder = project.getFolder(TmfTraceFolder.TRACE_FOLDER_NAME);
193 }
194
195 // Set the target trace folder
196 if (traceFolder != null) {
197 fTargetFolder = traceFolder;
198 String path = traceFolder.getFullPath().toOSString();
199 setContainerFieldValue(path);
200 }
201 }
202
203 // ------------------------------------------------------------------------
204 // WizardResourceImportPage
205 // ------------------------------------------------------------------------
206
207 @Override
208 public void createControl(Composite parent) {
209 super.createControl(parent);
210 // Restore last directory if applicable
211 if (fRootDirectory != null) {
212 directoryNameField.setText(fRootDirectory);
213 updateFromSourceField();
214 }
215 }
216
217 @Override
218 protected void createSourceGroup(Composite parent) {
219 createDirectorySelectionGroup(parent);
220 createFileSelectionGroup(parent);
221 createTraceTypeGroup(parent);
222 validateSourceGroup();
223 }
224
225 @Override
226 protected ITreeContentProvider getFileProvider() {
227 return new WorkbenchContentProvider() {
228 @Override
229 public Object[] getChildren(Object object) {
230 if (object instanceof TraceFileSystemElement) {
231 TraceFileSystemElement element = (TraceFileSystemElement) object;
232 return element.getFiles().getChildren(element);
233 }
234 return new Object[0];
235 }
236 };
237 }
238
239 @Override
240 protected ITreeContentProvider getFolderProvider() {
241 return new WorkbenchContentProvider() {
242 @Override
243 public Object[] getChildren(Object o) {
244 if (o instanceof TraceFileSystemElement) {
245 TraceFileSystemElement element = (TraceFileSystemElement) o;
246 return element.getFolders().getChildren();
247 }
248 return new Object[0];
249 }
250
251 @Override
252 public boolean hasChildren(Object o) {
253 if (o instanceof TraceFileSystemElement) {
254 TraceFileSystemElement element = (TraceFileSystemElement) o;
255 if (element.isPopulated()) {
256 return getChildren(element).length > 0;
257 }
258 //If we have not populated then wait until asked
259 return true;
260 }
261 return false;
262 }
263 };
264 }
265
266 // ------------------------------------------------------------------------
267 // Directory Selection Group (forked WizardFileSystemResourceImportPage1)
268 // ------------------------------------------------------------------------
269
270 /**
271 * creates the directory selection group.
272 *
273 * @param parent
274 * the parent composite
275 */
276 protected void createDirectorySelectionGroup(Composite parent) {
277
278 Composite directoryContainerGroup = new Composite(parent, SWT.NONE);
279 GridLayout layout = new GridLayout();
280 layout.numColumns = 3;
281 directoryContainerGroup.setLayout(layout);
282 directoryContainerGroup.setFont(parent.getFont());
283 directoryContainerGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
284
285 // Label ("Trace directory:")
286 Label groupLabel = new Label(directoryContainerGroup, SWT.NONE);
287 groupLabel.setText(Messages.ImportTraceWizard_DirectoryLocation);
288 groupLabel.setFont(parent.getFont());
289
290 // Directory name entry field
291 directoryNameField = new Combo(directoryContainerGroup, SWT.BORDER);
292 GridData data = new GridData(SWT.FILL, SWT.FILL, true, false);
293 data.widthHint = SIZING_TEXT_FIELD_WIDTH;
294 directoryNameField.setLayoutData(data);
295 directoryNameField.setFont(parent.getFont());
296
297 directoryNameField.addSelectionListener(new SelectionAdapter() {
298 @Override
299 public void widgetSelected(SelectionEvent e) {
300 updateFromSourceField();
301 }
302 });
303
304 directoryNameField.addKeyListener(new KeyListener() {
305 @Override
306 public void keyPressed(KeyEvent e) {
307 // If there has been a key pressed then mark as dirty
308 entryChanged = true;
309 if (e.character == SWT.CR) { // Windows...
310 entryChanged = false;
311 updateFromSourceField();
312 }
313 }
314
315 @Override
316 public void keyReleased(KeyEvent e) {
317 }
318 });
319
320 directoryNameField.addFocusListener(new FocusListener() {
321 @Override
322 public void focusGained(FocusEvent e) {
323 // Do nothing when getting focus
324 }
325 @Override
326 public void focusLost(FocusEvent e) {
327 // Clear the flag to prevent constant update
328 if (entryChanged) {
329 entryChanged = false;
330 updateFromSourceField();
331 }
332 }
333 });
334
335 // Browse button
336 directoryBrowseButton = new Button(directoryContainerGroup, SWT.PUSH);
337 directoryBrowseButton.setText(Messages.ImportTraceWizard_BrowseButton);
338 directoryBrowseButton.addListener(SWT.Selection, this);
339 directoryBrowseButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
340 directoryBrowseButton.setFont(parent.getFont());
341 setButtonLayoutData(directoryBrowseButton);
342 }
343
344 // ------------------------------------------------------------------------
345 // Browse for the source directory
346 // ------------------------------------------------------------------------
347
348 @Override
349 public void handleEvent(Event event) {
350 if (event.widget == directoryBrowseButton) {
351 handleSourceDirectoryBrowseButtonPressed();
352 }
353
354 // Avoid overwriting destination path without repeatedly trigger
355 // call of handleEvent();
356 synchronized (fIsDestinationChanged) {
357 if (fIsDestinationChanged == false) {
358 event.display.asyncExec(new Runnable() {
359 @Override
360 public void run() {
361 synchronized (fIsDestinationChanged) {
362 fIsDestinationChanged = true;
363 String path = fTargetFolder.getFullPath().toOSString();
364 setContainerFieldValue(path);
365 }
366 }
367 });
368 } else {
369 fIsDestinationChanged = false;
370 }
371 }
372 super.handleEvent(event);
373 }
374
375 @Override
376 protected void handleContainerBrowseButtonPressed() {
377 // Do nothing so that destination directory cannot be changed.
378 }
379
380 /**
381 * Handle the button pressed event
382 */
383 protected void handleSourceDirectoryBrowseButtonPressed() {
384 String currentSource = directoryNameField.getText();
385 DirectoryDialog dialog = new DirectoryDialog(directoryNameField.getShell(), SWT.SAVE | SWT.SHEET);
386 dialog.setText(Messages.ImportTraceWizard_SelectTraceDirectoryTitle);
387 dialog.setMessage(Messages.ImportTraceWizard_SelectTraceDirectoryMessage);
388 dialog.setFilterPath(getSourceDirectoryName(currentSource));
389
390 String selectedDirectory = dialog.open();
391 if (selectedDirectory != null) {
392 // Just quit if the directory is not valid
393 if ((getSourceDirectory(selectedDirectory) == null) || selectedDirectory.equals(currentSource)) {
394 return;
395 }
396 // If it is valid then proceed to populate
397 setErrorMessage(null);
398 setSourceName(selectedDirectory);
399 }
400 }
401
402 private File getSourceDirectory() {
403 return getSourceDirectory(directoryNameField.getText());
404 }
405
406 private static File getSourceDirectory(String path) {
407 File sourceDirectory = new File(getSourceDirectoryName(path));
408 if (!sourceDirectory.exists() || !sourceDirectory.isDirectory()) {
409 return null;
410 }
411
412 return sourceDirectory;
413 }
414
415 private static String getSourceDirectoryName(String sourceName) {
416 IPath result = new Path(sourceName.trim());
417 if (result.getDevice() != null && result.segmentCount() == 0) {
418 result = result.addTrailingSeparator();
419 } else {
420 result = result.removeTrailingSeparator();
421 }
422 return result.toOSString();
423 }
424
425 private String getSourceDirectoryName() {
426 return getSourceDirectoryName(directoryNameField.getText());
427 }
428
429 private void updateFromSourceField() {
430 setSourceName(directoryNameField.getText());
431 updateWidgetEnablements();
432 }
433
434 private void setSourceName(String path) {
435 if (path.length() > 0) {
436 String[] currentItems = directoryNameField.getItems();
437 int selectionIndex = -1;
438 for (int i = 0; i < currentItems.length; i++) {
439 if (currentItems[i].equals(path)) {
440 selectionIndex = i;
441 }
442 }
443 if (selectionIndex < 0) {
444 int oldLength = currentItems.length;
445 String[] newItems = new String[oldLength + 1];
446 System.arraycopy(currentItems, 0, newItems, 0, oldLength);
447 newItems[oldLength] = path;
448 directoryNameField.setItems(newItems);
449 selectionIndex = oldLength;
450 }
451 directoryNameField.select(selectionIndex);
452 }
453 resetSelection();
454 }
455
456 // ------------------------------------------------------------------------
457 // File Selection Group (forked WizardFileSystemResourceImportPage1)
458 // ------------------------------------------------------------------------
459 private void resetSelection() {
460 TraceFileSystemElement root = getFileSystemTree();
461 selectionGroup.setRoot(root);
462 }
463
464 private TraceFileSystemElement getFileSystemTree() {
465 File sourceDirectory = getSourceDirectory();
466 if (sourceDirectory == null) {
467 return null;
468 }
469 return selectFiles(sourceDirectory, FileSystemStructureProvider.INSTANCE);
470 }
471
472 private TraceFileSystemElement selectFiles(final Object rootFileSystemObject,
473 final IImportStructureProvider structureProvider) {
474 final TraceFileSystemElement[] results = new TraceFileSystemElement[1];
475 BusyIndicator.showWhile(getShell().getDisplay(), new Runnable() {
476 @Override
477 public void run() {
478 // Create the root element from the supplied file system object
479 results[0] = createRootElement(rootFileSystemObject, structureProvider);
480 }
481 });
482 return results[0];
483 }
484
485 private static TraceFileSystemElement createRootElement(Object fileSystemObject,
486 IImportStructureProvider provider) {
487
488 boolean isContainer = provider.isFolder(fileSystemObject);
489 String elementLabel = provider.getLabel(fileSystemObject);
490
491 // Use an empty label so that display of the element's full name
492 // doesn't include a confusing label
493 TraceFileSystemElement dummyParent = new TraceFileSystemElement("", null, true);//$NON-NLS-1$
494 dummyParent.setPopulated();
495 TraceFileSystemElement result = new TraceFileSystemElement(
496 elementLabel, dummyParent, isContainer);
497 result.setFileSystemObject(fileSystemObject);
498
499 //Get the files for the element so as to build the first level
500 result.getFiles();
501
502 return dummyParent;
503 }
504
505 // ------------------------------------------------------------------------
506 // Trace Type Group
507 // ------------------------------------------------------------------------
508 private final void createTraceTypeGroup(Composite parent) {
509 Composite composite = new Composite(parent, SWT.NONE);
510 GridLayout layout = new GridLayout();
511 layout.numColumns = 3;
512 layout.makeColumnsEqualWidth = false;
513 composite.setLayout(layout);
514 composite.setFont(parent.getFont());
515 GridData buttonData = new GridData(SWT.FILL, SWT.FILL, true, false);
516 composite.setLayoutData(buttonData);
517
518 // Trace type label ("Trace Type:")
519 Label typeLabel = new Label(composite, SWT.NONE);
520 typeLabel.setText(Messages.ImportTraceWizard_TraceType);
521 typeLabel.setFont(parent.getFont());
522
523 // Trace type combo
524 fTraceTypes = new Combo(composite, SWT.BORDER | SWT.READ_ONLY);
525 GridData data = new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1);
526 fTraceTypes.setLayoutData(data);
527 fTraceTypes.setFont(parent.getFont());
528
529 String[] availableTraceTypes = TmfTraceType.getInstance().getAvailableTraceTypes();
530 String[] traceTypeList = new String[availableTraceTypes.length + 1];
531 traceTypeList[0] = AUTO_DETECT;
532 for (int i = 0; i < availableTraceTypes.length; i++) {
533 traceTypeList[i + 1] = availableTraceTypes[i];
534 }
535 fTraceTypes.setItems(traceTypeList);
536 fTraceTypes.addSelectionListener(new SelectionListener() {
537 @Override
538 public void widgetSelected(SelectionEvent e) {
539 updateWidgetEnablements();
540 }
541
542 @Override
543 public void widgetDefaultSelected(SelectionEvent e) {
544 }
545 });
546 fTraceTypes.select(0);
547
548 fImportUnrecognizedButton = new Button(composite, SWT.CHECK);
549 fImportUnrecognizedButton.setSelection(true);
550 fImportUnrecognizedButton.setText(Messages.ImportTraceWizard_ImportUnrecognized);
551
552 IDialogSettings settings = getDialogSettings();
553 boolean value;
554 if (settings.get(IMPORT_WIZARD_IMPORT_UNRECOGNIZED_ID) == null) {
555 value = true;
556 } else {
557 value = settings.getBoolean(IMPORT_WIZARD_IMPORT_UNRECOGNIZED_ID);
558 }
559 fImportUnrecognizedButton.setSelection(value);
560 }
561
562 // ------------------------------------------------------------------------
563 // Options
564 // ------------------------------------------------------------------------
565
566 @Override
567 protected void createOptionsGroupButtons(Group optionsGroup) {
568
569 // Overwrite checkbox
570 fOverwriteExistingResourcesCheckbox = new Button(optionsGroup, SWT.CHECK);
571 fOverwriteExistingResourcesCheckbox.setFont(optionsGroup.getFont());
572 fOverwriteExistingResourcesCheckbox.setText(Messages.ImportTraceWizard_OverwriteExistingTrace);
573 fOverwriteExistingResourcesCheckbox.setSelection(false);
574
575 // Create links checkbox
576 fCreateLinksInWorkspaceButton = new Button(optionsGroup, SWT.CHECK);
577 fCreateLinksInWorkspaceButton.setFont(optionsGroup.getFont());
578 fCreateLinksInWorkspaceButton.setText(Messages.ImportTraceWizard_CreateLinksInWorkspace);
579 fCreateLinksInWorkspaceButton.setSelection(true);
580
581 fCreateLinksInWorkspaceButton.addSelectionListener(new SelectionAdapter() {
582 @Override
583 public void widgetSelected(SelectionEvent e) {
584 updateWidgetEnablements();
585 }
586 });
587
588 updateWidgetEnablements();
589 }
590
591 // ------------------------------------------------------------------------
592 // Determine if the finish button can be enabled
593 // ------------------------------------------------------------------------
594
595 @Override
596 public boolean validateSourceGroup() {
597
598 File sourceDirectory = getSourceDirectory();
599 if (sourceDirectory == null) {
600 setMessage(Messages.ImportTraceWizard_SelectTraceSourceEmpty);
601 return false;
602 }
603
604 if (sourceConflictsWithDestination(new Path(sourceDirectory.getPath()))) {
605 setMessage(null);
606 setErrorMessage(getSourceConflictMessage());
607 return false;
608 }
609
610 List<FileSystemElement> resourcesToImport = getSelectedResources();
611 if (resourcesToImport.size() == 0) {
612 setMessage(null);
613 setErrorMessage(Messages.ImportTraceWizard_SelectTraceNoneSelected);
614 return false;
615 }
616
617 IContainer container = getSpecifiedContainer();
618 if (container != null && container.isVirtual()) {
619 if (Platform.getPreferencesService().getBoolean(Activator.PLUGIN_ID, ResourcesPlugin.PREF_DISABLE_LINKING, false, null)) {
620 setMessage(null);
621 setErrorMessage(Messages.ImportTraceWizard_CannotImportFilesUnderAVirtualFolder);
622 return false;
623 }
624 if (fCreateLinksInWorkspaceButton == null || !fCreateLinksInWorkspaceButton.getSelection()) {
625 setMessage(null);
626 setErrorMessage(Messages.ImportTraceWizard_HaveToCreateLinksUnderAVirtualFolder);
627 return false;
628 }
629 }
630
631 setErrorMessage(null);
632 return true;
633 }
634
635 // ------------------------------------------------------------------------
636 // Import the trace(s)
637 // ------------------------------------------------------------------------
638
639 /**
640 * Finish the import.
641 *
642 * @return <code>true</code> if successful else <code>false</code>
643 */
644 public boolean finish() {
645 IDialogSettings settings = getDialogSettings();
646 settings.put(IMPORT_WIZARD_IMPORT_UNRECOGNIZED_ID, fImportUnrecognizedButton.getSelection());
647
648 String traceTypeName = fTraceTypes.getText();
649 String traceId = null;
650 if (!AUTO_DETECT.equals(traceTypeName)) {
651 String tokens[] = traceTypeName.split(SEPARATOR, 2);
652 if (tokens.length < 2) {
653 return false;
654 }
655 traceId = TmfTraceType.getInstance().getTraceTypeId(tokens[0], tokens[1]);
656 }
657
658 // Save directory for next import operation
659 fRootDirectory = getSourceDirectoryName();
660
661 final TraceValidateAndImportOperation operation = new TraceValidateAndImportOperation(traceId, getContainerFullPath(),
662 fImportUnrecognizedButton.getSelection(), fOverwriteExistingResourcesCheckbox.getSelection(), fCreateLinksInWorkspaceButton.getSelection());
663
664 IStatus status = Status.OK_STATUS;
665 try {
666 getContainer().run(true, true, new IRunnableWithProgress() {
667 @Override
668 public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
669 operation.run(monitor);
670 monitor.done();
671 }
672 });
673
674 status = operation.getStatus();
675 } catch (InvocationTargetException e) {
676 status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.ImportTraceWizard_ImportProblem, e);
677 } catch (InterruptedException e) {
678 status = Status.CANCEL_STATUS;
679 } finally {
680 if (!status.isOK()) {
681 if (status.getSeverity() == IStatus.CANCEL) {
682 setMessage(Messages.ImportTraceWizard_ImportOperationCancelled);
683 setErrorMessage(null);
684 } else {
685 if (status.getException() != null) {
686 displayErrorDialog(status.getMessage() + ": " + status.getException()); //$NON-NLS-1$
687 }
688 setMessage(null);
689 setErrorMessage(Messages.ImportTraceWizard_ImportProblem);
690 }
691 return false;
692 }
693 }
694 if (operation.getUnrecognizedTraces().size() > 0) {
695 StringBuilder unrecognizedTraces = new StringBuilder();
696 for(String trace: operation.getUnrecognizedTraces()) {
697 unrecognizedTraces.append(System.getProperty("line.separator")).append(trace); //$NON-NLS-1$
698 }
699 displayErrorDialog(Messages.ImportTraceWizard_NoValidTraceTypeFound + ":" + unrecognizedTraces.toString()); //$NON-NLS-1$
700 }
701 setErrorMessage(null);
702 return true;
703 }
704
705
706 // ------------------------------------------------------------------------
707 // Classes
708 // ------------------------------------------------------------------------
709
710 class TraceValidateAndImportOperation {
711 private IStatus fStatus;
712 final List<String> fUnrecognizedResources = new ArrayList<>();
713 private String fTraceType;
714 private IPath fContainerPath;
715 private boolean fImportUnrecognizedTraces;
716 private boolean fOverwrite;
717 private boolean fLink;
718
719 TraceValidateAndImportOperation(String traceId, IPath containerPath, boolean doImport, boolean overwrite, boolean link) {
720 fTraceType = traceId;
721 fContainerPath = containerPath;
722 fImportUnrecognizedTraces = doImport;
723 fOverwrite = overwrite;
724 fLink = link;
725 }
726
727 public void run(IProgressMonitor progressMonitor) {
728 String currentPath = null;
729 final Map<String, FileSystemElement> folderResources = new HashMap<>();
730 try {
731 List<FileSystemElement> resources = getSelectedResources();
732 Iterator<FileSystemElement> resourcesEnum = resources.iterator();
733 SubMonitor subMonitor = SubMonitor.convert(progressMonitor, resources.size());
734 // subMonitor.beginTask("Importing: ", resources.size());
735
736 while (resourcesEnum.hasNext()) {
737 ModalContext.checkCanceled(progressMonitor);
738 currentPath = null;
739 FileSystemElement resource = resourcesEnum.next();
740 File resourceFile = (File) resource.getFileSystemObject();
741 String resourcePath = resourceFile.getAbsolutePath();
742 currentPath = resourcePath;
743 SubMonitor sub = subMonitor.newChild(1);
744 if (resource.isDirectory()) {
745 if (!folderResources.containsKey(resourcePath)) {
746 if (isDirectoryTrace(resource)) {
747 folderResources.put(resourcePath, resource);
748 validateAndImportDirectoryTrace(resource, sub);
749 }
750 }
751 } else {
752 FileSystemElement parent = resource.getParent();
753 File file = (File) parent.getFileSystemObject();
754 String parentPath = file.getAbsolutePath();
755 currentPath = parentPath;
756 if (!folderResources.containsKey(parentPath)) {
757 if (isDirectoryTrace(parent)) {
758 folderResources.put(parentPath, parent);
759 validateAndImportDirectoryTrace(parent, sub);
760 } else {
761 if (resourceFile.exists()) {
762 validateAndImportFileTrace(resource, sub);
763 }
764 }
765 }
766 }
767 }
768 setStatus(Status.OK_STATUS);
769 } catch (InterruptedException e) {
770 setStatus(Status.CANCEL_STATUS);
771 } catch (Exception e) {
772 setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.ImportTraceWizard_ImportProblem + ": " + //$NON-NLS-1$
773 (currentPath != null ? currentPath : "") , e)); //$NON-NLS-1$
774 }
775 }
776
777 /**
778 * @return a list of trace file names for that no trace type could be detected.
779 */
780 public List<String> getUnrecognizedTraces() {
781 return new ArrayList<>(fUnrecognizedResources);
782 }
783
784 private void validateAndImportDirectoryTrace(FileSystemElement resource, IProgressMonitor monitor)
785 throws TmfTraceImportException, CoreException, InvocationTargetException, InterruptedException {
786 File file = (File) resource.getFileSystemObject();
787 String path = file.getAbsolutePath();
788 TraceTypeHelper traceTypeHelper;
789 boolean sendValidationError = true;
790 if (fTraceType == null) {
791 traceTypeHelper = TmfTraceTypeUIUtils.selectTraceType(path, null, null);
792 } else {
793 if (!TmfTraceType.getInstance().isDirectoryTraceType(fTraceType)) {
794 return;
795 }
796 sendValidationError = false;
797 traceTypeHelper = TmfTraceType.getInstance().getTraceType(fTraceType);
798 }
799 validateAndImportTrace(file, traceTypeHelper, sendValidationError, monitor);
800 }
801
802 private void validateAndImportFileTrace(FileSystemElement resource, IProgressMonitor monitor)
803 throws TmfTraceImportException, CoreException, InvocationTargetException, InterruptedException {
804
805 File file = (File) resource.getFileSystemObject();
806 String path = file.getAbsolutePath();
807 TraceTypeHelper traceTypeHelper = null;
808 boolean sendValidationError = true;
809 if (fTraceType == null) {
810 // TODO add automatic trace type selection for trace file
811 if (fImportUnrecognizedTraces) {
812 importResource(file, monitor);
813 fUnrecognizedResources.add(path);
814 }
815 return;
816 }
817
818 if (TmfTraceType.getInstance().isDirectoryTraceType(fTraceType)) {
819 return;
820 }
821 sendValidationError = false;
822 traceTypeHelper = TmfTraceType.getInstance().getTraceType(fTraceType);
823 validateAndImportTrace(file, traceTypeHelper, sendValidationError, monitor);
824 return;
825 }
826
827 private void validateAndImportTrace(File file, TraceTypeHelper traceTypeHelper, boolean sendValidationError, IProgressMonitor monitor)
828 throws InvocationTargetException, InterruptedException, CoreException, TmfTraceImportException {
829
830 if (traceTypeHelper == null) {
831 throw new TmfTraceImportException(Messages.ImportTraceWizard_TraceTypeNotFound);
832 }
833
834 String path = file.getAbsolutePath();
835
836 if (TmfTraceType.getInstance().validate(traceTypeHelper.getCanonicalName(), path)) {
837 importResource(file, monitor);
838 IResource eclipseResource = fTargetFolder.findMember(file.getName());
839 TmfTraceTypeUIUtils.setTraceType(eclipseResource.getFullPath(), traceTypeHelper);
840 return;
841 }
842 if (sendValidationError) {
843 throw new TmfTraceImportException(MessageFormat.format(Messages.ImportTraceWizard_TraceValidationFailed, path));
844 }
845 }
846
847 private void importResource(File fileSystemObject, IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
848 File parentFolder = new File(fileSystemObject.getParent());
849 List<File> subList = new ArrayList<>();
850 subList.add(fileSystemObject);
851 FileSystemStructureProvider fileSystemStructureProvider = FileSystemStructureProvider.INSTANCE;
852
853 // TODO have own IOverwriteQuery implementation for proper handling of overwrite and renaming
854 IOverwriteQuery myQueryImpl = new IOverwriteQuery() {
855 @Override
856 public String queryOverwrite(String file) {
857 return fOverwrite ? IOverwriteQuery.ALL : IOverwriteQuery.NO_ALL;
858 }
859 };
860
861 monitor.setTaskName(Messages.ImportTraceWizard_ImportOperationTaskName + " " + fileSystemObject.getAbsolutePath()); //$NON-NLS-1$
862 ImportOperation operation = new ImportOperation(fContainerPath, parentFolder, fileSystemStructureProvider, myQueryImpl, subList);
863 operation.setContext(getShell());
864
865 operation.setCreateContainerStructure(false);
866 operation.setOverwriteResources(fOverwrite);
867 operation.setCreateLinks(fLink);
868 operation.setVirtualFolders(false);
869
870 operation.run(new SubProgressMonitor(monitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK));
871 }
872
873 private boolean isDirectoryTrace(FileSystemElement resource) {
874 File file = (File) resource.getFileSystemObject();
875 String path = file.getAbsolutePath();
876 if (TmfTraceType.getInstance().isDirectoryTrace(path)) {
877 return true;
878 }
879 return false;
880 }
881
882 /**
883 * Set the status for this operation
884 *
885 * @param status
886 * the status
887 */
888 protected void setStatus(IStatus status) {
889 fStatus = status;
890 }
891
892 public IStatus getStatus() {
893 return fStatus;
894 }
895 }
896
897 /**
898 * The <code>TraceFileSystemElement</code> is a <code>FileSystemElement</code> that knows
899 * if it has been populated or not.
900 */
901 static class TraceFileSystemElement extends FileSystemElement {
902
903 private boolean populated = false;
904
905 public TraceFileSystemElement(String name, FileSystemElement parent, boolean isDirectory) {
906 super(name, parent, isDirectory);
907 }
908
909 public void setPopulated() {
910 populated = true;
911 }
912
913 public boolean isPopulated() {
914 return populated;
915 }
916
917 @Override
918 public AdaptableList getFiles() {
919 if(!populated) {
920 populateElementChildren();
921 }
922 return super.getFiles();
923 }
924
925 @Override
926 public AdaptableList getFolders() {
927 if(!populated) {
928 populateElementChildren();
929 }
930 return super.getFolders();
931 }
932
933 /**
934 * Populates the children of the specified parent <code>FileSystemElement</code>
935 */
936 private void populateElementChildren() {
937 FileSystemStructureProvider provider = FileSystemStructureProvider.INSTANCE;
938 List<File> allchildren = provider.getChildren(this.getFileSystemObject());
939 File child = null;
940 TraceFileSystemElement newelement = null;
941 Iterator<File> iter = allchildren.iterator();
942 while(iter.hasNext()) {
943 child = iter.next();
944 newelement = new TraceFileSystemElement(provider.getLabel(child), this, provider.isFolder(child));
945 newelement.setFileSystemObject(child);
946 }
947 setPopulated();
948 }
949 }
950 }
This page took 0.052588 seconds and 5 git commands to generate.