tmf: Move plugins to the Trace Compass namespace
[deliverable/tracecompass.git] / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / linuxtools / internal / 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 * Marc-Andre Laperle - Preserve folder structure on import
18 *******************************************************************************/
19
20 package org.eclipse.linuxtools.internal.tmf.ui.project.wizards.importtrace;
21
22 import java.io.File;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.lang.reflect.InvocationTargetException;
26 import java.net.URI;
27 import java.util.ArrayList;
28 import java.util.Collection;
29 import java.util.HashMap;
30 import java.util.Iterator;
31 import java.util.List;
32 import java.util.Map;
33 import java.util.zip.ZipEntry;
34 import java.util.zip.ZipException;
35 import java.util.zip.ZipFile;
36
37 import org.eclipse.core.resources.IContainer;
38 import org.eclipse.core.resources.IFolder;
39 import org.eclipse.core.resources.IProject;
40 import org.eclipse.core.resources.IResource;
41 import org.eclipse.core.resources.ResourcesPlugin;
42 import org.eclipse.core.runtime.CoreException;
43 import org.eclipse.core.runtime.IPath;
44 import org.eclipse.core.runtime.IProgressMonitor;
45 import org.eclipse.core.runtime.IStatus;
46 import org.eclipse.core.runtime.NullProgressMonitor;
47 import org.eclipse.core.runtime.Path;
48 import org.eclipse.core.runtime.Platform;
49 import org.eclipse.core.runtime.Status;
50 import org.eclipse.core.runtime.SubMonitor;
51 import org.eclipse.core.runtime.SubProgressMonitor;
52 import org.eclipse.core.runtime.URIUtil;
53 import org.eclipse.jface.dialogs.IDialogSettings;
54 import org.eclipse.jface.dialogs.MessageDialog;
55 import org.eclipse.jface.layout.PixelConverter;
56 import org.eclipse.jface.operation.IRunnableWithProgress;
57 import org.eclipse.jface.operation.ModalContext;
58 import org.eclipse.jface.viewers.CheckStateChangedEvent;
59 import org.eclipse.jface.viewers.ICheckStateListener;
60 import org.eclipse.jface.viewers.IStructuredSelection;
61 import org.eclipse.jface.viewers.ITreeContentProvider;
62 import org.eclipse.linuxtools.internal.tmf.ui.Activator;
63 import org.eclipse.linuxtools.tmf.core.TmfCommonConstants;
64 import org.eclipse.linuxtools.tmf.core.TmfProjectNature;
65 import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceImportException;
66 import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceType;
67 import org.eclipse.linuxtools.tmf.core.project.model.TraceTypeHelper;
68 import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectElement;
69 import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectRegistry;
70 import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement;
71 import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceFolder;
72 import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceTypeUIUtils;
73 import org.eclipse.linuxtools.tmf.ui.project.model.TmfTracesFolder;
74 import org.eclipse.osgi.util.NLS;
75 import org.eclipse.swt.SWT;
76 import org.eclipse.swt.custom.BusyIndicator;
77 import org.eclipse.swt.events.FocusAdapter;
78 import org.eclipse.swt.events.FocusEvent;
79 import org.eclipse.swt.events.ModifyEvent;
80 import org.eclipse.swt.events.ModifyListener;
81 import org.eclipse.swt.events.SelectionAdapter;
82 import org.eclipse.swt.events.SelectionEvent;
83 import org.eclipse.swt.events.TraverseEvent;
84 import org.eclipse.swt.events.TraverseListener;
85 import org.eclipse.swt.layout.GridData;
86 import org.eclipse.swt.layout.GridLayout;
87 import org.eclipse.swt.widgets.Button;
88 import org.eclipse.swt.widgets.Combo;
89 import org.eclipse.swt.widgets.Composite;
90 import org.eclipse.swt.widgets.DirectoryDialog;
91 import org.eclipse.swt.widgets.Event;
92 import org.eclipse.swt.widgets.FileDialog;
93 import org.eclipse.swt.widgets.Group;
94 import org.eclipse.swt.widgets.Label;
95 import org.eclipse.ui.dialogs.FileSystemElement;
96 import org.eclipse.ui.dialogs.IOverwriteQuery;
97 import org.eclipse.ui.dialogs.WizardResourceImportPage;
98 import org.eclipse.ui.internal.ide.DialogUtil;
99 import org.eclipse.ui.internal.ide.dialogs.IElementFilter;
100 import org.eclipse.ui.internal.wizards.datatransfer.ArchiveFileManipulations;
101 import org.eclipse.ui.internal.wizards.datatransfer.ILeveledImportStructureProvider;
102 import org.eclipse.ui.internal.wizards.datatransfer.TarEntry;
103 import org.eclipse.ui.internal.wizards.datatransfer.TarException;
104 import org.eclipse.ui.internal.wizards.datatransfer.TarFile;
105 import org.eclipse.ui.internal.wizards.datatransfer.TarLeveledStructureProvider;
106 import org.eclipse.ui.internal.wizards.datatransfer.ZipLeveledStructureProvider;
107 import org.eclipse.ui.model.AdaptableList;
108 import org.eclipse.ui.model.WorkbenchContentProvider;
109 import org.eclipse.ui.model.WorkbenchLabelProvider;
110 import org.eclipse.ui.model.WorkbenchViewerComparator;
111 import org.eclipse.ui.wizards.datatransfer.FileSystemStructureProvider;
112 import org.eclipse.ui.wizards.datatransfer.IImportStructureProvider;
113 import org.eclipse.ui.wizards.datatransfer.ImportOperation;
114
115 /**
116 * A variant of the standard resource import wizard for importing traces to
117 * given tracing project. If no project or tracing project was selected the
118 * wizard imports it to the default tracing project which is created if
119 * necessary.
120 *
121 * In our case traces could be files or a directory structure. This wizard
122 * supports both cases. It imports traces for a selected trace type or, if no
123 * trace type is selected, it tries to detect the trace type automatically.
124 * However, the automatic detection is a best-effort and cannot guarantee that
125 * the detection is successful. The reason for this is that there might be
126 * multiple trace types that can be assigned to a single trace.
127 *
128 *
129 * @author Francois Chouinard
130 * @since 2.0
131 */
132 @SuppressWarnings("restriction")
133 public class ImportTraceWizardPage extends WizardResourceImportPage {
134
135 // ------------------------------------------------------------------------
136 // Constants
137 // ------------------------------------------------------------------------
138 private static final String IMPORT_WIZARD_PAGE_NAME = "ImportTraceWizardPage"; //$NON-NLS-1$
139 private static final String IMPORT_WIZARD_ROOT_DIRECTORY_ID = ".import_root_directory_id"; //$NON-NLS-1$;
140 private static final String IMPORT_WIZARD_ARCHIVE_FILE_NAME_ID = ".import_archive_file_name_id"; //$NON-NLS-1$
141 private static final String IMPORT_WIZARD_IMPORT_UNRECOGNIZED_ID = ".import_unrecognized_traces_id"; //$NON-NLS-1$
142 private static final String IMPORT_WIZARD_PRESERVE_FOLDERS_ID = ".import_preserve_folders_id"; //$NON-NLS-1$
143 private static final String IMPORT_WIZARD_IMPORT_FROM_DIRECTORY_ID = ".import_from_directory"; //$NON-NLS-1$
144 private static final String SEPARATOR = ":"; //$NON-NLS-1$
145
146 // constant from WizardArchiveFileResourceImportPage1
147 private static final String[] FILE_IMPORT_MASK = { "*.jar;*.zip;*.tar;*.tar.gz;*.tgz", "*.*" }; //$NON-NLS-1$ //$NON-NLS-2$
148 private static final String TRACE_IMPORT_TEMP_FOLDER = ".traceImport"; //$NON-NLS-1$
149
150 /**
151 * A special trace type value to communicate that automatic trace type
152 * detection will occur instead of setting a specific trace type when
153 * importing the traces.
154 */
155 public static final String TRACE_TYPE_AUTO_DETECT = Messages.ImportTraceWizard_AutoDetection;
156
157 /**
158 * Preserve the folder structure of the import traces.
159 */
160 public static final int OPTION_PRESERVE_FOLDER_STRUCTURE = 1 << 1;
161 /**
162 * Create links to the trace files instead of copies.
163 */
164 public static final int OPTION_CREATE_LINKS_IN_WORKSPACE = 1 << 2;
165 /**
166 * Import files that were not recognized as the selected trace type.
167 */
168 public static final int OPTION_IMPORT_UNRECOGNIZED_TRACES = 1 << 3;
169 /**
170 * Overwrite existing resources without prompting.
171 */
172 public static final int OPTION_OVERWRITE_EXISTING_RESOURCES = 1 << 4;
173
174 // ------------------------------------------------------------------------
175 // Attributes
176 // ------------------------------------------------------------------------
177
178 // Target import directory ('Traces' folder)
179 private IFolder fTargetFolder;
180 // Target Trace folder element
181 private TmfTraceFolder fTraceFolderElement;
182 // Flag to handle destination folder change event
183 private Boolean fIsDestinationChanged = false;
184 // Combo box containing trace types
185 private Combo fTraceTypes;
186 // Button to ignore unrecognized traces or not
187 private Button fImportUnrecognizedButton;
188 // Button to overwrite existing resources or not
189 private Button fOverwriteExistingResourcesCheckbox;
190 // Button to link or copy traces to workspace
191 private Button fCreateLinksInWorkspaceButton;
192 // Button to preserve folder structure
193 private Button fPreserveFolderStructureButton;
194 private boolean entryChanged = false;
195 // The import from directory radio button
196 private Button fImportFromDirectoryRadio;
197 // The import from archive radio button
198 private Button fImportFromArchiveRadio;
199 // Flag to remember the "create links" checkbox when it gets disabled by
200 // the import from archive radio button
201 private Boolean fPreviousCreateLinksValue = true;
202
203 /** The archive name field */
204 protected Combo fArchiveNameField;
205 /** The archive browse button. */
206 protected Button fArchiveBrowseButton;
207 /** The directory name field */
208 protected Combo directoryNameField;
209 /** The directory browse button. */
210 protected Button directoryBrowseButton;
211
212 /**
213 * ResourceTreeAndListGroup was internal in Kepler and we referenced it. It
214 * is now removed in Luna. To keep our builds compatible with Kepler, we
215 * need to have our own version of this class. Once we stop supporting
216 * Kepler, we can delete this class and use the public one from the
217 * platform.
218 */
219 private ResourceTreeAndListGroup fSelectionGroup;
220
221 // Keep trace of the selection root so that we can dispose its related
222 // resources
223 private TraceFileSystemElement fSelectionGroupRoot;
224
225 // ------------------------------------------------------------------------
226 // Constructors
227 // ------------------------------------------------------------------------
228
229 /**
230 * Constructor. Creates the trace wizard page.
231 *
232 * @param name
233 * The name of the page.
234 * @param selection
235 * The current selection
236 */
237 protected ImportTraceWizardPage(String name, IStructuredSelection selection) {
238 super(name, selection);
239 setTitle(Messages.ImportTraceWizard_FileSystemTitle);
240 setDescription(Messages.ImportTraceWizard_ImportTrace);
241
242 // Locate the target trace folder
243 IFolder traceFolder = null;
244 Object element = selection.getFirstElement();
245
246 if (element instanceof TmfTraceFolder) {
247 fTraceFolderElement = (TmfTraceFolder) element;
248 traceFolder = fTraceFolderElement.getResource();
249 } else if (element instanceof IProject) {
250 IProject project = (IProject) element;
251 try {
252 if (project.hasNature(TmfProjectNature.ID)) {
253 TmfProjectElement projectElement = TmfProjectRegistry.getProject(project, true);
254 fTraceFolderElement = projectElement.getTracesFolder();
255 traceFolder = project.getFolder(TmfTracesFolder.TRACES_FOLDER_NAME);
256 }
257 } catch (CoreException e) {
258 }
259 }
260
261 // If no tracing project was selected or trace folder doesn't exist use
262 // default tracing project
263 if (traceFolder == null) {
264 IProject project = TmfProjectRegistry.createProject(
265 TmfCommonConstants.DEFAULT_TRACE_PROJECT_NAME, null, new NullProgressMonitor());
266 TmfProjectElement projectElement = TmfProjectRegistry.getProject(project, true);
267 fTraceFolderElement = projectElement.getTracesFolder();
268 traceFolder = project.getFolder(TmfTracesFolder.TRACES_FOLDER_NAME);
269 }
270
271 // Set the target trace folder
272 if (traceFolder != null) {
273 fTargetFolder = traceFolder;
274 String path = traceFolder.getFullPath().toString();
275 setContainerFieldValue(path);
276 }
277 }
278
279 /**
280 * Constructor
281 *
282 * @param selection
283 * The current selection
284 */
285 public ImportTraceWizardPage(IStructuredSelection selection) {
286 this(IMPORT_WIZARD_PAGE_NAME, selection);
287 }
288
289 /**
290 * Create the import source selection widget. (Copied from
291 * WizardResourceImportPage but instead always uses the internal
292 * ResourceTreeAndListGroup to keep compatibility with Kepler)
293 */
294 @Override
295 protected void createFileSelectionGroup(Composite parent) {
296
297 // Just create with a dummy root.
298 fSelectionGroup = new ResourceTreeAndListGroup(parent,
299 new FileSystemElement("Dummy", null, true),//$NON-NLS-1$
300 getFolderProvider(), new WorkbenchLabelProvider(),
301 getFileProvider(), new WorkbenchLabelProvider(), SWT.NONE,
302 DialogUtil.inRegularFontMode(parent));
303
304 ICheckStateListener listener = new ICheckStateListener() {
305 @Override
306 public void checkStateChanged(CheckStateChangedEvent event) {
307 updateWidgetEnablements();
308 }
309 };
310
311 WorkbenchViewerComparator comparator = new WorkbenchViewerComparator();
312 fSelectionGroup.setTreeComparator(comparator);
313 fSelectionGroup.setListComparator(comparator);
314 fSelectionGroup.addCheckStateListener(listener);
315
316 }
317
318 // ------------------------------------------------------------------------
319 // WizardResourceImportPage
320 // ------------------------------------------------------------------------
321
322 @Override
323 protected void createSourceGroup(Composite parent) {
324 createSourceSelectionGroup(parent);
325 createFileSelectionGroup(parent);
326 createTraceTypeGroup(parent);
327 validateSourceGroup();
328 }
329
330 @Override
331 protected ITreeContentProvider getFileProvider() {
332 return new WorkbenchContentProvider() {
333 @Override
334 public Object[] getChildren(Object object) {
335 if (object instanceof TraceFileSystemElement) {
336 TraceFileSystemElement element = (TraceFileSystemElement) object;
337 return element.getFiles().getChildren(element);
338 }
339 return new Object[0];
340 }
341 };
342 }
343
344 @Override
345 protected ITreeContentProvider getFolderProvider() {
346 return new WorkbenchContentProvider() {
347 @Override
348 public Object[] getChildren(Object o) {
349 if (o instanceof TraceFileSystemElement) {
350 TraceFileSystemElement element = (TraceFileSystemElement) o;
351 return element.getFolders().getChildren();
352 }
353 return new Object[0];
354 }
355
356 @Override
357 public boolean hasChildren(Object o) {
358 if (o instanceof TraceFileSystemElement) {
359 TraceFileSystemElement element = (TraceFileSystemElement) o;
360 if (element.isPopulated()) {
361 return getChildren(element).length > 0;
362 }
363 // If we have not populated then wait until asked
364 return true;
365 }
366 return false;
367 }
368 };
369 }
370
371 // ------------------------------------------------------------------------
372 // Directory Selection Group (forked WizardFileSystemResourceImportPage1)
373 // ------------------------------------------------------------------------
374
375 /**
376 * creates the source selection group.
377 *
378 * @param parent
379 * the parent composite
380 */
381 protected void createSourceSelectionGroup(Composite parent) {
382
383 Composite sourceGroup = new Composite(parent, SWT.NONE);
384 GridLayout layout = new GridLayout();
385 layout.numColumns = 3;
386 layout.makeColumnsEqualWidth = false;
387 layout.marginWidth = 0;
388 sourceGroup.setLayout(layout);
389 sourceGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
390
391 // import from directory radio button
392 fImportFromDirectoryRadio = new Button(sourceGroup, SWT.RADIO);
393 fImportFromDirectoryRadio
394 .setText(Messages.ImportTraceWizard_DirectoryLocation);
395
396 // import location entry combo
397 directoryNameField = createPathSelectionCombo(sourceGroup);
398 createDirectoryBrowseButton(sourceGroup);
399
400 // import from archive radio button
401 fImportFromArchiveRadio = new Button(sourceGroup, SWT.RADIO);
402 fImportFromArchiveRadio
403 .setText(Messages.ImportTraceWizard_ArchiveLocation);
404
405 // import location entry combo
406 fArchiveNameField = createPathSelectionCombo(sourceGroup);
407 createArchiveBrowseButton(sourceGroup);
408
409 fImportFromDirectoryRadio.setSelection(true);
410 fArchiveNameField.setEnabled(false);
411 fArchiveBrowseButton.setEnabled(false);
412
413 fImportFromDirectoryRadio.addSelectionListener(new SelectionAdapter() {
414 @Override
415 public void widgetSelected(SelectionEvent e) {
416 directoryRadioSelected();
417 }
418 });
419
420 fImportFromArchiveRadio.addSelectionListener(new SelectionAdapter() {
421 @Override
422 public void widgetSelected(SelectionEvent e) {
423 archiveRadioSelected();
424 }
425 });
426 }
427
428 /**
429 * Select or deselect all files in the file selection group
430 *
431 * @param checked
432 * whether or not the files should be checked
433 */
434 protected void setFileSelectionGroupChecked(boolean checked) {
435 if (fSelectionGroup != null) {
436 fSelectionGroup.setAllSelections(checked);
437 }
438 }
439
440 /**
441 * Create a combo that will be used to select a path to specify the source
442 * of the import. The parent is assumed to have a GridLayout.
443 *
444 * @param parent
445 * the parent composite
446 * @return the created path selection combo
447 */
448 protected Combo createPathSelectionCombo(Composite parent) {
449 Combo pathSelectionCombo = new Combo(parent, SWT.BORDER);
450
451 GridData layoutData = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL);
452 layoutData.widthHint = new PixelConverter(pathSelectionCombo).convertWidthInCharsToPixels(25);
453 pathSelectionCombo.setLayoutData(layoutData);
454
455 TraverseListener traverseListener = new TraverseListener() {
456 @Override
457 public void keyTraversed(TraverseEvent e) {
458 if (e.detail == SWT.TRAVERSE_RETURN) {
459 e.doit = false;
460 entryChanged = false;
461 updateFromSourceField();
462 }
463 }
464 };
465
466 FocusAdapter focusAdapter = new FocusAdapter() {
467 @Override
468 public void focusLost(FocusEvent e) {
469 // Clear the flag to prevent constant update
470 if (entryChanged) {
471 entryChanged = false;
472 updateFromSourceField();
473 }
474 }
475 };
476
477 SelectionAdapter selectionAdapter = new SelectionAdapter() {
478 @Override
479 public void widgetSelected(SelectionEvent e) {
480 entryChanged = false;
481 updateFromSourceField();
482 }
483 };
484
485 ModifyListener modifyListner = new ModifyListener() {
486 @Override
487 public void modifyText(ModifyEvent e) {
488 entryChanged = true;
489 }
490 };
491
492 pathSelectionCombo.addModifyListener(modifyListner);
493 pathSelectionCombo.addTraverseListener(traverseListener);
494 pathSelectionCombo.addFocusListener(focusAdapter);
495 pathSelectionCombo.addSelectionListener(selectionAdapter);
496
497 return pathSelectionCombo;
498 }
499
500 /**
501 * Create the directory browse button.
502 *
503 * @param parent
504 * the parent composite
505 */
506 protected void createDirectoryBrowseButton(Composite parent) {
507 directoryBrowseButton = createPathSelectionBrowseButton(parent);
508 directoryBrowseButton.addSelectionListener(new SelectionAdapter() {
509 @Override
510 public void widgetSelected(SelectionEvent e) {
511 handleSourceDirectoryBrowseButtonPressed();
512 }
513 });
514 }
515
516 /**
517 * Create the archive browse button.
518 *
519 * @param parent
520 * the parent composite
521 */
522 protected void createArchiveBrowseButton(Composite parent) {
523 fArchiveBrowseButton = createPathSelectionBrowseButton(parent);
524 fArchiveBrowseButton.addSelectionListener(new SelectionAdapter() {
525 @Override
526 public void widgetSelected(SelectionEvent e) {
527 handleArchiveBrowseButtonPressed(FILE_IMPORT_MASK);
528 }
529 });
530 }
531
532 /**
533 * Create a browse button that will be used to browse for a path to specify
534 * the source of the import. The parent is assumed to have a GridLayout.
535 *
536 * @param parent
537 * the parent composite
538 * @return the created path selection combo
539 */
540 protected Button createPathSelectionBrowseButton(Composite parent) {
541 Button pathSelectionBrowseButton = new Button(parent, SWT.PUSH);
542 pathSelectionBrowseButton.setText(Messages.ImportTraceWizard_BrowseButton);
543 setButtonLayoutData(pathSelectionBrowseButton);
544
545 return pathSelectionBrowseButton;
546 }
547
548 private void archiveRadioSelected() {
549 if (!isImportFromDirectory()) {
550 directoryNameField.setEnabled(false);
551 directoryBrowseButton.setEnabled(false);
552 fArchiveNameField.setEnabled(true);
553 fArchiveBrowseButton.setEnabled(true);
554 updateFromSourceField();
555 fArchiveNameField.setFocus();
556 if (fCreateLinksInWorkspaceButton != null) {
557 fPreviousCreateLinksValue = fCreateLinksInWorkspaceButton.getSelection();
558 fCreateLinksInWorkspaceButton.setSelection(false);
559 fCreateLinksInWorkspaceButton.setEnabled(false);
560 }
561 }
562 }
563
564 private void directoryRadioSelected() {
565 if (isImportFromDirectory()) {
566 directoryNameField.setEnabled(true);
567 directoryBrowseButton.setEnabled(true);
568 fArchiveNameField.setEnabled(false);
569 fArchiveBrowseButton.setEnabled(false);
570 updateFromSourceField();
571 directoryNameField.setFocus();
572 if (fCreateLinksInWorkspaceButton != null) {
573 fCreateLinksInWorkspaceButton.setSelection(fPreviousCreateLinksValue);
574 fCreateLinksInWorkspaceButton.setEnabled(true);
575 }
576 }
577 }
578
579 // ------------------------------------------------------------------------
580 // Browse for the source directory
581 // ------------------------------------------------------------------------
582
583 @Override
584 public void handleEvent(Event event) {
585 if (event.widget == directoryBrowseButton) {
586 handleSourceDirectoryBrowseButtonPressed();
587 }
588
589 // Avoid overwriting destination path without repeatedly trigger
590 // call of handleEvent();
591 synchronized (fIsDestinationChanged) {
592 if (fIsDestinationChanged == false) {
593 event.display.asyncExec(new Runnable() {
594 @Override
595 public void run() {
596 synchronized (fIsDestinationChanged) {
597 fIsDestinationChanged = true;
598 String path = fTargetFolder.getFullPath().toString();
599 setContainerFieldValue(path);
600 }
601 }
602 });
603 } else {
604 fIsDestinationChanged = false;
605 }
606 }
607 super.handleEvent(event);
608 }
609
610 @Override
611 protected void handleContainerBrowseButtonPressed() {
612 // Do nothing so that destination directory cannot be changed.
613 }
614
615 /**
616 * Handle the button pressed event
617 */
618 protected void handleSourceDirectoryBrowseButtonPressed() {
619 String currentSource = directoryNameField.getText();
620 DirectoryDialog dialog = new DirectoryDialog(directoryNameField.getShell(), SWT.SAVE | SWT.SHEET);
621 dialog.setText(Messages.ImportTraceWizard_SelectTraceDirectoryTitle);
622 dialog.setMessage(Messages.ImportTraceWizard_SelectTraceDirectoryMessage);
623 dialog.setFilterPath(getSourceDirectoryName(currentSource));
624
625 String selectedDirectory = dialog.open();
626 if (selectedDirectory != null) {
627 // Just quit if the directory is not valid
628 if ((getSourceDirectory(selectedDirectory) == null) || selectedDirectory.equals(currentSource)) {
629 return;
630 }
631 // If it is valid then proceed to populate
632 setErrorMessage(null);
633 setSourcePath(selectedDirectory);
634 }
635 }
636
637 /**
638 * Handle the button pressed event
639 *
640 * @param extensions
641 * file extensions used to filter files shown to the user
642 */
643 protected void handleArchiveBrowseButtonPressed(String[] extensions) {
644 FileDialog dialog = new FileDialog(fArchiveNameField.getShell(), SWT.SHEET);
645 dialog.setFilterExtensions(extensions);
646 dialog.setText(Messages.ImportTraceWizard_SelectTraceArchiveTitle);
647 String fileName = fArchiveNameField.getText().trim();
648 if (!fileName.isEmpty()) {
649 File path = new File(fileName).getParentFile();
650 if (path != null && path.exists()) {
651 dialog.setFilterPath(path.toString());
652 }
653 }
654
655 String selectedArchive = dialog.open();
656 if (selectedArchive != null) {
657 setErrorMessage(null);
658 setSourcePath(selectedArchive);
659 updateWidgetEnablements();
660 }
661 }
662
663 private File getSourceDirectory() {
664 if (directoryNameField == null) {
665 return null;
666 }
667 return getSourceDirectory(directoryNameField.getText());
668 }
669
670 private File getSourceArchiveFile() {
671 if (fArchiveNameField == null) {
672 return null;
673 }
674
675 return getSourceArchiveFile(fArchiveNameField.getText());
676 }
677
678 private String getSourceContainerPath() {
679 if (isImportFromDirectory()) {
680 File sourceDirectory = getSourceDirectory();
681 if (sourceDirectory != null) {
682 return sourceDirectory.getAbsolutePath();
683 }
684 }
685 File sourceArchiveFile = getSourceArchiveFile();
686 if (sourceArchiveFile != null) {
687 return sourceArchiveFile.getParent();
688 }
689 return null;
690 }
691
692 private static File getSourceDirectory(String path) {
693 File sourceDirectory = new File(getSourceDirectoryName(path));
694 if (!sourceDirectory.exists() || !sourceDirectory.isDirectory()) {
695 return null;
696 }
697
698 return sourceDirectory;
699 }
700
701 private static File getSourceArchiveFile(String path) {
702 File sourceArchiveFile = new File(path);
703 if (!sourceArchiveFile.exists() || sourceArchiveFile.isDirectory()) {
704 return null;
705 }
706
707 return sourceArchiveFile;
708 }
709
710 private static String getSourceDirectoryName(String sourceName) {
711 IPath result = new Path(sourceName.trim());
712 if (result.getDevice() != null && result.segmentCount() == 0) {
713 result = result.addTrailingSeparator();
714 } else {
715 result = result.removeTrailingSeparator();
716 }
717 return result.toOSString();
718 }
719
720 private void updateFromSourceField() {
721 setSourcePath(getSourceField().getText());
722 updateWidgetEnablements();
723 }
724
725 private Combo getSourceField() {
726 if (directoryNameField == null) {
727 return fArchiveNameField;
728 }
729
730 return directoryNameField.isEnabled() ? directoryNameField : fArchiveNameField;
731 }
732
733 /**
734 * Set the source path that was selected by the user by various input
735 * methods (Browse button, typing, etc).
736 *
737 * Clients can also call this to set the path programmatically (hard-coded
738 * initial path) and this can also be overridden to be notified when the
739 * source path changes.
740 *
741 * @param path
742 * the source path
743 */
744 protected void setSourcePath(String path) {
745 Combo sourceField = getSourceField();
746 if (sourceField == null) {
747 return;
748 }
749
750 if (path.length() > 0) {
751 String[] currentItems = sourceField.getItems();
752 int selectionIndex = -1;
753 for (int i = 0; i < currentItems.length; i++) {
754 if (currentItems[i].equals(path)) {
755 selectionIndex = i;
756 }
757 }
758 if (selectionIndex < 0) {
759 int oldLength = currentItems.length;
760 String[] newItems = new String[oldLength + 1];
761 System.arraycopy(currentItems, 0, newItems, 0, oldLength);
762 newItems[oldLength] = path;
763 sourceField.setItems(newItems);
764 selectionIndex = oldLength;
765 }
766 sourceField.select(selectionIndex);
767 }
768 resetSelection();
769 }
770
771 // ------------------------------------------------------------------------
772 // File Selection Group (forked WizardFileSystemResourceImportPage1)
773 // ------------------------------------------------------------------------
774 private void resetSelection() {
775 if (fSelectionGroupRoot != null) {
776 disposeSelectionGroupRoot();
777 }
778 fSelectionGroupRoot = getFileSystemTree();
779 fSelectionGroup.setRoot(fSelectionGroupRoot);
780 }
781
782 private void disposeSelectionGroupRoot() {
783 if (fSelectionGroupRoot != null && fSelectionGroupRoot.getProvider() != null) {
784 FileSystemObjectImportStructureProvider provider = fSelectionGroupRoot.getProvider();
785 provider.dispose();
786 fSelectionGroupRoot = null;
787 }
788 }
789
790 private TraceFileSystemElement getFileSystemTree() {
791 IFileSystemObject rootElement = null;
792 FileSystemObjectImportStructureProvider importStructureProvider = null;
793
794 // Import from directory
795 if (isImportFromDirectory()) {
796 importStructureProvider = new FileSystemObjectImportStructureProvider(FileSystemStructureProvider.INSTANCE, null);
797 File sourceDirectory = getSourceDirectory();
798 if (sourceDirectory == null) {
799 return null;
800 }
801 rootElement = importStructureProvider.getIFileSystemObject(sourceDirectory);
802 } else {
803 // Import from archive
804 FileSystemObjectLeveledImportStructureProvider leveledImportStructureProvider = null;
805 String archivePath = getSourceArchiveFile() != null ? getSourceArchiveFile().getAbsolutePath() : ""; //$NON-NLS-1$
806 if (ArchiveFileManipulations.isTarFile(archivePath)) {
807 if (ensureTarSourceIsValid(archivePath)) {
808 // We close the file when we dispose the import provider,
809 // see disposeSelectionGroupRoot
810 TarFile tarFile = getSpecifiedTarSourceFile(archivePath);
811 leveledImportStructureProvider = new FileSystemObjectLeveledImportStructureProvider(new TarLeveledStructureProvider(tarFile), archivePath);
812 }
813 } else if (ensureZipSourceIsValid(archivePath)) {
814 // We close the file when we dispose the import provider, see
815 // disposeSelectionGroupRoot
816 @SuppressWarnings("resource")
817 ZipFile zipFile = getSpecifiedZipSourceFile(archivePath);
818 leveledImportStructureProvider = new FileSystemObjectLeveledImportStructureProvider(new ZipLeveledStructureProvider(zipFile), archivePath);
819 }
820 if (leveledImportStructureProvider == null) {
821 return null;
822 }
823 rootElement = leveledImportStructureProvider.getRoot();
824 importStructureProvider = leveledImportStructureProvider;
825 }
826
827 if (rootElement == null) {
828 return null;
829 }
830
831 return selectFiles(rootElement, importStructureProvider);
832 }
833
834 /**
835 * An import provider that makes use of the IFileSystemObject abstraction
836 * instead of using plain file system objects (File, TarEntry, ZipEntry)
837 */
838 private static class FileSystemObjectImportStructureProvider implements IImportStructureProvider {
839
840 private IImportStructureProvider fImportProvider;
841 private String fArchivePath;
842
843 private FileSystemObjectImportStructureProvider(IImportStructureProvider importStructureProvider, String archivePath) {
844 fImportProvider = importStructureProvider;
845 fArchivePath = archivePath;
846 }
847
848 @Override
849 public List<IFileSystemObject> getChildren(Object element) {
850 @SuppressWarnings("rawtypes")
851 List children = fImportProvider.getChildren(((IFileSystemObject) element).getRawFileSystemObject());
852 List<IFileSystemObject> adapted = new ArrayList<>(children.size());
853 for (Object o : children) {
854 adapted.add(getIFileSystemObject(o));
855 }
856 return adapted;
857 }
858
859 public IFileSystemObject getIFileSystemObject(Object o) {
860 if (o == null) {
861 return null;
862 }
863
864 if (o instanceof File) {
865 return new FileFileSystemObject((File) o);
866 } else if (o instanceof TarEntry) {
867 return new TarFileSystemObject((TarEntry) o, fArchivePath);
868 } else if (o instanceof ZipEntry) {
869 return new ZipFileSystemObject((ZipEntry) o, fArchivePath);
870 }
871
872 throw new IllegalArgumentException("Object type not handled"); //$NON-NLS-1$
873 }
874
875 @Override
876 public InputStream getContents(Object element) {
877 return fImportProvider.getContents(((IFileSystemObject) element).getRawFileSystemObject());
878 }
879
880 @Override
881 public String getFullPath(Object element) {
882 return fImportProvider.getFullPath(((IFileSystemObject) element).getRawFileSystemObject());
883 }
884
885 @Override
886 public String getLabel(Object element) {
887 return fImportProvider.getLabel(((IFileSystemObject) element).getRawFileSystemObject());
888 }
889
890 @Override
891 public boolean isFolder(Object element) {
892 return fImportProvider.isFolder(((IFileSystemObject) element).getRawFileSystemObject());
893 }
894
895 /**
896 * Disposes of the resources associated with the provider.
897 */
898 public void dispose() {
899 }
900 }
901
902 /**
903 * An import provider that both supports using IFileSystemObject and adds
904 * "archive functionality" by delegating to a leveled import provider
905 * (TarLeveledStructureProvider, ZipLeveledStructureProvider)
906 */
907 private static class FileSystemObjectLeveledImportStructureProvider extends FileSystemObjectImportStructureProvider implements ILeveledImportStructureProvider {
908
909 private ILeveledImportStructureProvider fLeveledImportProvider;
910
911 private FileSystemObjectLeveledImportStructureProvider(ILeveledImportStructureProvider importStructureProvider, String archivePath) {
912 super(importStructureProvider, archivePath);
913 fLeveledImportProvider = importStructureProvider;
914 }
915
916 @Override
917 public IFileSystemObject getRoot() {
918 return getIFileSystemObject(fLeveledImportProvider.getRoot());
919 }
920
921 @Override
922 public void setStrip(int level) {
923 fLeveledImportProvider.setStrip(level);
924 }
925
926 @Override
927 public int getStrip() {
928 return fLeveledImportProvider.getStrip();
929 }
930
931 @Override
932 public boolean closeArchive() {
933 return fLeveledImportProvider.closeArchive();
934 }
935 }
936
937 @SuppressWarnings("resource")
938 private boolean ensureZipSourceIsValid(String archivePath) {
939 ZipFile specifiedFile = getSpecifiedZipSourceFile(archivePath);
940 if (specifiedFile == null) {
941 return false;
942 }
943 return ArchiveFileManipulations.closeZipFile(specifiedFile, getShell());
944 }
945
946 private boolean ensureTarSourceIsValid(String archivePath) {
947 TarFile specifiedFile = getSpecifiedTarSourceFile(archivePath);
948 if (specifiedFile == null) {
949 return false;
950 }
951 return ArchiveFileManipulations.closeTarFile(specifiedFile, getShell());
952 }
953
954 private static ZipFile getSpecifiedZipSourceFile(String fileName) {
955 if (fileName.length() == 0) {
956 return null;
957 }
958
959 try {
960 return new ZipFile(fileName);
961 } catch (ZipException e) {
962 // ignore
963 } catch (IOException e) {
964 // ignore
965 }
966
967 return null;
968 }
969
970 private static TarFile getSpecifiedTarSourceFile(String fileName) {
971 if (fileName.length() == 0) {
972 return null;
973 }
974
975 try {
976 return new TarFile(fileName);
977 } catch (TarException e) {
978 // ignore
979 } catch (IOException e) {
980 // ignore
981 }
982
983 return null;
984 }
985
986 private TraceFileSystemElement selectFiles(final IFileSystemObject rootFileSystemObject,
987 final FileSystemObjectImportStructureProvider structureProvider) {
988 final TraceFileSystemElement[] results = new TraceFileSystemElement[1];
989 BusyIndicator.showWhile(getShell().getDisplay(), new Runnable() {
990 @Override
991 public void run() {
992 // Create the root element from the supplied file system object
993 results[0] = createRootElement(rootFileSystemObject, structureProvider);
994 }
995 });
996 return results[0];
997 }
998
999 private static TraceFileSystemElement createRootElement(IFileSystemObject element,
1000 FileSystemObjectImportStructureProvider provider) {
1001 boolean isContainer = provider.isFolder(element);
1002 String elementLabel = provider.getLabel(element);
1003
1004 // Use an empty label so that display of the element's full name
1005 // doesn't include a confusing label
1006 TraceFileSystemElement dummyParent = new TraceFileSystemElement("", null, true, provider);//$NON-NLS-1$
1007 Object dummyParentFileSystemObject = element;
1008 Object rawFileSystemObject = element.getRawFileSystemObject();
1009 if (rawFileSystemObject instanceof File) {
1010 dummyParentFileSystemObject = provider.getIFileSystemObject(((File) rawFileSystemObject).getParentFile());
1011 }
1012 dummyParent.setFileSystemObject(dummyParentFileSystemObject);
1013 dummyParent.setPopulated();
1014 TraceFileSystemElement result = new TraceFileSystemElement(
1015 elementLabel, dummyParent, isContainer, provider);
1016 result.setFileSystemObject(element);
1017
1018 // Get the files for the element so as to build the first level
1019 result.getFiles();
1020
1021 return dummyParent;
1022 }
1023
1024 // ------------------------------------------------------------------------
1025 // Trace Type Group
1026 // ------------------------------------------------------------------------
1027 private final void createTraceTypeGroup(Composite parent) {
1028 Composite composite = new Composite(parent, SWT.NONE);
1029 GridLayout layout = new GridLayout();
1030 layout.numColumns = 3;
1031 layout.makeColumnsEqualWidth = false;
1032 composite.setLayout(layout);
1033 composite.setFont(parent.getFont());
1034 GridData buttonData = new GridData(SWT.FILL, SWT.FILL, true, false);
1035 composite.setLayoutData(buttonData);
1036
1037 // Trace type label ("Trace Type:")
1038 Label typeLabel = new Label(composite, SWT.NONE);
1039 typeLabel.setText(Messages.ImportTraceWizard_TraceType);
1040 typeLabel.setFont(parent.getFont());
1041
1042 // Trace type combo
1043 fTraceTypes = new Combo(composite, SWT.BORDER | SWT.READ_ONLY);
1044 GridData data = new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1);
1045 fTraceTypes.setLayoutData(data);
1046 fTraceTypes.setFont(parent.getFont());
1047
1048 String[] availableTraceTypes = TmfTraceType.getAvailableTraceTypes();
1049 String[] traceTypeList = new String[availableTraceTypes.length + 1];
1050 traceTypeList[0] = TRACE_TYPE_AUTO_DETECT;
1051 for (int i = 0; i < availableTraceTypes.length; i++) {
1052 traceTypeList[i + 1] = availableTraceTypes[i];
1053 }
1054 fTraceTypes.setItems(traceTypeList);
1055 fTraceTypes.addSelectionListener(new SelectionAdapter() {
1056 @Override
1057 public void widgetSelected(SelectionEvent e) {
1058 updateWidgetEnablements();
1059 boolean enabled = fTraceTypes.getText().equals(TRACE_TYPE_AUTO_DETECT);
1060 fImportUnrecognizedButton.setEnabled(enabled);
1061 }
1062 });
1063 fTraceTypes.select(0);
1064
1065 // Unrecognized checkbox
1066 fImportUnrecognizedButton = new Button(composite, SWT.CHECK);
1067 fImportUnrecognizedButton.setSelection(true);
1068 fImportUnrecognizedButton.setText(Messages.ImportTraceWizard_ImportUnrecognized);
1069 }
1070
1071 // ------------------------------------------------------------------------
1072 // Options
1073 // ------------------------------------------------------------------------
1074
1075 @Override
1076 protected void createOptionsGroupButtons(Group optionsGroup) {
1077
1078 // Overwrite checkbox
1079 fOverwriteExistingResourcesCheckbox = new Button(optionsGroup, SWT.CHECK);
1080 fOverwriteExistingResourcesCheckbox.setFont(optionsGroup.getFont());
1081 fOverwriteExistingResourcesCheckbox.setText(Messages.ImportTraceWizard_OverwriteExistingTrace);
1082 fOverwriteExistingResourcesCheckbox.setSelection(false);
1083
1084 // Create links checkbox
1085 fCreateLinksInWorkspaceButton = new Button(optionsGroup, SWT.CHECK);
1086 fCreateLinksInWorkspaceButton.setFont(optionsGroup.getFont());
1087 fCreateLinksInWorkspaceButton.setText(Messages.ImportTraceWizard_CreateLinksInWorkspace);
1088 fCreateLinksInWorkspaceButton.setSelection(true);
1089
1090 fCreateLinksInWorkspaceButton.addSelectionListener(new SelectionAdapter() {
1091 @Override
1092 public void widgetSelected(SelectionEvent e) {
1093 updateWidgetEnablements();
1094 }
1095 });
1096
1097 fPreserveFolderStructureButton = new Button(optionsGroup, SWT.CHECK);
1098 fPreserveFolderStructureButton.setFont(optionsGroup.getFont());
1099 fPreserveFolderStructureButton.setText(Messages.ImportTraceWizard_PreserveFolderStructure);
1100 fPreserveFolderStructureButton.setSelection(true);
1101
1102 updateWidgetEnablements();
1103 }
1104
1105 // ------------------------------------------------------------------------
1106 // Determine if the finish button can be enabled
1107 // ------------------------------------------------------------------------
1108 @Override
1109 public boolean validateSourceGroup() {
1110
1111 File source = isImportFromDirectory() ? getSourceDirectory() : getSourceArchiveFile();
1112 if (source == null) {
1113 setMessage(Messages.ImportTraceWizard_SelectTraceSourceEmpty);
1114 setErrorMessage(null);
1115 return false;
1116 }
1117
1118 if (sourceConflictsWithDestination(new Path(source.getPath()))) {
1119 setMessage(null);
1120 setErrorMessage(getSourceConflictMessage());
1121 return false;
1122 }
1123
1124 if (!isImportFromDirectory()) {
1125 if (!ensureTarSourceIsValid(source.getAbsolutePath()) && !ensureZipSourceIsValid(source.getAbsolutePath())) {
1126 setMessage(null);
1127 setErrorMessage(Messages.ImportTraceWizard_BadArchiveFormat);
1128 return false;
1129 }
1130 }
1131
1132 if (fSelectionGroup.getCheckedElementCount() == 0) {
1133 setMessage(null);
1134 setErrorMessage(Messages.ImportTraceWizard_SelectTraceNoneSelected);
1135 return false;
1136 }
1137
1138 IContainer container = getSpecifiedContainer();
1139 if (container != null && container.isVirtual()) {
1140 if (Platform.getPreferencesService().getBoolean(Activator.PLUGIN_ID, ResourcesPlugin.PREF_DISABLE_LINKING, false, null)) {
1141 setMessage(null);
1142 setErrorMessage(Messages.ImportTraceWizard_CannotImportFilesUnderAVirtualFolder);
1143 return false;
1144 }
1145 if (fCreateLinksInWorkspaceButton == null || !fCreateLinksInWorkspaceButton.getSelection()) {
1146 setMessage(null);
1147 setErrorMessage(Messages.ImportTraceWizard_HaveToCreateLinksUnderAVirtualFolder);
1148 return false;
1149 }
1150 }
1151
1152 setErrorMessage(null);
1153 return true;
1154 }
1155
1156 private boolean isImportFromDirectory() {
1157 return fImportFromDirectoryRadio != null && fImportFromDirectoryRadio.getSelection();
1158 }
1159
1160 @Override
1161 protected void restoreWidgetValues() {
1162 super.restoreWidgetValues();
1163
1164 IDialogSettings settings = getDialogSettings();
1165 boolean value;
1166 if (fImportUnrecognizedButton != null) {
1167 if (settings.get(getPageStoreKey(IMPORT_WIZARD_IMPORT_UNRECOGNIZED_ID)) == null) {
1168 value = true;
1169 } else {
1170 value = settings.getBoolean(getPageStoreKey(IMPORT_WIZARD_IMPORT_UNRECOGNIZED_ID));
1171 }
1172 fImportUnrecognizedButton.setSelection(value);
1173 }
1174
1175 if (fPreserveFolderStructureButton != null) {
1176 if (settings.get(getPageStoreKey(IMPORT_WIZARD_PRESERVE_FOLDERS_ID)) == null) {
1177 value = true;
1178 } else {
1179 value = settings.getBoolean(getPageStoreKey(IMPORT_WIZARD_PRESERVE_FOLDERS_ID));
1180 }
1181 fPreserveFolderStructureButton.setSelection(value);
1182 }
1183
1184 if (settings.get(getPageStoreKey(IMPORT_WIZARD_IMPORT_FROM_DIRECTORY_ID)) == null) {
1185 value = true;
1186 } else {
1187 value = settings.getBoolean(getPageStoreKey(IMPORT_WIZARD_IMPORT_FROM_DIRECTORY_ID));
1188 }
1189
1190 if (directoryNameField != null) {
1191 restoreComboValues(directoryNameField, settings, getPageStoreKey(IMPORT_WIZARD_ROOT_DIRECTORY_ID));
1192 }
1193 if (fArchiveNameField != null) {
1194 restoreComboValues(fArchiveNameField, settings, getPageStoreKey(IMPORT_WIZARD_ARCHIVE_FILE_NAME_ID));
1195 }
1196
1197 if (fImportFromDirectoryRadio != null) {
1198 fImportFromDirectoryRadio.setSelection(value);
1199 if (value) {
1200 directoryRadioSelected();
1201 }
1202 }
1203 if (fImportFromArchiveRadio != null) {
1204 fImportFromArchiveRadio.setSelection(!value);
1205 if (!value) {
1206 archiveRadioSelected();
1207 }
1208 }
1209 }
1210
1211 @Override
1212 protected void saveWidgetValues() {
1213 // Persist dialog settings
1214 IDialogSettings settings = getDialogSettings();
1215 if (fImportUnrecognizedButton != null) {
1216 settings.put(getPageStoreKey(IMPORT_WIZARD_IMPORT_UNRECOGNIZED_ID), fImportUnrecognizedButton.getSelection());
1217 }
1218 if (fPreserveFolderStructureButton != null) {
1219 settings.put(getPageStoreKey(IMPORT_WIZARD_PRESERVE_FOLDERS_ID), fPreserveFolderStructureButton.getSelection());
1220 }
1221 settings.put(getPageStoreKey(IMPORT_WIZARD_IMPORT_FROM_DIRECTORY_ID), isImportFromDirectory());
1222
1223 if (directoryNameField != null) {
1224 saveComboValues(directoryNameField, settings, getPageStoreKey(IMPORT_WIZARD_ROOT_DIRECTORY_ID));
1225 }
1226 if (fArchiveNameField != null) {
1227 saveComboValues(fArchiveNameField, settings, getPageStoreKey(IMPORT_WIZARD_ARCHIVE_FILE_NAME_ID));
1228 }
1229 }
1230
1231 private String getPageStoreKey(String key) {
1232 return getName() + key;
1233 }
1234
1235 private static void restoreComboValues(Combo combo, IDialogSettings settings, String key) {
1236 String[] directoryNames = settings.getArray(key);
1237 if ((directoryNames != null) && (directoryNames.length != 0)) {
1238 for (int i = 0; i < directoryNames.length; i++) {
1239 combo.add(directoryNames[i]);
1240 }
1241 }
1242 }
1243
1244 private void saveComboValues(Combo combo, IDialogSettings settings, String key) {
1245 // update names history
1246 String[] directoryNames = settings.getArray(key);
1247 if (directoryNames == null) {
1248 directoryNames = new String[0];
1249 }
1250
1251 String items[] = combo.getItems();
1252 for (int i = 0; i < items.length; i++) {
1253 directoryNames = addToHistory(directoryNames, items[i]);
1254 }
1255 settings.put(key, directoryNames);
1256 }
1257
1258 // ------------------------------------------------------------------------
1259 // Import the trace(s)
1260 // ------------------------------------------------------------------------
1261
1262 /**
1263 * Finish the import.
1264 *
1265 * @return <code>true</code> if successful else <code>false</code>
1266 */
1267 public boolean finish() {
1268 String traceTypeName = getImportTraceTypeId();
1269 String traceId = null;
1270 if (!TRACE_TYPE_AUTO_DETECT.equals(traceTypeName)) {
1271 String tokens[] = traceTypeName.split(SEPARATOR, 2);
1272 if (tokens.length < 2) {
1273 return false;
1274 }
1275 traceId = TmfTraceType.getTraceTypeId(tokens[0], tokens[1]);
1276 }
1277
1278 // Save dialog settings
1279 saveWidgetValues();
1280
1281 IPath baseSourceContainerPath = new Path(getSourceContainerPath());
1282 boolean importFromArchive = getSourceArchiveFile() != null;
1283 int importOptionFlags = getImportOptionFlags();
1284
1285 final TraceValidateAndImportOperation operation = new TraceValidateAndImportOperation(traceId, baseSourceContainerPath, getContainerFullPath(), importFromArchive,
1286 importOptionFlags);
1287
1288 IStatus status = Status.OK_STATUS;
1289 try {
1290 getContainer().run(true, true, new IRunnableWithProgress() {
1291 @Override
1292 public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
1293 operation.run(monitor);
1294 monitor.done();
1295 }
1296 });
1297
1298 status = operation.getStatus();
1299 } catch (InvocationTargetException e) {
1300 status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.ImportTraceWizard_ImportProblem, e);
1301 } catch (InterruptedException e) {
1302 status = Status.CANCEL_STATUS;
1303 }
1304 if (!status.isOK()) {
1305 if (status.getSeverity() == IStatus.CANCEL) {
1306 setMessage(Messages.ImportTraceWizard_ImportOperationCancelled);
1307 setErrorMessage(null);
1308 } else {
1309 if (status.getException() != null) {
1310 displayErrorDialog(status.getMessage() + ": " + status.getException()); //$NON-NLS-1$
1311 }
1312 setMessage(null);
1313 setErrorMessage(Messages.ImportTraceWizard_ImportProblem);
1314 }
1315 return false;
1316 }
1317 setErrorMessage(null);
1318 return true;
1319 }
1320
1321 /**
1322 * Get the trace type id to import as. This can also return
1323 * {@link #TRACE_TYPE_AUTO_DETECT} to communicate that automatic trace type
1324 * detection will occur instead of setting a specific trace type when
1325 * importing the traces.
1326 *
1327 * @return the trace type id or {@link #TRACE_TYPE_AUTO_DETECT}
1328 */
1329 protected String getImportTraceTypeId() {
1330 return fTraceTypes.getText();
1331 }
1332
1333 /**
1334 * Get import options in the form of flags (bits).
1335 *
1336 * @return the import flags.
1337 * @see #OPTION_CREATE_LINKS_IN_WORKSPACE
1338 * @see #OPTION_IMPORT_UNRECOGNIZED_TRACES
1339 * @see #OPTION_OVERWRITE_EXISTING_RESOURCES
1340 * @see #OPTION_PRESERVE_FOLDER_STRUCTURE
1341 */
1342 protected int getImportOptionFlags() {
1343 int flags = 0;
1344 if (fCreateLinksInWorkspaceButton != null && fCreateLinksInWorkspaceButton.getSelection()) {
1345 flags |= OPTION_CREATE_LINKS_IN_WORKSPACE;
1346 }
1347 if (fImportUnrecognizedButton != null && fImportUnrecognizedButton.getSelection()) {
1348 flags |= OPTION_IMPORT_UNRECOGNIZED_TRACES;
1349 }
1350 if (fOverwriteExistingResourcesCheckbox != null && fOverwriteExistingResourcesCheckbox.getSelection()) {
1351 flags |= OPTION_OVERWRITE_EXISTING_RESOURCES;
1352 }
1353 if (fPreserveFolderStructureButton != null && fPreserveFolderStructureButton.getSelection()) {
1354 flags |= OPTION_PRESERVE_FOLDER_STRUCTURE;
1355 }
1356 return flags;
1357 }
1358
1359 @Override
1360 public void dispose() {
1361 super.dispose();
1362 disposeSelectionGroupRoot();
1363 }
1364
1365 // ------------------------------------------------------------------------
1366 // Classes
1367 // ------------------------------------------------------------------------
1368
1369 private class TraceValidateAndImportOperation {
1370 private IStatus fStatus;
1371 private String fTraceType;
1372 private IPath fDestinationContainerPath;
1373 private IPath fBaseSourceContainerPath;
1374 private boolean fImportFromArchive;
1375 private int fImportOptionFlags;
1376 private ImportConfirmation fConfirmationMode = ImportConfirmation.SKIP;
1377
1378 private TraceValidateAndImportOperation(String traceId, IPath baseSourceContainerPath, IPath destinationContainerPath, boolean importFromArchive, int importOptionFlags) {
1379 fTraceType = traceId;
1380 fBaseSourceContainerPath = baseSourceContainerPath;
1381 fDestinationContainerPath = destinationContainerPath;
1382 fImportOptionFlags = importOptionFlags;
1383 fImportFromArchive = importFromArchive;
1384
1385 boolean overwriteExistingResources = (importOptionFlags & OPTION_OVERWRITE_EXISTING_RESOURCES) != 0;
1386 if (overwriteExistingResources) {
1387 fConfirmationMode = ImportConfirmation.OVERWRITE_ALL;
1388 }
1389 }
1390
1391 public void run(IProgressMonitor progressMonitor) {
1392 String currentPath = null;
1393 final Map<String, TraceFileSystemElement> folderElements = new HashMap<>();
1394 try {
1395
1396 final ArrayList<TraceFileSystemElement> fileSystemElements = new ArrayList<>();
1397 IElementFilter passThroughFilter = new IElementFilter() {
1398
1399 @Override
1400 public void filterElements(Collection elements, IProgressMonitor monitor) {
1401 fileSystemElements.addAll(elements);
1402 }
1403
1404 @Override
1405 public void filterElements(Object[] elements, IProgressMonitor monitor) {
1406 for (int i = 0; i < elements.length; i++) {
1407 fileSystemElements.add((TraceFileSystemElement) elements[i]);
1408 }
1409 }
1410 };
1411
1412 // List fileSystemElements will be filled using the
1413 // passThroughFilter
1414 SubMonitor subMonitor = SubMonitor.convert(progressMonitor, 1);
1415 fSelectionGroup.getAllCheckedListItems(passThroughFilter, subMonitor);
1416
1417 // Check if operation was cancelled.
1418 ModalContext.checkCanceled(subMonitor);
1419
1420 Iterator<TraceFileSystemElement> fileSystemElementsIter = fileSystemElements.iterator();
1421 IFolder destTempFolder = null;
1422 subMonitor = SubMonitor.convert(progressMonitor, fileSystemElements.size());
1423 if (fImportFromArchive) {
1424 // When importing from archive, we first extract the
1425 // *selected* files to a temporary folder then create a new
1426 // Iterator<TraceFileSystemElement> that points to the
1427 // extracted files. This way, the import operator can
1428 // continue as it normally would.
1429
1430 subMonitor = SubMonitor.convert(progressMonitor, fileSystemElements.size() * 2);
1431 destTempFolder = fTargetFolder.getProject().getFolder(TRACE_IMPORT_TEMP_FOLDER);
1432 if (destTempFolder.exists()) {
1433 SubProgressMonitor monitor = new SubProgressMonitor(subMonitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK);
1434 destTempFolder.delete(true, monitor);
1435 }
1436 SubProgressMonitor monitor = new SubProgressMonitor(subMonitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK);
1437 destTempFolder.create(IResource.HIDDEN, true, monitor);
1438
1439 fileSystemElementsIter = extractSelectedFiles(fileSystemElementsIter, destTempFolder, subMonitor);
1440 // We need to update the source container path because the
1441 // "preserve folder structure" option would create the
1442 // wrong folders otherwise.
1443 fBaseSourceContainerPath = destTempFolder.getLocation();
1444 }
1445
1446 while (fileSystemElementsIter.hasNext()) {
1447 ModalContext.checkCanceled(progressMonitor);
1448 currentPath = null;
1449 TraceFileSystemElement element = fileSystemElementsIter.next();
1450 IFileSystemObject fileSystemObject = element.getFileSystemObject();
1451 String resourcePath = element.getFileSystemObject().getAbsolutePath(fBaseSourceContainerPath.toOSString());
1452 element.setDestinationContainerPath(computeDestinationContainerPath(new Path(resourcePath)));
1453
1454 currentPath = resourcePath;
1455 SubMonitor sub = subMonitor.newChild(1);
1456 if (element.isDirectory()) {
1457 if (!folderElements.containsKey(resourcePath)) {
1458 if (isDirectoryTrace(element)) {
1459 folderElements.put(resourcePath, element);
1460 validateAndImportTrace(element, sub);
1461 }
1462 }
1463 } else {
1464 TraceFileSystemElement parentElement = (TraceFileSystemElement) element.getParent();
1465 String parentPath = parentElement.getFileSystemObject().getAbsolutePath(fBaseSourceContainerPath.toOSString());
1466 parentElement.setDestinationContainerPath(computeDestinationContainerPath(new Path(parentPath)));
1467 currentPath = parentPath;
1468 if (!folderElements.containsKey(parentPath)) {
1469 if (isDirectoryTrace(parentElement)) {
1470 folderElements.put(parentPath, parentElement);
1471 validateAndImportTrace(parentElement, sub);
1472 } else {
1473 if (fileSystemObject.exists()) {
1474 validateAndImportTrace(element, sub);
1475 }
1476 }
1477 }
1478 }
1479 }
1480
1481 if (destTempFolder != null && destTempFolder.exists()) {
1482 destTempFolder.delete(true, progressMonitor);
1483 }
1484
1485 setStatus(Status.OK_STATUS);
1486 } catch (InterruptedException e) {
1487 setStatus(Status.CANCEL_STATUS);
1488 } catch (Exception e) {
1489 String errorMessage = Messages.ImportTraceWizard_ImportProblem + ": " + //$NON-NLS-1$
1490 (currentPath != null ? currentPath : ""); //$NON-NLS-1$
1491 Activator.getDefault().logError(errorMessage, e);
1492 setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, errorMessage, e));
1493 }
1494 }
1495
1496 private Iterator<TraceFileSystemElement> extractSelectedFiles(Iterator<TraceFileSystemElement> fileSystemElementsIter, IFolder tempFolder, IProgressMonitor progressMonitor) throws InterruptedException,
1497 InvocationTargetException {
1498 List<TraceFileSystemElement> subList = new ArrayList<>();
1499 Map<IPath, String> sourceLocationMap = new HashMap<>();
1500 // Collect all the elements
1501 while (fileSystemElementsIter.hasNext()) {
1502 ModalContext.checkCanceled(progressMonitor);
1503 TraceFileSystemElement element = fileSystemElementsIter.next();
1504 sourceLocationMap.put(new Path(element.getFileSystemObject().getName()).removeTrailingSeparator(), element.getSourceLocation());
1505 TraceFileSystemElement parentElement = (TraceFileSystemElement) element.getParent();
1506 sourceLocationMap.put(new Path(parentElement.getFileSystemObject().getName()).removeTrailingSeparator(), parentElement.getSourceLocation());
1507 if (element.isDirectory()) {
1508 Object[] array = element.getFiles().getChildren();
1509 for (int i = 0; i < array.length; i++) {
1510 subList.add((TraceFileSystemElement) array[i]);
1511 }
1512 }
1513 subList.add(element);
1514 }
1515
1516 // Find a sensible root element
1517 TraceFileSystemElement root = subList.get(0);
1518 while (root.getParent() != null) {
1519 root = (TraceFileSystemElement) root.getParent();
1520 }
1521
1522 ImportProvider fileSystemStructureProvider = new ImportProvider();
1523
1524 IOverwriteQuery myQueryImpl = new IOverwriteQuery() {
1525 @Override
1526 public String queryOverwrite(String file) {
1527 return IOverwriteQuery.NO_ALL;
1528 }
1529 };
1530
1531 progressMonitor.setTaskName(Messages.ImportTraceWizard_ExtractImportOperationTaskName);
1532 IPath containerPath = tempFolder.getFullPath();
1533 ImportOperation operation = new ImportOperation(containerPath, root, fileSystemStructureProvider, myQueryImpl, subList);
1534 operation.setContext(getShell());
1535
1536 operation.setCreateContainerStructure(true);
1537 operation.setOverwriteResources(false);
1538 operation.setVirtualFolders(false);
1539
1540 operation.run(new SubProgressMonitor(progressMonitor, subList.size(), SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK));
1541
1542 // Create the new import provider and root element based on the
1543 // extracted temp folder
1544 FileSystemObjectImportStructureProvider importStructureProvider = new FileSystemObjectImportStructureProvider(FileSystemStructureProvider.INSTANCE, null);
1545 IFileSystemObject rootElement = importStructureProvider.getIFileSystemObject(new File(tempFolder.getLocation().toOSString()));
1546 TraceFileSystemElement createRootElement = createRootElement(rootElement, importStructureProvider);
1547 List<TraceFileSystemElement> list = new ArrayList<>();
1548 getAllChildren(list, createRootElement);
1549 Iterator<TraceFileSystemElement> extractedElementsIter = list.iterator();
1550 IPath tempPath = new Path(tempFolder.getLocation().toOSString());
1551 for (TraceFileSystemElement element : list) {
1552 IPath path = new Path(((File) element.getFileSystemObject().getRawFileSystemObject()).getAbsolutePath()).makeRelativeTo(tempPath);
1553 element.setSourceLocation(sourceLocationMap.get(path));
1554 TraceFileSystemElement parentElement = (TraceFileSystemElement) element.getParent();
1555 IPath parentPath = new Path(((File) parentElement.getFileSystemObject().getRawFileSystemObject()).getAbsolutePath()).makeRelativeTo(tempPath);
1556 parentElement.setSourceLocation(sourceLocationMap.get(parentPath));
1557 }
1558 return extractedElementsIter;
1559 }
1560
1561 /**
1562 * Get all the TraceFileSystemElements recursively.
1563 *
1564 * @param result
1565 * the list accumulating the result
1566 * @param rootElement
1567 * the root element of the file system to be imported
1568 */
1569 private void getAllChildren(List<TraceFileSystemElement> result, TraceFileSystemElement rootElement) {
1570 AdaptableList files = rootElement.getFiles();
1571 for (Object file : files.getChildren()) {
1572 result.add((TraceFileSystemElement) file);
1573 }
1574
1575 AdaptableList folders = rootElement.getFolders();
1576 for (Object folder : folders.getChildren()) {
1577 getAllChildren(result, (TraceFileSystemElement) folder);
1578 }
1579 }
1580
1581 private IPath computeDestinationContainerPath(Path resourcePath) {
1582 IPath destinationContainerPath = fDestinationContainerPath;
1583
1584 // We need to figure out the new destination path relative to the
1585 // selected "base" source directory.
1586 // Here for example, the selected source directory is /home/user
1587 if ((fImportOptionFlags & OPTION_PRESERVE_FOLDER_STRUCTURE) != 0) {
1588 // /home/user/bar/foo/trace -> /home/user/bar/foo
1589 IPath sourceContainerPath = resourcePath.removeLastSegments(1);
1590 if (fBaseSourceContainerPath.equals(resourcePath)) {
1591 // Use resourcePath directory if fBaseSourceContainerPath
1592 // points to a directory trace
1593 sourceContainerPath = resourcePath;
1594 }
1595 // /home/user/bar/foo, /home/user -> bar/foo
1596 IPath relativeContainerPath = sourceContainerPath.makeRelativeTo(fBaseSourceContainerPath);
1597 // project/Traces + bar/foo -> project/Traces/bar/foo
1598 destinationContainerPath = fDestinationContainerPath.append(relativeContainerPath);
1599 }
1600 return destinationContainerPath;
1601 }
1602
1603 private void validateAndImportTrace(TraceFileSystemElement fileSystemElement, IProgressMonitor monitor)
1604 throws TmfTraceImportException, CoreException, InvocationTargetException, InterruptedException {
1605 String parentContainerPath = fBaseSourceContainerPath.toOSString();
1606 String path = fileSystemElement.getFileSystemObject().getAbsolutePath(parentContainerPath);
1607 TraceTypeHelper traceTypeHelper = null;
1608
1609 if (fTraceType == null) {
1610 // Auto Detection
1611 try {
1612 traceTypeHelper = TmfTraceTypeUIUtils.selectTraceType(path, null, null);
1613 } catch (TmfTraceImportException e) {
1614 // the trace did not match any trace type
1615 }
1616 if (traceTypeHelper == null) {
1617 if ((fImportOptionFlags & OPTION_IMPORT_UNRECOGNIZED_TRACES) != 0) {
1618 importResource(fileSystemElement, monitor);
1619 }
1620 return;
1621 }
1622 } else {
1623 boolean isDirectoryTraceType = TmfTraceType.isDirectoryTraceType(fTraceType);
1624 if (fileSystemElement.isDirectory() != isDirectoryTraceType) {
1625 return;
1626 }
1627 traceTypeHelper = TmfTraceType.getTraceType(fTraceType);
1628
1629 if (traceTypeHelper == null) {
1630 // Trace type not found
1631 throw new TmfTraceImportException(Messages.ImportTraceWizard_TraceTypeNotFound);
1632 }
1633
1634 if (!traceTypeHelper.validate(path).isOK()) {
1635 // Trace type exist but doesn't validate for given trace.
1636 return;
1637 }
1638 }
1639
1640 // Finally import trace
1641 IResource importedResource = importResource(fileSystemElement, monitor);
1642 if (importedResource != null) {
1643 TmfTraceTypeUIUtils.setTraceType(importedResource, traceTypeHelper);
1644 }
1645
1646 }
1647
1648 /**
1649 * Imports a trace resource to project. In case of name collision the
1650 * user will be asked to confirm overwriting the existing trace,
1651 * overwriting or skipping the trace to be imported.
1652 *
1653 * @param fileSystemElement
1654 * trace file system object to import
1655 * @param monitor
1656 * a progress monitor
1657 * @return the imported resource or null if no resource was imported
1658 *
1659 * @throws InvocationTargetException
1660 * if problems during import operation
1661 * @throws InterruptedException
1662 * if cancelled
1663 * @throws CoreException
1664 * if problems with workspace
1665 */
1666 private IResource importResource(TraceFileSystemElement fileSystemElement, IProgressMonitor monitor)
1667 throws InvocationTargetException, InterruptedException, CoreException {
1668
1669 ImportConfirmation mode = checkForNameClashes(fileSystemElement);
1670 switch (mode) {
1671 case RENAME:
1672 case RENAME_ALL:
1673 rename(fileSystemElement);
1674 break;
1675 case OVERWRITE:
1676 case OVERWRITE_ALL:
1677 delete(fileSystemElement, monitor);
1678 break;
1679 case CONTINUE:
1680 break;
1681 case SKIP:
1682 case SKIP_ALL:
1683 default:
1684 return null;
1685 }
1686
1687 List<TraceFileSystemElement> subList = new ArrayList<>();
1688
1689 FileSystemElement parentFolder = fileSystemElement.getParent();
1690
1691 IPath containerPath = fileSystemElement.getDestinationContainerPath();
1692 IPath tracePath = containerPath.addTrailingSeparator().append(fileSystemElement.getLabel());
1693 boolean createLinksInWorkspace = (fImportOptionFlags & OPTION_CREATE_LINKS_IN_WORKSPACE) != 0;
1694 if (fileSystemElement.isDirectory() && !createLinksInWorkspace) {
1695 containerPath = tracePath;
1696
1697 Object[] array = fileSystemElement.getFiles().getChildren();
1698 for (int i = 0; i < array.length; i++) {
1699 subList.add((TraceFileSystemElement) array[i]);
1700 }
1701 parentFolder = fileSystemElement;
1702
1703 } else {
1704 subList.add(fileSystemElement);
1705 }
1706
1707 ImportProvider fileSystemStructureProvider = new ImportProvider();
1708
1709 IOverwriteQuery myQueryImpl = new IOverwriteQuery() {
1710 @Override
1711 public String queryOverwrite(String file) {
1712 return IOverwriteQuery.NO_ALL;
1713 }
1714 };
1715
1716 monitor.setTaskName(Messages.ImportTraceWizard_ImportOperationTaskName + " " + fileSystemElement.getFileSystemObject().getAbsolutePath(fBaseSourceContainerPath.toOSString())); //$NON-NLS-1$
1717 ImportOperation operation = new ImportOperation(containerPath, parentFolder, fileSystemStructureProvider, myQueryImpl, subList);
1718 operation.setContext(getShell());
1719
1720 operation.setCreateContainerStructure(false);
1721 operation.setOverwriteResources(false);
1722 operation.setCreateLinks(createLinksInWorkspace);
1723 operation.setVirtualFolders(false);
1724
1725 operation.run(new SubProgressMonitor(monitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK));
1726 String sourceLocation = fileSystemElement.getSourceLocation();
1727 IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(tracePath);
1728 if (sourceLocation != null) {
1729 resource.setPersistentProperty(TmfCommonConstants.SOURCE_LOCATION, sourceLocation);
1730 }
1731
1732 return resource;
1733 }
1734
1735 private boolean isDirectoryTrace(TraceFileSystemElement fileSystemElement) {
1736 String path = fileSystemElement.getFileSystemObject().getAbsolutePath(fBaseSourceContainerPath.toOSString());
1737 if (TmfTraceType.isDirectoryTrace(path)) {
1738 return true;
1739 }
1740 return false;
1741 }
1742
1743 private ImportConfirmation checkForNameClashes(TraceFileSystemElement fileSystemElement) throws InterruptedException {
1744 IPath tracePath = getInitialDestinationPath(fileSystemElement);
1745
1746 // handle rename
1747 if (getExistingTrace(tracePath) != null) {
1748 if ((fConfirmationMode == ImportConfirmation.RENAME_ALL) ||
1749 (fConfirmationMode == ImportConfirmation.OVERWRITE_ALL) ||
1750 (fConfirmationMode == ImportConfirmation.SKIP_ALL)) {
1751 return fConfirmationMode;
1752 }
1753
1754 int returnCode = promptForOverwrite(tracePath);
1755 if (returnCode < 0) {
1756 // Cancel
1757 throw new InterruptedException();
1758 }
1759 fConfirmationMode = ImportConfirmation.values()[returnCode];
1760 return fConfirmationMode;
1761 }
1762 return ImportConfirmation.CONTINUE;
1763 }
1764
1765 private int promptForOverwrite(IPath tracePath) {
1766 final MessageDialog dialog = new MessageDialog(getContainer()
1767 .getShell(), null, null, NLS.bind(Messages.ImportTraceWizard_TraceAlreadyExists, tracePath.makeRelativeTo(fTraceFolderElement.getProject().getPath())),
1768 MessageDialog.QUESTION, new String[] {
1769 ImportConfirmation.RENAME.getInName(),
1770 ImportConfirmation.RENAME_ALL.getInName(),
1771 ImportConfirmation.OVERWRITE.getInName(),
1772 ImportConfirmation.OVERWRITE_ALL.getInName(),
1773 ImportConfirmation.SKIP.getInName(),
1774 ImportConfirmation.SKIP_ALL.getInName(),
1775 }, 4) {
1776 @Override
1777 protected int getShellStyle() {
1778 return super.getShellStyle() | SWT.SHEET;
1779 }
1780 };
1781
1782 final int[] returnValue = new int[1];
1783 getShell().getDisplay().syncExec(new Runnable() {
1784
1785 @Override
1786 public void run() {
1787 returnValue[0] = dialog.open();
1788 }
1789 });
1790 return returnValue[0];
1791 }
1792
1793 /**
1794 * @return the initial destination path, before rename, if any
1795 */
1796 private IPath getInitialDestinationPath(TraceFileSystemElement fileSystemElement) {
1797 IPath traceFolderPath = fileSystemElement.getDestinationContainerPath();
1798 return traceFolderPath.append(fileSystemElement.getFileSystemObject().getLabel());
1799 }
1800
1801 private void rename(TraceFileSystemElement fileSystemElement) {
1802 IPath tracePath = getInitialDestinationPath(fileSystemElement);
1803 TmfTraceElement trace = getExistingTrace(tracePath);
1804 if (trace == null) {
1805 return;
1806 }
1807
1808 // Not using IFolder on purpose to leave the door open to import
1809 // directly into an IProject
1810 IContainer folder = (IContainer) trace.getParent().getResource();
1811 int i = 2;
1812 while (true) {
1813 String name = trace.getName() + '(' + Integer.toString(i++) + ')';
1814 IResource resource = folder.findMember(name);
1815 if (resource == null) {
1816 fileSystemElement.setLabel(name);
1817 return;
1818 }
1819 }
1820 }
1821
1822 private void delete(TraceFileSystemElement fileSystemElement, IProgressMonitor monitor) throws CoreException {
1823 IPath tracePath = getInitialDestinationPath(fileSystemElement);
1824 TmfTraceElement trace = getExistingTrace(tracePath);
1825 if (trace == null) {
1826 return;
1827 }
1828
1829 trace.delete(monitor);
1830 }
1831
1832 private TmfTraceElement getExistingTrace(IPath tracePath) {
1833 List<TmfTraceElement> traces = fTraceFolderElement.getTraces();
1834 for (TmfTraceElement t : traces) {
1835 if (t.getPath().equals(tracePath)) {
1836 return t;
1837 }
1838 }
1839 return null;
1840 }
1841
1842 /**
1843 * Set the status for this operation
1844 *
1845 * @param status
1846 * the status
1847 */
1848 protected void setStatus(IStatus status) {
1849 fStatus = status;
1850 }
1851
1852 public IStatus getStatus() {
1853 return fStatus;
1854 }
1855 }
1856
1857 /**
1858 * The <code>TraceFileSystemElement</code> is a
1859 * <code>FileSystemElement</code> that knows if it has been populated or
1860 * not.
1861 */
1862 private static class TraceFileSystemElement extends FileSystemElement {
1863
1864 private boolean fIsPopulated = false;
1865 private String fLabel = null;
1866 private IPath fDestinationContainerPath;
1867 private FileSystemObjectImportStructureProvider fProvider;
1868 private String fSourceLocation;
1869
1870 public TraceFileSystemElement(String name, FileSystemElement parent, boolean isDirectory, FileSystemObjectImportStructureProvider provider) {
1871 super(name, parent, isDirectory);
1872 fProvider = provider;
1873 }
1874
1875 public void setDestinationContainerPath(IPath destinationContainerPath) {
1876 fDestinationContainerPath = destinationContainerPath;
1877 }
1878
1879 public void setPopulated() {
1880 fIsPopulated = true;
1881 }
1882
1883 public boolean isPopulated() {
1884 return fIsPopulated;
1885 }
1886
1887 @Override
1888 public AdaptableList getFiles() {
1889 if (!fIsPopulated) {
1890 populateElementChildren();
1891 }
1892 return super.getFiles();
1893 }
1894
1895 @Override
1896 public AdaptableList getFolders() {
1897 if (!fIsPopulated) {
1898 populateElementChildren();
1899 }
1900 return super.getFolders();
1901 }
1902
1903 /**
1904 * Sets the label for the trace to be used when importing at trace.
1905 *
1906 * @param name
1907 * the label for the trace
1908 */
1909 public void setLabel(String name) {
1910 fLabel = name;
1911 }
1912
1913 /**
1914 * Returns the label for the trace to be used when importing at trace.
1915 *
1916 * @return the label of trace resource
1917 */
1918 public String getLabel() {
1919 if (fLabel == null) {
1920 return getFileSystemObject().getLabel();
1921 }
1922 return fLabel;
1923 }
1924
1925 /**
1926 * The full path to the container that will contain the trace
1927 *
1928 * @return the destination container path
1929 */
1930 public IPath getDestinationContainerPath() {
1931 return fDestinationContainerPath;
1932 }
1933
1934 /**
1935 * Populates the children of the specified parent
1936 * <code>FileSystemElement</code>
1937 */
1938 private void populateElementChildren() {
1939 List<IFileSystemObject> allchildren = fProvider.getChildren(this.getFileSystemObject());
1940 Object child = null;
1941 TraceFileSystemElement newelement = null;
1942 Iterator<IFileSystemObject> iter = allchildren.iterator();
1943 while (iter.hasNext()) {
1944 child = iter.next();
1945 newelement = new TraceFileSystemElement(fProvider.getLabel(child), this, fProvider.isFolder(child), fProvider);
1946 newelement.setFileSystemObject(child);
1947 }
1948 setPopulated();
1949 }
1950
1951 public FileSystemObjectImportStructureProvider getProvider() {
1952 return fProvider;
1953 }
1954
1955 @Override
1956 public IFileSystemObject getFileSystemObject() {
1957 Object fileSystemObject = super.getFileSystemObject();
1958 return (IFileSystemObject) fileSystemObject;
1959 }
1960
1961 public String getSourceLocation() {
1962 if (fSourceLocation == null) {
1963 fSourceLocation = getFileSystemObject().getSourceLocation();
1964 }
1965 return fSourceLocation;
1966 }
1967
1968 public void setSourceLocation(String sourceLocation) {
1969 fSourceLocation = sourceLocation;
1970 }
1971 }
1972
1973 /**
1974 * This interface abstracts the differences between different kinds of
1975 * FileSystemObjects such as File, TarEntry and ZipEntry. This allows
1976 * clients (TraceFileSystemElement, TraceValidateAndImportOperation) to
1977 * handle all the types transparently.
1978 */
1979 private interface IFileSystemObject {
1980 String getLabel();
1981
1982 String getName();
1983
1984 String getAbsolutePath(String parentContainerPath);
1985
1986 String getSourceLocation();
1987
1988 Object getRawFileSystemObject();
1989
1990 boolean exists();
1991 }
1992
1993 /**
1994 * The "File" implementation of an IFileSystemObject
1995 */
1996 private static class FileFileSystemObject implements IFileSystemObject {
1997
1998 private File fFileSystemObject;
1999
2000 private FileFileSystemObject(File fileSystemObject) {
2001 fFileSystemObject = fileSystemObject;
2002 }
2003
2004 @Override
2005 public String getLabel() {
2006 String name = fFileSystemObject.getName();
2007 if (name.length() == 0) {
2008 return fFileSystemObject.getPath();
2009 }
2010 return name;
2011 }
2012
2013 @Override
2014 public String getName() {
2015 return fFileSystemObject.getName();
2016 }
2017
2018 @Override
2019 public String getAbsolutePath(String parentContainerPath) {
2020 return fFileSystemObject.getAbsolutePath();
2021 }
2022
2023 @Override
2024 public boolean exists() {
2025 return fFileSystemObject.exists();
2026 }
2027
2028 @Override
2029 public String getSourceLocation() {
2030 IResource sourceResource;
2031 String sourceLocation = null;
2032 if (fFileSystemObject.isDirectory()) {
2033 sourceResource = ResourcesPlugin.getWorkspace().getRoot().getContainerForLocation(Path.fromOSString(fFileSystemObject.getAbsolutePath()));
2034 } else {
2035 sourceResource = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(Path.fromOSString(fFileSystemObject.getAbsolutePath()));
2036 }
2037 if (sourceResource != null && sourceResource.exists()) {
2038 try {
2039 sourceLocation = sourceResource.getPersistentProperty(TmfCommonConstants.SOURCE_LOCATION);
2040 } catch (CoreException e) {
2041 // Something went wrong with the already existing resource.
2042 // This is not a problem, we'll assign a new location below.
2043 }
2044 }
2045 if (sourceLocation == null) {
2046 sourceLocation = URIUtil.toUnencodedString(fFileSystemObject.toURI());
2047 }
2048 return sourceLocation;
2049 }
2050
2051 @Override
2052 public Object getRawFileSystemObject() {
2053 return fFileSystemObject;
2054 }
2055 }
2056
2057 /**
2058 * The "Tar" implementation of an IFileSystemObject
2059 */
2060 private static class TarFileSystemObject implements IFileSystemObject {
2061
2062 private TarEntry fFileSystemObject;
2063 private String fArchivePath;
2064
2065 private TarFileSystemObject(TarEntry fileSystemObject, String archivePath) {
2066 fFileSystemObject = fileSystemObject;
2067 fArchivePath = archivePath;
2068 }
2069
2070 @Override
2071 public String getLabel() {
2072 return new Path(fFileSystemObject.getName()).lastSegment();
2073 }
2074
2075 @Override
2076 public String getName() {
2077 return fFileSystemObject.getName();
2078 }
2079
2080 @Override
2081 public String getAbsolutePath(String parentContainerPath) {
2082 return new Path(parentContainerPath).append(fFileSystemObject.getName()).toOSString();
2083 }
2084
2085 @Override
2086 public boolean exists() {
2087 return true;
2088 }
2089
2090 @Override
2091 public String getSourceLocation() {
2092 URI uri = new File(fArchivePath).toURI();
2093 IPath entryPath = new Path(fFileSystemObject.getName());
2094 return URIUtil.toUnencodedString(URIUtil.toJarURI(uri, entryPath));
2095 }
2096
2097 @Override
2098 public Object getRawFileSystemObject() {
2099 return fFileSystemObject;
2100 }
2101 }
2102
2103 /**
2104 * The "Zip" implementation of an IFileSystemObject
2105 */
2106 private static class ZipFileSystemObject implements IFileSystemObject {
2107
2108 private ZipEntry fFileSystemObject;
2109 private String fArchivePath;
2110
2111 private ZipFileSystemObject(ZipEntry fileSystemObject, String archivePath) {
2112 fFileSystemObject = fileSystemObject;
2113 fArchivePath = archivePath;
2114 }
2115
2116 @Override
2117 public String getLabel() {
2118 return new Path(fFileSystemObject.getName()).lastSegment();
2119 }
2120
2121 @Override
2122 public String getName() {
2123 return fFileSystemObject.getName();
2124 }
2125
2126 @Override
2127 public String getAbsolutePath(String parentContainerPath) {
2128 return new Path(parentContainerPath).append(fFileSystemObject.getName()).toOSString();
2129 }
2130
2131 @Override
2132 public boolean exists() {
2133 return true;
2134 }
2135
2136 @Override
2137 public String getSourceLocation() {
2138 URI uri = new File(fArchivePath).toURI();
2139 IPath entryPath = new Path(fFileSystemObject.getName());
2140 return URIUtil.toUnencodedString(URIUtil.toJarURI(uri, entryPath));
2141 }
2142
2143 @Override
2144 public Object getRawFileSystemObject() {
2145 return fFileSystemObject;
2146 }
2147 }
2148
2149 private class ImportProvider implements IImportStructureProvider {
2150
2151 ImportProvider() {
2152 }
2153
2154 @Override
2155 public String getLabel(Object element) {
2156 TraceFileSystemElement resource = (TraceFileSystemElement) element;
2157 return resource.getLabel();
2158 }
2159
2160 @Override
2161 public List getChildren(Object element) {
2162 TraceFileSystemElement resource = (TraceFileSystemElement) element;
2163 Object[] array = resource.getFiles().getChildren();
2164 List<Object> list = new ArrayList<>();
2165 for (int i = 0; i < array.length; i++) {
2166 list.add(array[i]);
2167 }
2168 return list;
2169 }
2170
2171 @Override
2172 public InputStream getContents(Object element) {
2173 TraceFileSystemElement resource = (TraceFileSystemElement) element;
2174 return resource.getProvider().getContents(resource.getFileSystemObject());
2175 }
2176
2177 @Override
2178 public String getFullPath(Object element) {
2179 TraceFileSystemElement resource = (TraceFileSystemElement) element;
2180 return resource.getProvider().getFullPath(resource.getFileSystemObject());
2181 }
2182
2183 @Override
2184 public boolean isFolder(Object element) {
2185 TraceFileSystemElement resource = (TraceFileSystemElement) element;
2186 return resource.isDirectory();
2187 }
2188 }
2189
2190 private enum ImportConfirmation {
2191 // ------------------------------------------------------------------------
2192 // Enum definition
2193 // ------------------------------------------------------------------------
2194 RENAME(Messages.ImportTraceWizard_ImportConfigurationRename),
2195 RENAME_ALL(Messages.ImportTraceWizard_ImportConfigurationRenameAll),
2196 OVERWRITE(Messages.ImportTraceWizard_ImportConfigurationOverwrite),
2197 OVERWRITE_ALL(Messages.ImportTraceWizard_ImportConfigurationOverwriteAll),
2198 SKIP(Messages.ImportTraceWizard_ImportConfigurationSkip),
2199 SKIP_ALL(Messages.ImportTraceWizard_ImportConfigurationSkipAll),
2200 CONTINUE("CONTINUE"); //$NON-NLS-1$
2201
2202 // ------------------------------------------------------------------------
2203 // Attributes
2204 // ------------------------------------------------------------------------
2205 /**
2206 * Name of enum
2207 */
2208 private final String fInName;
2209
2210 // ------------------------------------------------------------------------
2211 // Constuctors
2212 // ------------------------------------------------------------------------
2213
2214 /**
2215 * Private constructor
2216 *
2217 * @param name
2218 * the name of state
2219 */
2220 private ImportConfirmation(String name) {
2221 fInName = name;
2222 }
2223
2224 // ------------------------------------------------------------------------
2225 // Accessors
2226 // ------------------------------------------------------------------------
2227 /**
2228 * @return state name
2229 */
2230 public String getInName() {
2231 return fInName;
2232 }
2233 }
2234 }
This page took 0.088967 seconds and 5 git commands to generate.