tmf: Bug 476551: Omit empty traces in standard import and remote fetch
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / internal / tmf / ui / project / wizards / importtrace / ImportTraceWizardPage.java
1 /*******************************************************************************
2 * Copyright (c) 2009, 2015 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 * Marc-Andre Laperle - Preserve folder structure on import
18 * Marc-Andre Laperle - Extract archives during import
19 * Marc-Andre Laperle - Add support for Gzip (non-Tar)
20 *******************************************************************************/
21
22 package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace;
23
24 import java.io.File;
25 import java.lang.reflect.InvocationTargetException;
26 import java.util.Collection;
27 import java.util.LinkedList;
28 import java.util.List;
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.ResourcesPlugin;
34 import org.eclipse.core.runtime.CoreException;
35 import org.eclipse.core.runtime.IPath;
36 import org.eclipse.core.runtime.IProgressMonitor;
37 import org.eclipse.core.runtime.IStatus;
38 import org.eclipse.core.runtime.NullProgressMonitor;
39 import org.eclipse.core.runtime.Path;
40 import org.eclipse.core.runtime.Platform;
41 import org.eclipse.core.runtime.Status;
42 import org.eclipse.core.runtime.SubMonitor;
43 import org.eclipse.jface.dialogs.IDialogSettings;
44 import org.eclipse.jface.layout.PixelConverter;
45 import org.eclipse.jface.operation.IRunnableWithProgress;
46 import org.eclipse.jface.viewers.CheckStateChangedEvent;
47 import org.eclipse.jface.viewers.ICheckStateListener;
48 import org.eclipse.jface.viewers.IStructuredSelection;
49 import org.eclipse.jface.viewers.ITreeContentProvider;
50 import org.eclipse.swt.SWT;
51 import org.eclipse.swt.custom.BusyIndicator;
52 import org.eclipse.swt.events.FocusAdapter;
53 import org.eclipse.swt.events.FocusEvent;
54 import org.eclipse.swt.events.ModifyEvent;
55 import org.eclipse.swt.events.ModifyListener;
56 import org.eclipse.swt.events.SelectionAdapter;
57 import org.eclipse.swt.events.SelectionEvent;
58 import org.eclipse.swt.events.TraverseEvent;
59 import org.eclipse.swt.events.TraverseListener;
60 import org.eclipse.swt.layout.GridData;
61 import org.eclipse.swt.layout.GridLayout;
62 import org.eclipse.swt.widgets.Button;
63 import org.eclipse.swt.widgets.Combo;
64 import org.eclipse.swt.widgets.Composite;
65 import org.eclipse.swt.widgets.DirectoryDialog;
66 import org.eclipse.swt.widgets.Event;
67 import org.eclipse.swt.widgets.FileDialog;
68 import org.eclipse.swt.widgets.Group;
69 import org.eclipse.swt.widgets.Label;
70 import org.eclipse.tracecompass.internal.tmf.ui.Activator;
71 import org.eclipse.tracecompass.tmf.core.TmfCommonConstants;
72 import org.eclipse.tracecompass.tmf.core.TmfProjectNature;
73 import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType;
74 import org.eclipse.tracecompass.tmf.core.util.Pair;
75 import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectElement;
76 import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectRegistry;
77 import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder;
78 import org.eclipse.tracecompass.tmf.ui.project.model.TmfTracesFolder;
79 import org.eclipse.ui.dialogs.FileSystemElement;
80 import org.eclipse.ui.dialogs.WizardResourceImportPage;
81 import org.eclipse.ui.ide.dialogs.IElementFilter;
82 import org.eclipse.ui.ide.dialogs.ResourceTreeAndListGroup;
83 import org.eclipse.ui.internal.ide.DialogUtil;
84 import org.eclipse.ui.model.WorkbenchContentProvider;
85 import org.eclipse.ui.model.WorkbenchLabelProvider;
86 import org.eclipse.ui.model.WorkbenchViewerComparator;
87
88 /**
89 * A variant of the standard resource import wizard for importing traces to
90 * given tracing project. If no project or tracing project was selected the
91 * wizard imports it to the default tracing project which is created if
92 * 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 no
96 * trace type is selected, it tries to detect the trace type automatically.
97 * However, the automatic detection is a best-effort and cannot guarantee that
98 * the detection is successful. The reason for this is that there might be
99 * multiple trace types that can be assigned to a single trace.
100 *
101 *
102 * @author Francois Chouinard
103 */
104 @SuppressWarnings("restriction")
105 public class ImportTraceWizardPage extends WizardResourceImportPage {
106
107 // ------------------------------------------------------------------------
108 // Constants
109 // ------------------------------------------------------------------------
110 private static final String IMPORT_WIZARD_PAGE_NAME = "ImportTraceWizardPage"; //$NON-NLS-1$
111 private static final String IMPORT_WIZARD_ROOT_DIRECTORY_ID = ".import_root_directory_id"; //$NON-NLS-1$;
112 private static final String IMPORT_WIZARD_ARCHIVE_FILE_NAME_ID = ".import_archive_file_name_id"; //$NON-NLS-1$
113 private static final String IMPORT_WIZARD_IMPORT_UNRECOGNIZED_ID = ".import_unrecognized_traces_id"; //$NON-NLS-1$
114 private static final String IMPORT_WIZARD_PRESERVE_FOLDERS_ID = ".import_preserve_folders_id"; //$NON-NLS-1$
115 private static final String IMPORT_WIZARD_IMPORT_FROM_DIRECTORY_ID = ".import_from_directory"; //$NON-NLS-1$
116
117 // constant from WizardArchiveFileResourceImportPage1
118 private static final String[] FILE_IMPORT_MASK = { "*.jar;*.zip;*.tar;*.tar.gz;*.tgz;*.gz", "*.*" }; //$NON-NLS-1$ //$NON-NLS-2$
119
120 /**
121 * A special trace type value to communicate that automatic trace type
122 * detection will occur instead of setting a specific trace type when
123 * importing the traces.
124 */
125 public static final String TRACE_TYPE_AUTO_DETECT = Messages.ImportTraceWizard_AutoDetection;
126
127 /**
128 * Preserve the folder structure of the import traces.
129 */
130 public static final int OPTION_PRESERVE_FOLDER_STRUCTURE = 1 << 1;
131 /**
132 * Create links to the trace files instead of copies.
133 */
134 public static final int OPTION_CREATE_LINKS_IN_WORKSPACE = 1 << 2;
135 /**
136 * Import files that were not recognized as the selected trace type.
137 */
138 public static final int OPTION_IMPORT_UNRECOGNIZED_TRACES = 1 << 3;
139 /**
140 * Overwrite existing resources without prompting.
141 */
142 public static final int OPTION_OVERWRITE_EXISTING_RESOURCES = 1 << 4;
143
144 // ------------------------------------------------------------------------
145 // Attributes
146 // ------------------------------------------------------------------------
147
148 // Target import directory ('Traces' folder)
149 private IFolder fTargetFolder;
150 // Target Trace folder element
151 private TmfTraceFolder fTraceFolderElement;
152 // Flag to handle destination folder change event
153 private Boolean fIsDestinationChanged = false;
154 private final Object fSyncObject = new Object();
155 // Combo box containing trace types
156 private Combo fTraceTypes;
157 // Button to ignore unrecognized traces or not
158 private Button fImportUnrecognizedButton;
159 // Button to overwrite existing resources or not
160 private Button fOverwriteExistingResourcesCheckbox;
161 // Button to link or copy traces to workspace
162 private Button fCreateLinksInWorkspaceButton;
163 // Button to preserve folder structure
164 private Button fPreserveFolderStructureButton;
165 private boolean entryChanged = false;
166 // The import from directory radio button
167 private Button fImportFromDirectoryRadio;
168 // The import from archive radio button
169 private Button fImportFromArchiveRadio;
170 // Flag to remember the "create links" checkbox when it gets disabled by
171 // the import from archive radio button
172 private Boolean fPreviousCreateLinksValue = true;
173
174 /** The archive name field */
175 protected Combo fArchiveNameField;
176 /** The archive browse button. */
177 protected Button fArchiveBrowseButton;
178 /** The directory name field */
179 protected Combo directoryNameField;
180 /** The directory browse button. */
181 protected Button directoryBrowseButton;
182
183 private ResourceTreeAndListGroup fSelectionGroup;
184
185 // Keep trace of the selection root so that we can dispose its related
186 // resources
187 private TraceFileSystemElement fSelectionGroupRoot;
188
189 // ------------------------------------------------------------------------
190 // Constructors
191 // ------------------------------------------------------------------------
192
193 /**
194 * Constructor. Creates the trace wizard page.
195 *
196 * @param name
197 * The name of the page.
198 * @param selection
199 * The current selection
200 */
201 protected ImportTraceWizardPage(String name, IStructuredSelection selection) {
202 super(name, selection);
203 setTitle(Messages.ImportTraceWizard_FileSystemTitle);
204 setDescription(Messages.ImportTraceWizard_ImportTrace);
205
206 // Locate the target trace folder
207 IFolder traceFolder = null;
208 Object element = selection.getFirstElement();
209
210 if (element instanceof TmfTraceFolder) {
211 fTraceFolderElement = (TmfTraceFolder) element;
212 traceFolder = fTraceFolderElement.getResource();
213 } else if (element instanceof IProject) {
214 IProject project = (IProject) element;
215 try {
216 if (project.hasNature(TmfProjectNature.ID)) {
217 TmfProjectElement projectElement = TmfProjectRegistry.getProject(project, true);
218 fTraceFolderElement = projectElement.getTracesFolder();
219 traceFolder = project.getFolder(TmfTracesFolder.TRACES_FOLDER_NAME);
220 }
221 } catch (CoreException e) {
222 }
223 }
224
225 // If no tracing project was selected or trace folder doesn't exist use
226 // default tracing project
227 if (traceFolder == null) {
228 IProject project = TmfProjectRegistry.createProject(
229 TmfCommonConstants.DEFAULT_TRACE_PROJECT_NAME, null, new NullProgressMonitor());
230 TmfProjectElement projectElement = TmfProjectRegistry.getProject(project, true);
231 fTraceFolderElement = projectElement.getTracesFolder();
232 traceFolder = project.getFolder(TmfTracesFolder.TRACES_FOLDER_NAME);
233 }
234
235 // Set the target trace folder
236 if (traceFolder != null) {
237 fTargetFolder = traceFolder;
238 String path = traceFolder.getFullPath().toString();
239 setContainerFieldValue(path);
240 }
241 }
242
243 /**
244 * Constructor
245 *
246 * @param selection
247 * The current selection
248 */
249 public ImportTraceWizardPage(IStructuredSelection selection) {
250 this(IMPORT_WIZARD_PAGE_NAME, selection);
251 }
252
253 /**
254 * Create the import source selection widget. (Copied from
255 * WizardResourceImportPage but instead always uses the internal
256 * ResourceTreeAndListGroup to keep compatibility with Kepler)
257 */
258 @Override
259 protected void createFileSelectionGroup(Composite parent) {
260
261 // Just create with a dummy root.
262 fSelectionGroup = new ResourceTreeAndListGroup(parent,
263 new FileSystemElement("Dummy", null, true),//$NON-NLS-1$
264 getFolderProvider(), new WorkbenchLabelProvider(),
265 getFileProvider(), new WorkbenchLabelProvider(), SWT.NONE,
266 DialogUtil.inRegularFontMode(parent));
267
268 ICheckStateListener listener = new ICheckStateListener() {
269 @Override
270 public void checkStateChanged(CheckStateChangedEvent event) {
271 updateWidgetEnablements();
272 }
273 };
274
275 WorkbenchViewerComparator comparator = new WorkbenchViewerComparator();
276 fSelectionGroup.setTreeComparator(comparator);
277 fSelectionGroup.setListComparator(comparator);
278 fSelectionGroup.addCheckStateListener(listener);
279
280 }
281
282 // ------------------------------------------------------------------------
283 // WizardResourceImportPage
284 // ------------------------------------------------------------------------
285
286 @Override
287 protected void createSourceGroup(Composite parent) {
288 createSourceSelectionGroup(parent);
289 createFileSelectionGroup(parent);
290 createTraceTypeGroup(parent);
291 validateSourceGroup();
292 }
293
294 @Override
295 protected ITreeContentProvider getFileProvider() {
296 return new WorkbenchContentProvider() {
297 @Override
298 public Object[] getChildren(Object object) {
299 if (object instanceof TraceFileSystemElement) {
300 TraceFileSystemElement element = (TraceFileSystemElement) object;
301 return element.getFiles().getChildren(element);
302 }
303 return new Object[0];
304 }
305 };
306 }
307
308 @Override
309 protected ITreeContentProvider getFolderProvider() {
310 return new WorkbenchContentProvider() {
311 @Override
312 public Object[] getChildren(Object o) {
313 if (o instanceof TraceFileSystemElement) {
314 TraceFileSystemElement element = (TraceFileSystemElement) o;
315 return element.getFolders().getChildren();
316 }
317 return new Object[0];
318 }
319
320 @Override
321 public boolean hasChildren(Object o) {
322 if (o instanceof TraceFileSystemElement) {
323 TraceFileSystemElement element = (TraceFileSystemElement) o;
324 if (element.isPopulated()) {
325 return getChildren(element).length > 0;
326 }
327 // If we have not populated then wait until asked
328 return true;
329 }
330 return false;
331 }
332 };
333 }
334
335 // ------------------------------------------------------------------------
336 // Directory Selection Group (forked WizardFileSystemResourceImportPage1)
337 // ------------------------------------------------------------------------
338
339 /**
340 * creates the source selection group.
341 *
342 * @param parent
343 * the parent composite
344 */
345 protected void createSourceSelectionGroup(Composite parent) {
346
347 Composite sourceGroup = new Composite(parent, SWT.NONE);
348 GridLayout layout = new GridLayout();
349 layout.numColumns = 3;
350 layout.makeColumnsEqualWidth = false;
351 layout.marginWidth = 0;
352 sourceGroup.setLayout(layout);
353 sourceGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
354
355 // import from directory radio button
356 fImportFromDirectoryRadio = new Button(sourceGroup, SWT.RADIO);
357 fImportFromDirectoryRadio
358 .setText(Messages.ImportTraceWizard_DirectoryLocation);
359
360 // import location entry combo
361 directoryNameField = createPathSelectionCombo(sourceGroup);
362 createDirectoryBrowseButton(sourceGroup);
363
364 // import from archive radio button
365 fImportFromArchiveRadio = new Button(sourceGroup, SWT.RADIO);
366 fImportFromArchiveRadio
367 .setText(Messages.ImportTraceWizard_ArchiveLocation);
368
369 // import location entry combo
370 fArchiveNameField = createPathSelectionCombo(sourceGroup);
371 createArchiveBrowseButton(sourceGroup);
372
373 fImportFromDirectoryRadio.setSelection(true);
374 fArchiveNameField.setEnabled(false);
375 fArchiveBrowseButton.setEnabled(false);
376
377 fImportFromDirectoryRadio.addSelectionListener(new SelectionAdapter() {
378 @Override
379 public void widgetSelected(SelectionEvent e) {
380 directoryRadioSelected();
381 }
382 });
383
384 fImportFromArchiveRadio.addSelectionListener(new SelectionAdapter() {
385 @Override
386 public void widgetSelected(SelectionEvent e) {
387 archiveRadioSelected();
388 }
389 });
390 }
391
392 /**
393 * Select or deselect all files in the file selection group
394 *
395 * @param checked
396 * whether or not the files should be checked
397 */
398 protected void setFileSelectionGroupChecked(boolean checked) {
399 if (fSelectionGroup != null) {
400 fSelectionGroup.setAllSelections(checked);
401 }
402 }
403
404 /**
405 * Create a combo that will be used to select a path to specify the source
406 * of the import. The parent is assumed to have a GridLayout.
407 *
408 * @param parent
409 * the parent composite
410 * @return the created path selection combo
411 */
412 protected Combo createPathSelectionCombo(Composite parent) {
413 Combo pathSelectionCombo = new Combo(parent, SWT.BORDER);
414
415 GridData layoutData = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL);
416 layoutData.widthHint = new PixelConverter(pathSelectionCombo).convertWidthInCharsToPixels(25);
417 pathSelectionCombo.setLayoutData(layoutData);
418
419 TraverseListener traverseListener = new TraverseListener() {
420 @Override
421 public void keyTraversed(TraverseEvent e) {
422 if (e.detail == SWT.TRAVERSE_RETURN) {
423 e.doit = false;
424 entryChanged = false;
425 updateFromSourceField();
426 }
427 }
428 };
429
430 FocusAdapter focusAdapter = new FocusAdapter() {
431 @Override
432 public void focusLost(FocusEvent e) {
433 // Clear the flag to prevent constant update
434 if (entryChanged) {
435 entryChanged = false;
436 updateFromSourceField();
437 }
438 }
439 };
440
441 SelectionAdapter selectionAdapter = new SelectionAdapter() {
442 @Override
443 public void widgetSelected(SelectionEvent e) {
444 entryChanged = false;
445 updateFromSourceField();
446 }
447 };
448
449 ModifyListener modifyListner = new ModifyListener() {
450 @Override
451 public void modifyText(ModifyEvent e) {
452 entryChanged = true;
453 }
454 };
455
456 pathSelectionCombo.addModifyListener(modifyListner);
457 pathSelectionCombo.addTraverseListener(traverseListener);
458 pathSelectionCombo.addFocusListener(focusAdapter);
459 pathSelectionCombo.addSelectionListener(selectionAdapter);
460
461 return pathSelectionCombo;
462 }
463
464 /**
465 * Create the directory browse button.
466 *
467 * @param parent
468 * the parent composite
469 */
470 protected void createDirectoryBrowseButton(Composite parent) {
471 directoryBrowseButton = createPathSelectionBrowseButton(parent);
472 directoryBrowseButton.addSelectionListener(new SelectionAdapter() {
473 @Override
474 public void widgetSelected(SelectionEvent e) {
475 handleSourceDirectoryBrowseButtonPressed();
476 }
477 });
478 }
479
480 /**
481 * Create the archive browse button.
482 *
483 * @param parent
484 * the parent composite
485 */
486 protected void createArchiveBrowseButton(Composite parent) {
487 fArchiveBrowseButton = createPathSelectionBrowseButton(parent);
488 fArchiveBrowseButton.addSelectionListener(new SelectionAdapter() {
489 @Override
490 public void widgetSelected(SelectionEvent e) {
491 handleArchiveBrowseButtonPressed(FILE_IMPORT_MASK);
492 }
493 });
494 }
495
496 /**
497 * Create a browse button that will be used to browse for a path to specify
498 * the source of the import. The parent is assumed to have a GridLayout.
499 *
500 * @param parent
501 * the parent composite
502 * @return the created path selection combo
503 */
504 protected Button createPathSelectionBrowseButton(Composite parent) {
505 Button pathSelectionBrowseButton = new Button(parent, SWT.PUSH);
506 pathSelectionBrowseButton.setText(Messages.ImportTraceWizard_BrowseButton);
507 setButtonLayoutData(pathSelectionBrowseButton);
508
509 return pathSelectionBrowseButton;
510 }
511
512 private void archiveRadioSelected() {
513 if (!isImportFromDirectory()) {
514 directoryNameField.setEnabled(false);
515 directoryBrowseButton.setEnabled(false);
516 fArchiveNameField.setEnabled(true);
517 fArchiveBrowseButton.setEnabled(true);
518 updateFromSourceField();
519 fArchiveNameField.setFocus();
520 if (fCreateLinksInWorkspaceButton != null) {
521 fPreviousCreateLinksValue = fCreateLinksInWorkspaceButton.getSelection();
522 fCreateLinksInWorkspaceButton.setSelection(false);
523 fCreateLinksInWorkspaceButton.setEnabled(false);
524 }
525 }
526 }
527
528 private void directoryRadioSelected() {
529 if (isImportFromDirectory()) {
530 directoryNameField.setEnabled(true);
531 directoryBrowseButton.setEnabled(true);
532 fArchiveNameField.setEnabled(false);
533 fArchiveBrowseButton.setEnabled(false);
534 updateFromSourceField();
535 directoryNameField.setFocus();
536 if (fCreateLinksInWorkspaceButton != null) {
537 fCreateLinksInWorkspaceButton.setSelection(fPreviousCreateLinksValue);
538 fCreateLinksInWorkspaceButton.setEnabled(true);
539 }
540 }
541 }
542
543 // ------------------------------------------------------------------------
544 // Browse for the source directory
545 // ------------------------------------------------------------------------
546
547 @Override
548 public void handleEvent(Event event) {
549 if (event.widget == directoryBrowseButton) {
550 handleSourceDirectoryBrowseButtonPressed();
551 }
552
553 // Avoid overwriting destination path without repeatedly trigger
554 // call of handleEvent();
555 synchronized (fSyncObject) {
556 if (fIsDestinationChanged == false) {
557 event.display.asyncExec(new Runnable() {
558 @Override
559 public void run() {
560 synchronized (fSyncObject) {
561 fIsDestinationChanged = true;
562 String path = fTargetFolder.getFullPath().toString();
563 setContainerFieldValue(path);
564 }
565 }
566 });
567 } else {
568 fIsDestinationChanged = false;
569 }
570 }
571 super.handleEvent(event);
572 }
573
574 @Override
575 protected void handleContainerBrowseButtonPressed() {
576 // Do nothing so that destination directory cannot be changed.
577 }
578
579 /**
580 * Handle the button pressed event
581 */
582 protected void handleSourceDirectoryBrowseButtonPressed() {
583 String currentSource = directoryNameField.getText();
584 DirectoryDialog dialog = new DirectoryDialog(directoryNameField.getShell(), SWT.SAVE | SWT.SHEET);
585 dialog.setText(Messages.ImportTraceWizard_SelectTraceDirectoryTitle);
586 dialog.setMessage(Messages.ImportTraceWizard_SelectTraceDirectoryMessage);
587 dialog.setFilterPath(getSourceDirectoryName(currentSource));
588
589 String selectedDirectory = dialog.open();
590 if (selectedDirectory != null) {
591 // Just quit if the directory is not valid
592 if ((getSourceDirectory(selectedDirectory) == null) || selectedDirectory.equals(currentSource)) {
593 return;
594 }
595 // If it is valid then proceed to populate
596 setErrorMessage(null);
597 setSourcePath(selectedDirectory);
598 }
599 }
600
601 /**
602 * Handle the button pressed event
603 *
604 * @param extensions
605 * file extensions used to filter files shown to the user
606 */
607 protected void handleArchiveBrowseButtonPressed(String[] extensions) {
608 FileDialog dialog = new FileDialog(fArchiveNameField.getShell(), SWT.SHEET);
609 dialog.setFilterExtensions(extensions);
610 dialog.setText(Messages.ImportTraceWizard_SelectTraceArchiveTitle);
611 String fileName = fArchiveNameField.getText().trim();
612 if (!fileName.isEmpty()) {
613 File path = new File(fileName).getParentFile();
614 if (path != null && path.exists()) {
615 dialog.setFilterPath(path.toString());
616 }
617 }
618
619 String selectedArchive = dialog.open();
620 if (selectedArchive != null) {
621 setErrorMessage(null);
622 setSourcePath(selectedArchive);
623 updateWidgetEnablements();
624 }
625 }
626
627 private File getSourceDirectory() {
628 if (directoryNameField == null) {
629 return null;
630 }
631 return getSourceDirectory(directoryNameField.getText());
632 }
633
634 private File getSourceArchiveFile() {
635 if (fArchiveNameField == null) {
636 return null;
637 }
638
639 return getSourceArchiveFile(fArchiveNameField.getText());
640 }
641
642 private String getSourceContainerPath() {
643 if (isImportFromDirectory()) {
644 File sourceDirectory = getSourceDirectory();
645 if (sourceDirectory != null) {
646 return sourceDirectory.getAbsolutePath();
647 }
648 }
649 File sourceArchiveFile = getSourceArchiveFile();
650 if (sourceArchiveFile != null) {
651 return sourceArchiveFile.getParent();
652 }
653 return null;
654 }
655
656 private static File getSourceDirectory(String path) {
657 File sourceDirectory = new File(getSourceDirectoryName(path));
658 if (!sourceDirectory.exists() || !sourceDirectory.isDirectory()) {
659 return null;
660 }
661
662 return sourceDirectory;
663 }
664
665 private static File getSourceArchiveFile(String path) {
666 File sourceArchiveFile = new File(path);
667 if (!sourceArchiveFile.exists() || sourceArchiveFile.isDirectory()) {
668 return null;
669 }
670
671 return sourceArchiveFile;
672 }
673
674 private static String getSourceDirectoryName(String sourceName) {
675 IPath result = new Path(sourceName.trim());
676 if (result.getDevice() != null && result.segmentCount() == 0) {
677 result = result.addTrailingSeparator();
678 } else {
679 result = result.removeTrailingSeparator();
680 }
681 return result.toOSString();
682 }
683
684 private void updateFromSourceField() {
685 setSourcePath(getSourceField().getText());
686 updateWidgetEnablements();
687 }
688
689 private Combo getSourceField() {
690 if (directoryNameField == null) {
691 return fArchiveNameField;
692 }
693
694 return directoryNameField.isEnabled() ? directoryNameField : fArchiveNameField;
695 }
696
697 /**
698 * Set the source path that was selected by the user by various input
699 * methods (Browse button, typing, etc).
700 *
701 * Clients can also call this to set the path programmatically (hard-coded
702 * initial path) and this can also be overridden to be notified when the
703 * source path changes.
704 *
705 * @param path
706 * the source path
707 */
708 protected void setSourcePath(String path) {
709 Combo sourceField = getSourceField();
710 if (sourceField == null) {
711 return;
712 }
713
714 if (path.length() > 0) {
715 String[] currentItems = sourceField.getItems();
716 int selectionIndex = -1;
717 for (int i = 0; i < currentItems.length; i++) {
718 if (currentItems[i].equals(path)) {
719 selectionIndex = i;
720 }
721 }
722 if (selectionIndex < 0) {
723 int oldLength = currentItems.length;
724 String[] newItems = new String[oldLength + 1];
725 System.arraycopy(currentItems, 0, newItems, 0, oldLength);
726 newItems[oldLength] = path;
727 sourceField.setItems(newItems);
728 selectionIndex = oldLength;
729 }
730 sourceField.select(selectionIndex);
731 }
732 resetSelection();
733 }
734
735 // ------------------------------------------------------------------------
736 // File Selection Group (forked WizardFileSystemResourceImportPage1)
737 // ------------------------------------------------------------------------
738 private void resetSelection() {
739 if (fSelectionGroupRoot != null) {
740 disposeSelectionGroupRoot();
741 }
742 fSelectionGroupRoot = getFileSystemTree();
743 fSelectionGroup.setRoot(fSelectionGroupRoot);
744 }
745
746 private void disposeSelectionGroupRoot() {
747 if (fSelectionGroupRoot != null && fSelectionGroupRoot.getProvider() != null) {
748 FileSystemObjectImportStructureProvider provider = fSelectionGroupRoot.getProvider();
749 provider.dispose();
750 fSelectionGroupRoot = null;
751 }
752 }
753
754 private TraceFileSystemElement getFileSystemTree() {
755 Pair<IFileSystemObject, FileSystemObjectImportStructureProvider> rootObjectAndProvider = ArchiveUtil.getRootObjectAndProvider(getSourceFile(), getContainer().getShell());
756 if (rootObjectAndProvider == null) {
757 return null;
758 }
759 return selectFiles(rootObjectAndProvider.getFirst(), rootObjectAndProvider.getSecond());
760 }
761
762 private TraceFileSystemElement selectFiles(final IFileSystemObject rootFileSystemObject,
763 final FileSystemObjectImportStructureProvider structureProvider) {
764 final TraceFileSystemElement[] results = new TraceFileSystemElement[1];
765 BusyIndicator.showWhile(getShell().getDisplay(), new Runnable() {
766 @Override
767 public void run() {
768 // Create the root element from the supplied file system object
769 results[0] = TraceFileSystemElement.createRootTraceFileElement(rootFileSystemObject, structureProvider);
770 }
771 });
772 return results[0];
773 }
774
775 // ------------------------------------------------------------------------
776 // Trace Type Group
777 // ------------------------------------------------------------------------
778 private final void createTraceTypeGroup(Composite parent) {
779 Composite composite = new Composite(parent, SWT.NONE);
780 GridLayout layout = new GridLayout();
781 layout.numColumns = 3;
782 layout.makeColumnsEqualWidth = false;
783 composite.setLayout(layout);
784 composite.setFont(parent.getFont());
785 GridData buttonData = new GridData(SWT.FILL, SWT.FILL, true, false);
786 composite.setLayoutData(buttonData);
787
788 // Trace type label ("Trace Type:")
789 Label typeLabel = new Label(composite, SWT.NONE);
790 typeLabel.setText(Messages.ImportTraceWizard_TraceType);
791 typeLabel.setFont(parent.getFont());
792
793 // Trace type combo
794 fTraceTypes = new Combo(composite, SWT.BORDER | SWT.READ_ONLY);
795 GridData data = new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1);
796 fTraceTypes.setLayoutData(data);
797 fTraceTypes.setFont(parent.getFont());
798
799 String[] availableTraceTypes = TmfTraceType.getAvailableTraceTypes();
800 String[] traceTypeList = new String[availableTraceTypes.length + 1];
801 traceTypeList[0] = TRACE_TYPE_AUTO_DETECT;
802 for (int i = 0; i < availableTraceTypes.length; i++) {
803 traceTypeList[i + 1] = availableTraceTypes[i];
804 }
805 fTraceTypes.setItems(traceTypeList);
806 fTraceTypes.addSelectionListener(new SelectionAdapter() {
807 @Override
808 public void widgetSelected(SelectionEvent e) {
809 updateWidgetEnablements();
810 boolean enabled = fTraceTypes.getText().equals(TRACE_TYPE_AUTO_DETECT);
811 fImportUnrecognizedButton.setEnabled(enabled);
812 }
813 });
814 fTraceTypes.select(0);
815
816 // Unrecognized checkbox
817 fImportUnrecognizedButton = new Button(composite, SWT.CHECK);
818 fImportUnrecognizedButton.setSelection(true);
819 fImportUnrecognizedButton.setText(Messages.ImportTraceWizard_ImportUnrecognized);
820 }
821
822 // ------------------------------------------------------------------------
823 // Options
824 // ------------------------------------------------------------------------
825
826 @Override
827 protected void createOptionsGroupButtons(Group optionsGroup) {
828
829 // Overwrite checkbox
830 fOverwriteExistingResourcesCheckbox = new Button(optionsGroup, SWT.CHECK);
831 fOverwriteExistingResourcesCheckbox.setFont(optionsGroup.getFont());
832 fOverwriteExistingResourcesCheckbox.setText(Messages.ImportTraceWizard_OverwriteExistingTrace);
833 fOverwriteExistingResourcesCheckbox.setSelection(false);
834
835 // Create links checkbox
836 fCreateLinksInWorkspaceButton = new Button(optionsGroup, SWT.CHECK);
837 fCreateLinksInWorkspaceButton.setFont(optionsGroup.getFont());
838 fCreateLinksInWorkspaceButton.setText(Messages.ImportTraceWizard_CreateLinksInWorkspace);
839 fCreateLinksInWorkspaceButton.setSelection(true);
840
841 fCreateLinksInWorkspaceButton.addSelectionListener(new SelectionAdapter() {
842 @Override
843 public void widgetSelected(SelectionEvent e) {
844 updateWidgetEnablements();
845 }
846 });
847
848 fPreserveFolderStructureButton = new Button(optionsGroup, SWT.CHECK);
849 fPreserveFolderStructureButton.setFont(optionsGroup.getFont());
850 fPreserveFolderStructureButton.setText(Messages.ImportTraceWizard_PreserveFolderStructure);
851 fPreserveFolderStructureButton.setSelection(true);
852
853 updateWidgetEnablements();
854 }
855
856 // ------------------------------------------------------------------------
857 // Determine if the finish button can be enabled
858 // ------------------------------------------------------------------------
859 @Override
860 public boolean validateSourceGroup() {
861
862 File source = getSourceFile();
863 if (source == null) {
864 setMessage(Messages.ImportTraceWizard_SelectTraceSourceEmpty);
865 setErrorMessage(null);
866 return false;
867 }
868
869 if (sourceConflictsWithDestination(new Path(source.getPath()))) {
870 setMessage(null);
871 setErrorMessage(getSourceConflictMessage());
872 return false;
873 }
874
875 if (!isImportFromDirectory() && !ArchiveUtil.ensureTarSourceIsValid(source.getAbsolutePath(), getContainer().getShell()) && !ArchiveUtil.ensureZipSourceIsValid(source.getAbsolutePath(), getContainer().getShell()) && !ArchiveUtil.ensureGzipSourceIsValid(source.getAbsolutePath())) {
876 setMessage(null);
877 setErrorMessage(Messages.ImportTraceWizard_BadArchiveFormat);
878 return false;
879 }
880
881 if (fSelectionGroup.getCheckedElementCount() == 0) {
882 setMessage(null);
883 setErrorMessage(Messages.ImportTraceWizard_SelectTraceNoneSelected);
884 return false;
885 }
886
887 IContainer container = getSpecifiedContainer();
888 if (container != null && container.isVirtual()) {
889 if (Platform.getPreferencesService().getBoolean(Activator.PLUGIN_ID, ResourcesPlugin.PREF_DISABLE_LINKING, false, null)) {
890 setMessage(null);
891 setErrorMessage(Messages.ImportTraceWizard_CannotImportFilesUnderAVirtualFolder);
892 return false;
893 }
894 if (fCreateLinksInWorkspaceButton == null || !fCreateLinksInWorkspaceButton.getSelection()) {
895 setMessage(null);
896 setErrorMessage(Messages.ImportTraceWizard_HaveToCreateLinksUnderAVirtualFolder);
897 return false;
898 }
899 }
900
901 setErrorMessage(null);
902 return true;
903 }
904
905 private File getSourceFile() {
906 return isImportFromDirectory() ? getSourceDirectory() : getSourceArchiveFile();
907 }
908
909 private boolean isImportFromDirectory() {
910 return fImportFromDirectoryRadio != null && fImportFromDirectoryRadio.getSelection();
911 }
912
913 @Override
914 protected void restoreWidgetValues() {
915 super.restoreWidgetValues();
916
917 IDialogSettings settings = getDialogSettings();
918 boolean value;
919 if (fImportUnrecognizedButton != null) {
920 if (settings.get(getPageStoreKey(IMPORT_WIZARD_IMPORT_UNRECOGNIZED_ID)) == null) {
921 value = true;
922 } else {
923 value = settings.getBoolean(getPageStoreKey(IMPORT_WIZARD_IMPORT_UNRECOGNIZED_ID));
924 }
925 fImportUnrecognizedButton.setSelection(value);
926 }
927
928 if (fPreserveFolderStructureButton != null) {
929 if (settings.get(getPageStoreKey(IMPORT_WIZARD_PRESERVE_FOLDERS_ID)) == null) {
930 value = true;
931 } else {
932 value = settings.getBoolean(getPageStoreKey(IMPORT_WIZARD_PRESERVE_FOLDERS_ID));
933 }
934 fPreserveFolderStructureButton.setSelection(value);
935 }
936
937 if (settings.get(getPageStoreKey(IMPORT_WIZARD_IMPORT_FROM_DIRECTORY_ID)) == null) {
938 value = true;
939 } else {
940 value = settings.getBoolean(getPageStoreKey(IMPORT_WIZARD_IMPORT_FROM_DIRECTORY_ID));
941 }
942
943 if (directoryNameField != null) {
944 restoreComboValues(directoryNameField, settings, getPageStoreKey(IMPORT_WIZARD_ROOT_DIRECTORY_ID));
945 }
946 if (fArchiveNameField != null) {
947 restoreComboValues(fArchiveNameField, settings, getPageStoreKey(IMPORT_WIZARD_ARCHIVE_FILE_NAME_ID));
948 }
949
950 if (fImportFromDirectoryRadio != null) {
951 fImportFromDirectoryRadio.setSelection(value);
952 if (value) {
953 directoryRadioSelected();
954 }
955 }
956 if (fImportFromArchiveRadio != null) {
957 fImportFromArchiveRadio.setSelection(!value);
958 if (!value) {
959 archiveRadioSelected();
960 }
961 }
962 }
963
964 @Override
965 protected void saveWidgetValues() {
966 // Persist dialog settings
967 IDialogSettings settings = getDialogSettings();
968 if (fImportUnrecognizedButton != null) {
969 settings.put(getPageStoreKey(IMPORT_WIZARD_IMPORT_UNRECOGNIZED_ID), fImportUnrecognizedButton.getSelection());
970 }
971 if (fPreserveFolderStructureButton != null) {
972 settings.put(getPageStoreKey(IMPORT_WIZARD_PRESERVE_FOLDERS_ID), fPreserveFolderStructureButton.getSelection());
973 }
974 settings.put(getPageStoreKey(IMPORT_WIZARD_IMPORT_FROM_DIRECTORY_ID), isImportFromDirectory());
975
976 if (directoryNameField != null) {
977 saveComboValues(directoryNameField, settings, getPageStoreKey(IMPORT_WIZARD_ROOT_DIRECTORY_ID));
978 }
979 if (fArchiveNameField != null) {
980 saveComboValues(fArchiveNameField, settings, getPageStoreKey(IMPORT_WIZARD_ARCHIVE_FILE_NAME_ID));
981 }
982 }
983
984 private String getPageStoreKey(String key) {
985 return getName() + key;
986 }
987
988 private static void restoreComboValues(Combo combo, IDialogSettings settings, String key) {
989 String[] directoryNames = settings.getArray(key);
990 if ((directoryNames != null) && (directoryNames.length != 0)) {
991 for (int i = 0; i < directoryNames.length; i++) {
992 combo.add(directoryNames[i]);
993 }
994 }
995 }
996
997 private void saveComboValues(Combo combo, IDialogSettings settings, String key) {
998 // update names history
999 String[] directoryNames = settings.getArray(key);
1000 if (directoryNames == null) {
1001 directoryNames = new String[0];
1002 }
1003
1004 String items[] = combo.getItems();
1005 for (int i = 0; i < items.length; i++) {
1006 directoryNames = addToHistory(directoryNames, items[i]);
1007 }
1008 settings.put(key, directoryNames);
1009 }
1010
1011 // ------------------------------------------------------------------------
1012 // Import the trace(s)
1013 // ------------------------------------------------------------------------
1014
1015 /**
1016 * Finish the import.
1017 *
1018 * @return <code>true</code> if successful else <code>false</code>
1019 */
1020 public boolean finish() {
1021 String traceTypeLabel = getImportTraceTypeId();
1022 final String traceId = !TRACE_TYPE_AUTO_DETECT.equals(traceTypeLabel) ? TmfTraceType.getTraceTypeId(traceTypeLabel) : null;
1023
1024 // Save dialog settings
1025 saveWidgetValues();
1026
1027 final IPath baseSourceContainerPath = new Path(getSourceContainerPath());
1028 final boolean importFromArchive = getSourceArchiveFile() != null;
1029 final int importOptionFlags = getImportOptionFlags();
1030 final IPath destinationContainerPath = getContainerFullPath();
1031
1032 final IStatus[] operationStatus = new IStatus[1];
1033 operationStatus[0] = Status.OK_STATUS;
1034 try {
1035 getContainer().run(true, true, new IRunnableWithProgress() {
1036 @Override
1037 public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
1038
1039 final List<TraceFileSystemElement> selectedFileSystemElements = new LinkedList<>();
1040 IElementFilter passThroughFilter = new IElementFilter() {
1041
1042 @Override
1043 public void filterElements(Collection elements, IProgressMonitor m) {
1044 selectedFileSystemElements.addAll(elements);
1045 }
1046
1047 @Override
1048 public void filterElements(Object[] elements, IProgressMonitor m) {
1049 for (int i = 0; i < elements.length; i++) {
1050 selectedFileSystemElements.add((TraceFileSystemElement) elements[i]);
1051 }
1052 }
1053 };
1054
1055 // List fileSystemElements will be filled using the
1056 // passThroughFilter
1057 SubMonitor subMonitor = SubMonitor.convert(monitor, 1);
1058 fSelectionGroup.getAllCheckedListItems(passThroughFilter, subMonitor);
1059
1060 final TraceValidateAndImportOperation operation = new TraceValidateAndImportOperation(getContainer().getShell(), selectedFileSystemElements, traceId, baseSourceContainerPath, destinationContainerPath, importFromArchive,
1061 importOptionFlags, fTraceFolderElement);
1062 operation.run(monitor);
1063 monitor.done();
1064 operationStatus[0] = operation.getStatus();
1065 }
1066 });
1067
1068 } catch (InvocationTargetException e) {
1069 operationStatus[0] = new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.ImportTraceWizard_ImportProblem, e.getTargetException());
1070 } catch (InterruptedException e) {
1071 operationStatus[0] = Status.CANCEL_STATUS;
1072 }
1073 if (!operationStatus[0].isOK()) {
1074 if (operationStatus[0].getSeverity() == IStatus.CANCEL) {
1075 setMessage(Messages.ImportTraceWizard_ImportOperationCancelled);
1076 setErrorMessage(null);
1077 } else {
1078 Throwable exception = operationStatus[0].getException();
1079 if (exception != null) {
1080 Activator.getDefault().logError(exception.getMessage(), exception);
1081 displayErrorDialog(operationStatus[0].getMessage() + ": " + exception); //$NON-NLS-1$
1082 }
1083 setMessage(null);
1084 setErrorMessage(Messages.ImportTraceWizard_ImportProblem);
1085 }
1086 return false;
1087 }
1088 setErrorMessage(null);
1089 return true;
1090 }
1091
1092 /**
1093 * Get the trace type id to import as. This can also return
1094 * {@link #TRACE_TYPE_AUTO_DETECT} to communicate that automatic trace type
1095 * detection will occur instead of setting a specific trace type when
1096 * importing the traces.
1097 *
1098 * @return the trace type id or {@link #TRACE_TYPE_AUTO_DETECT}
1099 */
1100 protected String getImportTraceTypeId() {
1101 return fTraceTypes.getText();
1102 }
1103
1104 /**
1105 * Get import options in the form of flags (bits).
1106 *
1107 * @return the import flags.
1108 * @see #OPTION_CREATE_LINKS_IN_WORKSPACE
1109 * @see #OPTION_IMPORT_UNRECOGNIZED_TRACES
1110 * @see #OPTION_OVERWRITE_EXISTING_RESOURCES
1111 * @see #OPTION_PRESERVE_FOLDER_STRUCTURE
1112 */
1113 protected int getImportOptionFlags() {
1114 int flags = 0;
1115 if (fCreateLinksInWorkspaceButton != null && fCreateLinksInWorkspaceButton.getSelection()) {
1116 flags |= OPTION_CREATE_LINKS_IN_WORKSPACE;
1117 }
1118 if (fImportUnrecognizedButton != null && fImportUnrecognizedButton.getSelection()) {
1119 flags |= OPTION_IMPORT_UNRECOGNIZED_TRACES;
1120 }
1121 if (fOverwriteExistingResourcesCheckbox != null && fOverwriteExistingResourcesCheckbox.getSelection()) {
1122 flags |= OPTION_OVERWRITE_EXISTING_RESOURCES;
1123 }
1124 if (fPreserveFolderStructureButton != null && fPreserveFolderStructureButton.getSelection()) {
1125 flags |= OPTION_PRESERVE_FOLDER_STRUCTURE;
1126 }
1127 return flags;
1128 }
1129
1130 @Override
1131 public void dispose() {
1132 super.dispose();
1133 disposeSelectionGroupRoot();
1134 }
1135 }
This page took 0.08442 seconds and 5 git commands to generate.