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