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