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