tmf: Change time graph mouse wheel behavior
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / 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
1de10308 20package org.eclipse.linuxtools.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;
16f91bd5 54import org.eclipse.jface.dialogs.MessageDialog;
c8cf44dc 55import org.eclipse.jface.layout.PixelConverter;
252c602c
BH
56import org.eclipse.jface.operation.IRunnableWithProgress;
57import org.eclipse.jface.operation.ModalContext;
282218e9
MAL
58import org.eclipse.jface.viewers.CheckStateChangedEvent;
59import org.eclipse.jface.viewers.ICheckStateListener;
002f9f07
BH
60import org.eclipse.jface.viewers.IStructuredSelection;
61import org.eclipse.jface.viewers.ITreeContentProvider;
62import org.eclipse.linuxtools.internal.tmf.ui.Activator;
252c602c 63import org.eclipse.linuxtools.tmf.core.TmfCommonConstants;
002f9f07 64import org.eclipse.linuxtools.tmf.core.TmfProjectNature;
252c602c 65import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceImportException;
002f9f07
BH
66import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceType;
67import org.eclipse.linuxtools.tmf.core.project.model.TraceTypeHelper;
6ca50a1d 68import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectElement;
002f9f07 69import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectRegistry;
16f91bd5 70import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement;
002f9f07
BH
71import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceFolder;
72import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceTypeUIUtils;
339d539c 73import org.eclipse.linuxtools.tmf.ui.project.model.TmfTracesFolder;
16f91bd5 74import org.eclipse.osgi.util.NLS;
002f9f07
BH
75import org.eclipse.swt.SWT;
76import org.eclipse.swt.custom.BusyIndicator;
c8cf44dc 77import org.eclipse.swt.events.FocusAdapter;
002f9f07 78import org.eclipse.swt.events.FocusEvent;
2f7b3dd7
BH
79import org.eclipse.swt.events.ModifyEvent;
80import org.eclipse.swt.events.ModifyListener;
002f9f07
BH
81import org.eclipse.swt.events.SelectionAdapter;
82import org.eclipse.swt.events.SelectionEvent;
c8cf44dc
MAL
83import org.eclipse.swt.events.TraverseEvent;
84import org.eclipse.swt.events.TraverseListener;
002f9f07
BH
85import org.eclipse.swt.layout.GridData;
86import org.eclipse.swt.layout.GridLayout;
87import org.eclipse.swt.widgets.Button;
88import org.eclipse.swt.widgets.Combo;
89import org.eclipse.swt.widgets.Composite;
90import org.eclipse.swt.widgets.DirectoryDialog;
91import org.eclipse.swt.widgets.Event;
c8cf44dc 92import org.eclipse.swt.widgets.FileDialog;
002f9f07
BH
93import org.eclipse.swt.widgets.Group;
94import org.eclipse.swt.widgets.Label;
002f9f07 95import org.eclipse.ui.dialogs.FileSystemElement;
252c602c 96import org.eclipse.ui.dialogs.IOverwriteQuery;
002f9f07 97import org.eclipse.ui.dialogs.WizardResourceImportPage;
282218e9 98import org.eclipse.ui.internal.ide.DialogUtil;
29ceb238 99import org.eclipse.ui.internal.ide.dialogs.IElementFilter;
c8cf44dc 100import org.eclipse.ui.internal.wizards.datatransfer.ArchiveFileManipulations;
c8cf44dc
MAL
101import org.eclipse.ui.internal.wizards.datatransfer.ILeveledImportStructureProvider;
102import org.eclipse.ui.internal.wizards.datatransfer.TarEntry;
103import org.eclipse.ui.internal.wizards.datatransfer.TarException;
104import org.eclipse.ui.internal.wizards.datatransfer.TarFile;
105import org.eclipse.ui.internal.wizards.datatransfer.TarLeveledStructureProvider;
106import org.eclipse.ui.internal.wizards.datatransfer.ZipLeveledStructureProvider;
252c602c 107import org.eclipse.ui.model.AdaptableList;
002f9f07 108import org.eclipse.ui.model.WorkbenchContentProvider;
282218e9
MAL
109import org.eclipse.ui.model.WorkbenchLabelProvider;
110import org.eclipse.ui.model.WorkbenchViewerComparator;
002f9f07
BH
111import org.eclipse.ui.wizards.datatransfer.FileSystemStructureProvider;
112import org.eclipse.ui.wizards.datatransfer.IImportStructureProvider;
113import org.eclipse.ui.wizards.datatransfer.ImportOperation;
114
115/**
252c602c
BH
116 * A variant of the standard resource import wizard for importing traces
117 * to given tracing project. If no project or tracing project was selected
118 * the wizard imports it to the default tracing project which is created
119 * if necessary.
120 *
121 * In our case traces could be files or a directory structure. This wizard
122 * supports both cases. It imports traces for a selected trace type or, if
123 * no trace type is selected, it tries to detect the trace type automatically.
124 * However, the automatic detection is a best-effort and cannot guarantee
125 * that the detection is successful. The reason for this is that there might
126 * be multiple trace types that can be assigned to a single trace.
127 *
002f9f07 128 *
002f9f07
BH
129 * @author Francois Chouinard
130 * @since 2.0
131 */
29ceb238 132@SuppressWarnings("restriction")
002f9f07
BH
133public class ImportTraceWizardPage extends WizardResourceImportPage {
134
002f9f07
BH
135 // ------------------------------------------------------------------------
136 // Constants
137 // ------------------------------------------------------------------------
d0e34947
MAL
138 private static final String IMPORT_WIZARD_PAGE_NAME = "ImportTraceWizardPage"; //$NON-NLS-1$
139 private static final String IMPORT_WIZARD_ROOT_DIRECTORY_ID = ".import_root_directory_id"; //$NON-NLS-1$;
140 private static final String IMPORT_WIZARD_ARCHIVE_FILE_NAME_ID = ".import_archive_file_name_id"; //$NON-NLS-1$
141 private static final String IMPORT_WIZARD_IMPORT_UNRECOGNIZED_ID = ".import_unrecognized_traces_id"; //$NON-NLS-1$
142 private static final String IMPORT_WIZARD_PRESERVE_FOLDERS_ID = ".import_preserve_folders_id"; //$NON-NLS-1$
143 private static final String IMPORT_WIZARD_IMPORT_FROM_DIRECTORY_ID = ".import_from_directory"; //$NON-NLS-1$
252c602c 144 private static final String SEPARATOR = ":"; //$NON-NLS-1$
002f9f07 145
c8cf44dc
MAL
146 // constant from WizardArchiveFileResourceImportPage1
147 private static final String[] FILE_IMPORT_MASK = { "*.jar;*.zip;*.tar;*.tar.gz;*.tgz", "*.*" }; //$NON-NLS-1$ //$NON-NLS-2$
148 private static final String TRACE_IMPORT_TEMP_FOLDER = ".traceImport"; //$NON-NLS-1$
149
d0e34947
MAL
150 /**
151 * A special trace type value to communicate that automatic trace type
152 * detection will occur instead of setting a specific trace type when
153 * importing the traces.
154 */
155 protected static final String TRACE_TYPE_AUTO_DETECT = Messages.ImportTraceWizard_AutoDetection;
156
157 /**
158 * Preserve the folder structure of the import traces.
159 */
160 protected static final int OPTION_PRESERVE_FOLDER_STRUCTURE = 1 << 1;
161 /**
162 * Create links to the trace files instead of copies.
163 */
164 protected static final int OPTION_CREATE_LINKS_IN_WORKSPACE = 1 << 2;
165 /**
166 * Import files that were not recognized as the selected trace type.
167 */
168 protected static final int OPTION_IMPORT_UNRECOGNIZED_TRACES = 1 << 3;
169 /**
170 * Overwrite existing resources without prompting.
171 */
172 protected static final int OPTION_OVERWRITE_EXISTING_RESOURCES = 1 << 4;
173
002f9f07
BH
174 // ------------------------------------------------------------------------
175 // Attributes
176 // ------------------------------------------------------------------------
177
002f9f07
BH
178 // Target import directory ('Traces' folder)
179 private IFolder fTargetFolder;
16f91bd5
BH
180 // Target Trace folder element
181 private TmfTraceFolder fTraceFolderElement;
252c602c
BH
182 // Flag to handle destination folder change event
183 private Boolean fIsDestinationChanged = false;
184 // Combo box containing trace types
185 private Combo fTraceTypes;
186 // Button to ignore unrecognized traces or not
187 private Button fImportUnrecognizedButton;
188 // Button to overwrite existing resources or not
189 private Button fOverwriteExistingResourcesCheckbox;
190 // Button to link or copy traces to workspace
191 private Button fCreateLinksInWorkspaceButton;
0e1d517e
MAL
192 // Button to preserve folder structure
193 private Button fPreserveFolderStructureButton;
252c602c 194 private boolean entryChanged = false;
c8cf44dc
MAL
195 // The import from directory radio button
196 private Button fImportFromDirectoryRadio;
197 // The import from archive radio button
198 private Button fImportFromArchiveRadio;
199 // Flag to remember the "create links" checkbox when it gets disabled by
200 // the import from archive radio button
201 private Boolean fPreviousCreateLinksValue = true;
d0e34947 202
c8cf44dc 203 /** The archive name field */
d0e34947 204 protected Combo fArchiveNameField;
c8cf44dc
MAL
205 /** The archive browse button. */
206 protected Button fArchiveBrowseButton;
252c602c
BH
207 /** The directory name field */
208 protected Combo directoryNameField;
209 /** The directory browse button. */
210 protected Button directoryBrowseButton;
002f9f07 211
282218e9
MAL
212 /**
213 * ResourceTreeAndListGroup was internal in Kepler and we referenced it. It
214 * is now removed in Luna. To keep our builds compatible with Kepler, we
215 * need to have our own version of this class. Once we stop supporting
216 * Kepler, we can delete this class and use the public one from the
217 * platform.
218 */
219 private ResourceTreeAndListGroup fSelectionGroup;
220
c8cf44dc
MAL
221 // Keep trace of the selection root so that we can dispose its related
222 // resources
223 private TraceFileSystemElement fSelectionGroupRoot;
224
002f9f07
BH
225 // ------------------------------------------------------------------------
226 // Constructors
227 // ------------------------------------------------------------------------
228
229 /**
230 * Constructor. Creates the trace wizard page.
231 *
232 * @param name
233 * The name of the page.
234 * @param selection
235 * The current selection
236 */
237 protected ImportTraceWizardPage(String name, IStructuredSelection selection) {
238 super(name, selection);
002f9f07
BH
239 setTitle(Messages.ImportTraceWizard_FileSystemTitle);
240 setDescription(Messages.ImportTraceWizard_ImportTrace);
241
242 // Locate the target trace folder
243 IFolder traceFolder = null;
244 Object element = selection.getFirstElement();
245
246 if (element instanceof TmfTraceFolder) {
16f91bd5 247 fTraceFolderElement = (TmfTraceFolder) element;
16f91bd5 248 traceFolder = fTraceFolderElement.getResource();
002f9f07
BH
249 } else if (element instanceof IProject) {
250 IProject project = (IProject) element;
251 try {
252 if (project.hasNature(TmfProjectNature.ID)) {
6ca50a1d
BH
253 TmfProjectElement projectElement = TmfProjectRegistry.getProject(project, true);
254 fTraceFolderElement = projectElement.getTracesFolder();
339d539c 255 traceFolder = project.getFolder(TmfTracesFolder.TRACES_FOLDER_NAME);
002f9f07
BH
256 }
257 } catch (CoreException e) {
258 }
259 }
260
6ca50a1d
BH
261 // If no tracing project was selected or trace folder doesn't exist use
262 // default tracing project
252c602c
BH
263 if (traceFolder == null) {
264 IProject project = TmfProjectRegistry.createProject(
265 TmfCommonConstants.DEFAULT_TRACE_PROJECT_NAME, null, new NullProgressMonitor());
6ca50a1d
BH
266 TmfProjectElement projectElement = TmfProjectRegistry.getProject(project, true);
267 fTraceFolderElement = projectElement.getTracesFolder();
339d539c 268 traceFolder = project.getFolder(TmfTracesFolder.TRACES_FOLDER_NAME);
252c602c
BH
269 }
270
002f9f07
BH
271 // Set the target trace folder
272 if (traceFolder != null) {
273 fTargetFolder = traceFolder;
1d6c9022 274 String path = traceFolder.getFullPath().toString();
002f9f07
BH
275 setContainerFieldValue(path);
276 }
277 }
278
d0e34947
MAL
279 /**
280 * Constructor
281 *
282 * @param selection
283 * The current selection
284 */
285 public ImportTraceWizardPage(IStructuredSelection selection) {
286 this(IMPORT_WIZARD_PAGE_NAME, selection);
287 }
288
289 /**
290 * Create the import source selection widget. (Copied from
291 * WizardResourceImportPage but instead always uses the internal
292 * ResourceTreeAndListGroup to keep compatibility with Kepler)
293 */
294 @Override
295 protected void createFileSelectionGroup(Composite parent) {
296
297 // Just create with a dummy root.
298 fSelectionGroup = new ResourceTreeAndListGroup(parent,
299 new FileSystemElement("Dummy", null, true),//$NON-NLS-1$
300 getFolderProvider(), new WorkbenchLabelProvider(),
301 getFileProvider(), new WorkbenchLabelProvider(), SWT.NONE,
302 DialogUtil.inRegularFontMode(parent));
303
304 ICheckStateListener listener = new ICheckStateListener() {
305 @Override
306 public void checkStateChanged(CheckStateChangedEvent event) {
307 updateWidgetEnablements();
308 }
309 };
310
311 WorkbenchViewerComparator comparator = new WorkbenchViewerComparator();
312 fSelectionGroup.setTreeComparator(comparator);
313 fSelectionGroup.setListComparator(comparator);
314 fSelectionGroup.addCheckStateListener(listener);
315
316 }
317
002f9f07
BH
318 // ------------------------------------------------------------------------
319 // WizardResourceImportPage
320 // ------------------------------------------------------------------------
321
002f9f07
BH
322 @Override
323 protected void createSourceGroup(Composite parent) {
c8cf44dc 324 createSourceSelectionGroup(parent);
002f9f07
BH
325 createFileSelectionGroup(parent);
326 createTraceTypeGroup(parent);
327 validateSourceGroup();
328 }
329
330 @Override
252c602c
BH
331 protected ITreeContentProvider getFileProvider() {
332 return new WorkbenchContentProvider() {
002f9f07 333 @Override
252c602c
BH
334 public Object[] getChildren(Object object) {
335 if (object instanceof TraceFileSystemElement) {
336 TraceFileSystemElement element = (TraceFileSystemElement) object;
337 return element.getFiles().getChildren(element);
002f9f07 338 }
252c602c 339 return new Object[0];
002f9f07 340 }
252c602c 341 };
002f9f07
BH
342 }
343
344 @Override
345 protected ITreeContentProvider getFolderProvider() {
002f9f07
BH
346 return new WorkbenchContentProvider() {
347 @Override
348 public Object[] getChildren(Object o) {
252c602c
BH
349 if (o instanceof TraceFileSystemElement) {
350 TraceFileSystemElement element = (TraceFileSystemElement) o;
351 return element.getFolders().getChildren();
002f9f07
BH
352 }
353 return new Object[0];
354 }
002f9f07 355
252c602c
BH
356 @Override
357 public boolean hasChildren(Object o) {
358 if (o instanceof TraceFileSystemElement) {
359 TraceFileSystemElement element = (TraceFileSystemElement) o;
360 if (element.isPopulated()) {
361 return getChildren(element).length > 0;
362 }
363 //If we have not populated then wait until asked
364 return true;
002f9f07 365 }
252c602c 366 return false;
002f9f07 367 }
252c602c 368 };
002f9f07
BH
369 }
370
371 // ------------------------------------------------------------------------
372 // Directory Selection Group (forked WizardFileSystemResourceImportPage1)
373 // ------------------------------------------------------------------------
374
002f9f07 375 /**
c8cf44dc 376 * creates the source selection group.
002f9f07
BH
377 *
378 * @param parent
379 * the parent composite
380 */
d0e34947 381 protected void createSourceSelectionGroup(Composite parent) {
002f9f07 382
d0e34947 383 Composite sourceGroup = new Composite(parent, SWT.NONE);
002f9f07
BH
384 GridLayout layout = new GridLayout();
385 layout.numColumns = 3;
c8cf44dc
MAL
386 layout.makeColumnsEqualWidth = false;
387 layout.marginWidth = 0;
388 sourceGroup.setLayout(layout);
389 sourceGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
390
391 // import from directory radio button
392 fImportFromDirectoryRadio = new Button(sourceGroup, SWT.RADIO);
393 fImportFromDirectoryRadio
394 .setText(Messages.ImportTraceWizard_DirectoryLocation);
395
396 // import location entry combo
d0e34947
MAL
397 directoryNameField = createPathSelectionCombo(sourceGroup);
398 createDirectoryBrowseButton(sourceGroup);
c8cf44dc
MAL
399
400 // import from archive radio button
401 fImportFromArchiveRadio = new Button(sourceGroup, SWT.RADIO);
402 fImportFromArchiveRadio
403 .setText(Messages.ImportTraceWizard_ArchiveLocation);
404
405 // import location entry combo
d0e34947
MAL
406 fArchiveNameField = createPathSelectionCombo(sourceGroup);
407 createArchiveBrowseButton(sourceGroup);
c8cf44dc
MAL
408
409 fImportFromDirectoryRadio.setSelection(true);
410 fArchiveNameField.setEnabled(false);
411 fArchiveBrowseButton.setEnabled(false);
412
d0e34947 413 fImportFromDirectoryRadio.addSelectionListener(new SelectionAdapter() {
002f9f07
BH
414 @Override
415 public void widgetSelected(SelectionEvent e) {
d0e34947 416 directoryRadioSelected();
002f9f07 417 }
c8cf44dc 418 });
002f9f07 419
d0e34947 420 fImportFromArchiveRadio.addSelectionListener(new SelectionAdapter() {
002f9f07 421 @Override
c8cf44dc 422 public void widgetSelected(SelectionEvent e) {
d0e34947 423 archiveRadioSelected();
002f9f07
BH
424 }
425 });
d0e34947
MAL
426 }
427
428 /**
429 * Select or deselect all files in the file selection group
430 *
431 * @param checked
432 * whether or not the files should be checked
433 */
434 protected void setFileSelectionGroupChecked(boolean checked) {
435 if (fSelectionGroup != null) {
436 fSelectionGroup.setAllSelections(checked);
437 }
438 }
439
440 /**
441 * Create a combo that will be used to select a path to specify the source
442 * of the import. The parent is assumed to have a GridLayout.
443 *
444 * @param parent
445 * the parent composite
446 * @return the created path selection combo
447 */
448 protected Combo createPathSelectionCombo(Composite parent) {
449 Combo pathSelectionCombo = new Combo(parent, SWT.BORDER);
450
451 GridData layoutData = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL);
452 layoutData.widthHint = new PixelConverter(pathSelectionCombo).convertWidthInCharsToPixels(25);
453 pathSelectionCombo.setLayoutData(layoutData);
002f9f07 454
c8cf44dc 455 TraverseListener traverseListener = new TraverseListener() {
002f9f07 456 @Override
c8cf44dc
MAL
457 public void keyTraversed(TraverseEvent e) {
458 if (e.detail == SWT.TRAVERSE_RETURN) {
459 e.doit = false;
460 entryChanged = false;
461 updateFromSourceField();
462 }
002f9f07 463 }
c8cf44dc
MAL
464 };
465
466 FocusAdapter focusAdapter = new FocusAdapter() {
002f9f07
BH
467 @Override
468 public void focusLost(FocusEvent e) {
469 // Clear the flag to prevent constant update
470 if (entryChanged) {
471 entryChanged = false;
472 updateFromSourceField();
473 }
474 }
c8cf44dc
MAL
475 };
476
477 SelectionAdapter selectionAdapter = new SelectionAdapter() {
478 @Override
479 public void widgetSelected(SelectionEvent e) {
480 entryChanged = false;
481 updateFromSourceField();
482 }
483 };
002f9f07 484
c8cf44dc 485 ModifyListener modifyListner = new ModifyListener() {
2f7b3dd7
BH
486 @Override
487 public void modifyText(ModifyEvent e) {
488 entryChanged = true;
489 }
c8cf44dc
MAL
490 };
491
d0e34947
MAL
492 pathSelectionCombo.addModifyListener(modifyListner);
493 pathSelectionCombo.addTraverseListener(traverseListener);
494 pathSelectionCombo.addFocusListener(focusAdapter);
495 pathSelectionCombo.addSelectionListener(selectionAdapter);
c8cf44dc 496
d0e34947
MAL
497 return pathSelectionCombo;
498 }
499
500 /**
501 * Create the directory browse button.
502 *
503 * @param parent
504 * the parent composite
505 */
506 protected void createDirectoryBrowseButton(Composite parent) {
507 directoryBrowseButton = createPathSelectionBrowseButton(parent);
508 directoryBrowseButton.addSelectionListener(new SelectionAdapter() {
c8cf44dc
MAL
509 @Override
510 public void widgetSelected(SelectionEvent e) {
d0e34947 511 handleSourceDirectoryBrowseButtonPressed();
c8cf44dc 512 }
2f7b3dd7 513 });
d0e34947 514 }
2f7b3dd7 515
d0e34947
MAL
516 /**
517 * Create the archive browse button.
518 *
519 * @param parent
520 * the parent composite
521 */
522 protected void createArchiveBrowseButton(Composite parent) {
523 fArchiveBrowseButton = createPathSelectionBrowseButton(parent);
524 fArchiveBrowseButton.addSelectionListener(new SelectionAdapter() {
c8cf44dc
MAL
525 @Override
526 public void widgetSelected(SelectionEvent e) {
d0e34947 527 handleArchiveBrowseButtonPressed(FILE_IMPORT_MASK);
c8cf44dc
MAL
528 }
529 });
530 }
531
d0e34947
MAL
532 /**
533 * Create a browse button that will be used to browse for a path to specify
534 * the source of the import. The parent is assumed to have a GridLayout.
535 *
536 * @param parent
537 * the parent composite
538 * @return the created path selection combo
539 */
540 protected Button createPathSelectionBrowseButton(Composite parent) {
541 Button pathSelectionBrowseButton = new Button(parent, SWT.PUSH);
542 pathSelectionBrowseButton.setText(Messages.ImportTraceWizard_BrowseButton);
543 setButtonLayoutData(pathSelectionBrowseButton);
544
545 return pathSelectionBrowseButton;
546 }
547
c8cf44dc 548 private void archiveRadioSelected() {
d0e34947 549 if (!isImportFromDirectory()) {
c8cf44dc
MAL
550 directoryNameField.setEnabled(false);
551 directoryBrowseButton.setEnabled(false);
552 fArchiveNameField.setEnabled(true);
553 fArchiveBrowseButton.setEnabled(true);
554 updateFromSourceField();
555 fArchiveNameField.setFocus();
d0e34947
MAL
556 if (fCreateLinksInWorkspaceButton != null) {
557 fPreviousCreateLinksValue = fCreateLinksInWorkspaceButton.getSelection();
558 fCreateLinksInWorkspaceButton.setSelection(false);
559 fCreateLinksInWorkspaceButton.setEnabled(false);
560 }
c8cf44dc
MAL
561 }
562 }
563
564 private void directoryRadioSelected() {
d0e34947 565 if (isImportFromDirectory()) {
c8cf44dc
MAL
566 directoryNameField.setEnabled(true);
567 directoryBrowseButton.setEnabled(true);
568 fArchiveNameField.setEnabled(false);
569 fArchiveBrowseButton.setEnabled(false);
570 updateFromSourceField();
571 directoryNameField.setFocus();
d0e34947
MAL
572 if (fCreateLinksInWorkspaceButton != null) {
573 fCreateLinksInWorkspaceButton.setSelection(fPreviousCreateLinksValue);
574 fCreateLinksInWorkspaceButton.setEnabled(true);
575 }
c8cf44dc 576 }
002f9f07
BH
577 }
578
579 // ------------------------------------------------------------------------
580 // Browse for the source directory
581 // ------------------------------------------------------------------------
582
583 @Override
584 public void handleEvent(Event event) {
585 if (event.widget == directoryBrowseButton) {
586 handleSourceDirectoryBrowseButtonPressed();
587 }
252c602c
BH
588
589 // Avoid overwriting destination path without repeatedly trigger
590 // call of handleEvent();
591 synchronized (fIsDestinationChanged) {
592 if (fIsDestinationChanged == false) {
593 event.display.asyncExec(new Runnable() {
594 @Override
595 public void run() {
596 synchronized (fIsDestinationChanged) {
597 fIsDestinationChanged = true;
1d6c9022 598 String path = fTargetFolder.getFullPath().toString();
252c602c
BH
599 setContainerFieldValue(path);
600 }
601 }
602 });
603 } else {
604 fIsDestinationChanged = false;
605 }
606 }
002f9f07
BH
607 super.handleEvent(event);
608 }
609
252c602c
BH
610 @Override
611 protected void handleContainerBrowseButtonPressed() {
612 // Do nothing so that destination directory cannot be changed.
613 }
614
002f9f07
BH
615 /**
616 * Handle the button pressed event
617 */
618 protected void handleSourceDirectoryBrowseButtonPressed() {
619 String currentSource = directoryNameField.getText();
620 DirectoryDialog dialog = new DirectoryDialog(directoryNameField.getShell(), SWT.SAVE | SWT.SHEET);
621 dialog.setText(Messages.ImportTraceWizard_SelectTraceDirectoryTitle);
622 dialog.setMessage(Messages.ImportTraceWizard_SelectTraceDirectoryMessage);
623 dialog.setFilterPath(getSourceDirectoryName(currentSource));
624
625 String selectedDirectory = dialog.open();
626 if (selectedDirectory != null) {
627 // Just quit if the directory is not valid
628 if ((getSourceDirectory(selectedDirectory) == null) || selectedDirectory.equals(currentSource)) {
629 return;
630 }
631 // If it is valid then proceed to populate
632 setErrorMessage(null);
d0e34947 633 setSourcePath(selectedDirectory);
002f9f07
BH
634 }
635 }
636
c8cf44dc
MAL
637 /**
638 * Handle the button pressed event
d0e34947
MAL
639 *
640 * @param extensions
641 * file extensions used to filter files shown to the user
c8cf44dc 642 */
d0e34947 643 protected void handleArchiveBrowseButtonPressed(String[] extensions) {
c8cf44dc 644 FileDialog dialog = new FileDialog(fArchiveNameField.getShell(), SWT.SHEET);
d0e34947 645 dialog.setFilterExtensions(extensions);
c8cf44dc
MAL
646 dialog.setText(Messages.ImportTraceWizard_SelectTraceArchiveTitle);
647 String fileName = fArchiveNameField.getText().trim();
648 if (!fileName.isEmpty()) {
649 File path = new File(fileName).getParentFile();
650 if (path != null && path.exists()) {
651 dialog.setFilterPath(path.toString());
652 }
653 }
654
655 String selectedArchive = dialog.open();
656 if (selectedArchive != null) {
657 setErrorMessage(null);
d0e34947 658 setSourcePath(selectedArchive);
c8cf44dc
MAL
659 updateWidgetEnablements();
660 }
661 }
662
002f9f07 663 private File getSourceDirectory() {
d0e34947
MAL
664 if (directoryNameField == null) {
665 return null;
666 }
002f9f07
BH
667 return getSourceDirectory(directoryNameField.getText());
668 }
669
c8cf44dc 670 private File getSourceArchiveFile() {
d0e34947
MAL
671 if (fArchiveNameField == null) {
672 return null;
673 }
674
c8cf44dc
MAL
675 return getSourceArchiveFile(fArchiveNameField.getText());
676 }
677
678 private String getSourceContainerPath() {
d0e34947 679 if (isImportFromDirectory()) {
c8cf44dc
MAL
680 File sourceDirectory = getSourceDirectory();
681 if (sourceDirectory != null) {
682 return sourceDirectory.getAbsolutePath();
683 }
684 }
685 File sourceArchiveFile = getSourceArchiveFile();
686 if (sourceArchiveFile != null) {
687 return sourceArchiveFile.getParent();
688 }
689 return null;
690 }
691
002f9f07
BH
692 private static File getSourceDirectory(String path) {
693 File sourceDirectory = new File(getSourceDirectoryName(path));
694 if (!sourceDirectory.exists() || !sourceDirectory.isDirectory()) {
695 return null;
696 }
697
698 return sourceDirectory;
699 }
700
c8cf44dc
MAL
701 private static File getSourceArchiveFile(String path) {
702 File sourceArchiveFile = new File(path);
703 if (!sourceArchiveFile.exists() || sourceArchiveFile.isDirectory()) {
704 return null;
705 }
706
707 return sourceArchiveFile;
708 }
709
002f9f07
BH
710 private static String getSourceDirectoryName(String sourceName) {
711 IPath result = new Path(sourceName.trim());
712 if (result.getDevice() != null && result.segmentCount() == 0) {
713 result = result.addTrailingSeparator();
714 } else {
715 result = result.removeTrailingSeparator();
716 }
717 return result.toOSString();
718 }
719
002f9f07 720 private void updateFromSourceField() {
d0e34947 721 setSourcePath(getSourceField().getText());
002f9f07
BH
722 updateWidgetEnablements();
723 }
724
c8cf44dc 725 private Combo getSourceField() {
d0e34947
MAL
726 if (directoryNameField == null) {
727 return fArchiveNameField;
728 }
729
c8cf44dc
MAL
730 return directoryNameField.isEnabled() ? directoryNameField : fArchiveNameField;
731 }
732
d0e34947
MAL
733 /**
734 * Set the source path that was selected by the user by various input
735 * methods (Browse button, typing, etc).
736 *
737 * Clients can also call this to set the path programmatically (hard-coded
738 * initial path) and this can also be overridden to be notified when the
739 * source path changes.
740 *
741 * @param path
742 * the source path
743 */
744 protected void setSourcePath(String path) {
c8cf44dc 745 Combo sourceField = getSourceField();
d0e34947
MAL
746 if (sourceField == null) {
747 return;
748 }
749
002f9f07 750 if (path.length() > 0) {
c8cf44dc 751 String[] currentItems = sourceField.getItems();
002f9f07
BH
752 int selectionIndex = -1;
753 for (int i = 0; i < currentItems.length; i++) {
754 if (currentItems[i].equals(path)) {
755 selectionIndex = i;
756 }
757 }
758 if (selectionIndex < 0) {
759 int oldLength = currentItems.length;
760 String[] newItems = new String[oldLength + 1];
761 System.arraycopy(currentItems, 0, newItems, 0, oldLength);
762 newItems[oldLength] = path;
c8cf44dc 763 sourceField.setItems(newItems);
002f9f07
BH
764 selectionIndex = oldLength;
765 }
c8cf44dc 766 sourceField.select(selectionIndex);
002f9f07
BH
767 }
768 resetSelection();
769 }
770
771 // ------------------------------------------------------------------------
772 // File Selection Group (forked WizardFileSystemResourceImportPage1)
773 // ------------------------------------------------------------------------
002f9f07 774 private void resetSelection() {
c8cf44dc
MAL
775 if (fSelectionGroupRoot != null) {
776 disposeSelectionGroupRoot();
777 }
778 fSelectionGroupRoot = getFileSystemTree();
779 fSelectionGroup.setRoot(fSelectionGroupRoot);
780 }
781
782 private void disposeSelectionGroupRoot() {
783 if (fSelectionGroupRoot != null && fSelectionGroupRoot.getProvider() != null) {
784 FileSystemObjectImportStructureProvider provider = fSelectionGroupRoot.getProvider();
785 provider.dispose();
786 fSelectionGroupRoot = null;
787 }
002f9f07
BH
788 }
789
252c602c 790 private TraceFileSystemElement getFileSystemTree() {
c8cf44dc
MAL
791 IFileSystemObject rootElement = null;
792 FileSystemObjectImportStructureProvider importStructureProvider = null;
793
794 // Import from directory
d0e34947 795 if (isImportFromDirectory()) {
c8cf44dc
MAL
796 importStructureProvider = new FileSystemObjectImportStructureProvider(FileSystemStructureProvider.INSTANCE, null);
797 File sourceDirectory = getSourceDirectory();
798 if (sourceDirectory == null) {
799 return null;
800 }
801 rootElement = importStructureProvider.getIFileSystemObject(sourceDirectory);
802 } else {
803 // Import from archive
804 FileSystemObjectLeveledImportStructureProvider leveledImportStructureProvider = null;
805 String archivePath = getSourceArchiveFile() != null ? getSourceArchiveFile().getAbsolutePath() : ""; //$NON-NLS-1$
806 if (ArchiveFileManipulations.isTarFile(archivePath)) {
807 if (ensureTarSourceIsValid(archivePath)) {
808 // We close the file when we dispose the import provider, see disposeSelectionGroupRoot
809 TarFile tarFile = getSpecifiedTarSourceFile(archivePath);
810 leveledImportStructureProvider = new FileSystemObjectLeveledImportStructureProvider(new TarLeveledStructureProvider(tarFile), archivePath);
811 }
812 } else if (ensureZipSourceIsValid(archivePath)) {
813 // We close the file when we dispose the import provider, see disposeSelectionGroupRoot
814 @SuppressWarnings("resource")
815 ZipFile zipFile = getSpecifiedZipSourceFile(archivePath);
816 leveledImportStructureProvider = new FileSystemObjectLeveledImportStructureProvider(new ZipLeveledStructureProvider(zipFile), archivePath);
817 }
818 if (leveledImportStructureProvider == null) {
819 return null;
820 }
821 rootElement = leveledImportStructureProvider.getRoot();
822 importStructureProvider = leveledImportStructureProvider;
823 }
824
825 if (rootElement == null) {
826 return null;
827 }
828
829 return selectFiles(rootElement, importStructureProvider);
830 }
831
832 /**
833 * An import provider that makes use of the IFileSystemObject abstraction
834 * instead of using plain file system objects (File, TarEntry, ZipEntry)
835 */
836 private static class FileSystemObjectImportStructureProvider implements IImportStructureProvider {
837
838 private IImportStructureProvider fImportProvider;
839 private String fArchivePath;
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")
848 List children = fImportProvider.getChildren(((IFileSystemObject)element).getRawFileSystemObject());
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) {
874 return fImportProvider.getContents(((IFileSystemObject)element).getRawFileSystemObject());
875 }
876
877 @Override
878 public String getFullPath(Object element) {
879 return fImportProvider.getFullPath(((IFileSystemObject)element).getRawFileSystemObject());
880 }
881
882 @Override
883 public String getLabel(Object element) {
884 return fImportProvider.getLabel(((IFileSystemObject)element).getRawFileSystemObject());
885 }
886
887 @Override
888 public boolean isFolder(Object element) {
889 return fImportProvider.isFolder(((IFileSystemObject)element).getRawFileSystemObject());
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
252c602c
BH
1015 //Get the files for the element so as to build the first level
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;
1300 } finally {
1301 if (!status.isOK()) {
1302 if (status.getSeverity() == IStatus.CANCEL) {
1303 setMessage(Messages.ImportTraceWizard_ImportOperationCancelled);
1304 setErrorMessage(null);
002f9f07 1305 } else {
252c602c
BH
1306 if (status.getException() != null) {
1307 displayErrorDialog(status.getMessage() + ": " + status.getException()); //$NON-NLS-1$
1308 }
002f9f07 1309 setMessage(null);
252c602c 1310 setErrorMessage(Messages.ImportTraceWizard_ImportProblem);
002f9f07 1311 }
252c602c
BH
1312 return false;
1313 }
1314 }
252c602c
BH
1315 setErrorMessage(null);
1316 return true;
1317 }
002f9f07 1318
d0e34947
MAL
1319 /**
1320 * Get the trace type id to import as. This can also return
1321 * {@link #TRACE_TYPE_AUTO_DETECT} to communicate that automatic trace type
1322 * detection will occur instead of setting a specific trace type when
1323 * importing the traces.
1324 *
1325 * @return the trace type id or {@link #TRACE_TYPE_AUTO_DETECT}
1326 */
1327 protected String getImportTraceTypeId() {
1328 return fTraceTypes.getText();
1329 }
1330
1331 /**
1332 * Get import options in the form of flags (bits).
1333 *
1334 * @return the import flags.
1335 * @see #OPTION_CREATE_LINKS_IN_WORKSPACE
1336 * @see #OPTION_IMPORT_UNRECOGNIZED_TRACES
1337 * @see #OPTION_OVERWRITE_EXISTING_RESOURCES
1338 * @see #OPTION_PRESERVE_FOLDER_STRUCTURE
1339 */
1340 protected int getImportOptionFlags() {
1341 int flags = 0;
1342 if (fCreateLinksInWorkspaceButton != null && fCreateLinksInWorkspaceButton.getSelection()) {
1343 flags |= OPTION_CREATE_LINKS_IN_WORKSPACE;
1344 }
1345 if (fImportUnrecognizedButton != null && fImportUnrecognizedButton.getSelection()) {
1346 flags |= OPTION_IMPORT_UNRECOGNIZED_TRACES;
1347 }
1348 if (fOverwriteExistingResourcesCheckbox != null && fOverwriteExistingResourcesCheckbox.getSelection()) {
1349 flags |= OPTION_OVERWRITE_EXISTING_RESOURCES;
1350 }
1351 if (fPreserveFolderStructureButton != null && fPreserveFolderStructureButton.getSelection()) {
1352 flags |= OPTION_PRESERVE_FOLDER_STRUCTURE;
1353 }
1354 return flags;
1355 }
1356
c8cf44dc
MAL
1357 @Override
1358 public void dispose() {
1359 super.dispose();
1360 disposeSelectionGroupRoot();
1361 }
252c602c
BH
1362
1363 // ------------------------------------------------------------------------
1364 // Classes
1365 // ------------------------------------------------------------------------
1366
16f91bd5 1367 private class TraceValidateAndImportOperation {
252c602c 1368 private IStatus fStatus;
252c602c 1369 private String fTraceType;
0e1d517e
MAL
1370 private IPath fDestinationContainerPath;
1371 private IPath fBaseSourceContainerPath;
c8cf44dc 1372 private boolean fImportFromArchive;
d0e34947 1373 private int fImportOptionFlags;
16f91bd5 1374 private ImportConfirmation fConfirmationMode = ImportConfirmation.SKIP;
252c602c 1375
d0e34947 1376 private TraceValidateAndImportOperation(String traceId, IPath baseSourceContainerPath, IPath destinationContainerPath, boolean importFromArchive, int importOptionFlags) {
252c602c 1377 fTraceType = traceId;
0e1d517e
MAL
1378 fBaseSourceContainerPath = baseSourceContainerPath;
1379 fDestinationContainerPath = destinationContainerPath;
d0e34947 1380 fImportOptionFlags = importOptionFlags;
c8cf44dc 1381 fImportFromArchive = importFromArchive;
d0e34947
MAL
1382
1383 boolean overwriteExistingResources = (importOptionFlags & OPTION_OVERWRITE_EXISTING_RESOURCES) != 0;
1384 if (overwriteExistingResources) {
16f91bd5
BH
1385 fConfirmationMode = ImportConfirmation.OVERWRITE_ALL;
1386 }
252c602c
BH
1387 }
1388
1389 public void run(IProgressMonitor progressMonitor) {
1390 String currentPath = null;
16f91bd5 1391 final Map<String, TraceFileSystemElement> folderElements = new HashMap<>();
252c602c 1392 try {
29ceb238
BH
1393
1394 final ArrayList<TraceFileSystemElement> fileSystemElements = new ArrayList<>();
1395 IElementFilter passThroughFilter = new IElementFilter() {
1396
1397 @Override
1398 public void filterElements(Collection elements, IProgressMonitor monitor) {
1399 fileSystemElements.addAll(elements);
1400 }
1401 @Override
1402 public void filterElements(Object[] elements, IProgressMonitor monitor) {
1403 for (int i = 0; i < elements.length; i++) {
1404 fileSystemElements.add((TraceFileSystemElement)elements[i]);
1405 }
1406 }
1407 };
1408
1409 // List fileSystemElements will be filled using the passThroughFilter
1410 SubMonitor subMonitor = SubMonitor.convert(progressMonitor, 1);
282218e9 1411 fSelectionGroup.getAllCheckedListItems(passThroughFilter, subMonitor);
29ceb238
BH
1412
1413 // Check if operation was cancelled.
1414 ModalContext.checkCanceled(subMonitor);
1415
16f91bd5 1416 Iterator<TraceFileSystemElement> fileSystemElementsIter = fileSystemElements.iterator();
c8cf44dc 1417 IFolder destTempFolder = null;
29ceb238 1418 subMonitor = SubMonitor.convert(progressMonitor, fileSystemElements.size());
c8cf44dc
MAL
1419 if (fImportFromArchive) {
1420 // When importing from archive, we first extract the
1421 // *selected* files to a temporary folder then create a new
1422 // Iterator<TraceFileSystemElement> that points to the
1423 // extracted files. This way, the import operator can
1424 // continue as it normally would.
1425
1426 subMonitor = SubMonitor.convert(progressMonitor, fileSystemElements.size() * 2);
1427 destTempFolder = fTargetFolder.getProject().getFolder(TRACE_IMPORT_TEMP_FOLDER);
1428 if (destTempFolder.exists()) {
1429 SubProgressMonitor monitor = new SubProgressMonitor(subMonitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK);
1430 destTempFolder.delete(true, monitor);
1431 }
1432 SubProgressMonitor monitor = new SubProgressMonitor(subMonitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK);
1433 destTempFolder.create(IResource.HIDDEN, true, monitor);
1434
1435 fileSystemElementsIter = extractSelectedFiles(fileSystemElementsIter, destTempFolder, subMonitor);
1436 // We need to update the source container path because the
1437 // "preserve folder structure" option would create the
1438 // wrong folders otherwise.
1439 fBaseSourceContainerPath = destTempFolder.getLocation();
1440 }
252c602c 1441
16f91bd5 1442 while (fileSystemElementsIter.hasNext()) {
252c602c
BH
1443 ModalContext.checkCanceled(progressMonitor);
1444 currentPath = null;
16f91bd5 1445 TraceFileSystemElement element = fileSystemElementsIter.next();
c8cf44dc
MAL
1446 IFileSystemObject fileSystemObject = element.getFileSystemObject();
1447 String resourcePath = element.getFileSystemObject().getAbsolutePath(fBaseSourceContainerPath.toOSString());
0e1d517e
MAL
1448 element.setDestinationContainerPath(computeDestinationContainerPath(new Path(resourcePath)));
1449
252c602c
BH
1450 currentPath = resourcePath;
1451 SubMonitor sub = subMonitor.newChild(1);
16f91bd5
BH
1452 if (element.isDirectory()) {
1453 if (!folderElements.containsKey(resourcePath)) {
1454 if (isDirectoryTrace(element)) {
1455 folderElements.put(resourcePath, element);
c659283d 1456 validateAndImportTrace(element, sub);
252c602c
BH
1457 }
1458 }
1459 } else {
16f91bd5 1460 TraceFileSystemElement parentElement = (TraceFileSystemElement)element.getParent();
c8cf44dc 1461 String parentPath = parentElement.getFileSystemObject().getAbsolutePath(fBaseSourceContainerPath.toOSString());
0e1d517e 1462 parentElement.setDestinationContainerPath(computeDestinationContainerPath(new Path(parentPath)));
252c602c 1463 currentPath = parentPath;
16f91bd5
BH
1464 if (!folderElements.containsKey(parentPath)) {
1465 if (isDirectoryTrace(parentElement)) {
1466 folderElements.put(parentPath, parentElement);
c659283d 1467 validateAndImportTrace(parentElement, sub);
252c602c 1468 } else {
c8cf44dc 1469 if (fileSystemObject.exists()) {
c659283d 1470 validateAndImportTrace(element, sub);
002f9f07 1471 }
002f9f07
BH
1472 }
1473 }
1474 }
1475 }
c8cf44dc
MAL
1476
1477 if (destTempFolder != null && destTempFolder.exists()) {
1478 destTempFolder.delete(true, progressMonitor);
1479 }
1480
252c602c
BH
1481 setStatus(Status.OK_STATUS);
1482 } catch (InterruptedException e) {
1483 setStatus(Status.CANCEL_STATUS);
1484 } catch (Exception e) {
0e1d517e
MAL
1485 String errorMessage = Messages.ImportTraceWizard_ImportProblem + ": " + //$NON-NLS-1$
1486 (currentPath != null ? currentPath : ""); //$NON-NLS-1$
1487 Activator.getDefault().logError(errorMessage, e);
1488 setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, errorMessage , e));
1489 }
1490 }
1491
c8cf44dc
MAL
1492 private Iterator<TraceFileSystemElement> extractSelectedFiles(Iterator<TraceFileSystemElement> fileSystemElementsIter, IFolder tempFolder, IProgressMonitor progressMonitor) throws InterruptedException,
1493 InvocationTargetException {
1494 List<TraceFileSystemElement> subList = new ArrayList<>();
1495 // Collect all the elements
1496 while (fileSystemElementsIter.hasNext()) {
1497 ModalContext.checkCanceled(progressMonitor);
1498 TraceFileSystemElement element = fileSystemElementsIter.next();
1499 if (element.isDirectory()) {
1500 Object[] array = element.getFiles().getChildren();
1501 for (int i = 0; i < array.length; i++) {
1502 subList.add((TraceFileSystemElement)array[i]);
1503 }
1504 }
1505 subList.add(element);
1506 }
1507
1508 // Find a sensible root element
1509 TraceFileSystemElement root = subList.get(0);
1510 while (root.getParent() != null) {
1511 root = (TraceFileSystemElement) root.getParent();
1512 }
1513
1514 ImportProvider fileSystemStructureProvider = new ImportProvider();
1515
1516 IOverwriteQuery myQueryImpl = new IOverwriteQuery() {
1517 @Override
1518 public String queryOverwrite(String file) {
1519 return IOverwriteQuery.NO_ALL;
1520 }
1521 };
1522
1523 progressMonitor.setTaskName(Messages.ImportTraceWizard_ExtractImportOperationTaskName);
1524 IPath containerPath = tempFolder.getFullPath();
1525 ImportOperation operation = new ImportOperation(containerPath, root, fileSystemStructureProvider, myQueryImpl, subList);
1526 operation.setContext(getShell());
1527
1528 operation.setCreateContainerStructure(true);
1529 operation.setOverwriteResources(false);
1530 operation.setVirtualFolders(false);
1531
1532 operation.run(new SubProgressMonitor(progressMonitor, subList.size(), SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK));
1533
1534 // Create the new import provider and root element based on the extracted temp folder
1535 FileSystemObjectImportStructureProvider importStructureProvider = new FileSystemObjectImportStructureProvider(FileSystemStructureProvider.INSTANCE, null);
1536 IFileSystemObject rootElement = importStructureProvider.getIFileSystemObject(new File(tempFolder.getLocation().toOSString()));
1537 TraceFileSystemElement createRootElement = createRootElement(rootElement, importStructureProvider);
1538 List<TraceFileSystemElement> list = new ArrayList<>();
1539 getAllChildren(list, createRootElement);
1540 Iterator<TraceFileSystemElement> extractedElementsIter = list.iterator();
1541 return extractedElementsIter;
1542 }
1543
1544 /**
1545 * Get all the TraceFileSystemElements recursively.
1546 *
1547 * @param result
1548 * the list accumulating the result
1549 * @param rootElement
1550 * the root element of the file system to be imported
1551 */
1552 private void getAllChildren(List<TraceFileSystemElement> result, TraceFileSystemElement rootElement) {
1553 AdaptableList files = rootElement.getFiles();
1554 for (Object file : files.getChildren()) {
1555 result.add((TraceFileSystemElement) file);
1556 }
1557
1558 AdaptableList folders = rootElement.getFolders();
1559 for (Object folder : folders.getChildren()) {
1560 getAllChildren(result, (TraceFileSystemElement)folder);
1561 }
1562 }
1563
0e1d517e
MAL
1564 private IPath computeDestinationContainerPath(Path resourcePath) {
1565 IPath destinationContainerPath = fDestinationContainerPath;
1566
1567 // We need to figure out the new destination path relative to the selected "base" source directory.
1568 // Here for example, the selected source directory is /home/user
d0e34947 1569 if ((fImportOptionFlags & OPTION_PRESERVE_FOLDER_STRUCTURE) != 0) {
0e1d517e
MAL
1570 // /home/user/bar/foo/trace -> /home/user/bar/foo
1571 IPath sourceContainerPath = resourcePath.removeLastSegments(1);
1572 if (fBaseSourceContainerPath.equals(resourcePath)) {
1573 // Use resourcePath directory if fBaseSourceContainerPath points to a directory trace
1574 sourceContainerPath = resourcePath;
1575 }
1576 // /home/user/bar/foo, /home/user -> bar/foo
1577 IPath relativeContainerPath = sourceContainerPath.makeRelativeTo(fBaseSourceContainerPath);
1578 // project/Traces + bar/foo -> project/Traces/bar/foo
1579 destinationContainerPath = fDestinationContainerPath.append(relativeContainerPath);
002f9f07 1580 }
0e1d517e 1581 return destinationContainerPath;
002f9f07
BH
1582 }
1583
c659283d 1584 private void validateAndImportTrace(TraceFileSystemElement fileSystemElement, IProgressMonitor monitor)
252c602c 1585 throws TmfTraceImportException, CoreException, InvocationTargetException, InterruptedException {
c8cf44dc
MAL
1586 String parentContainerPath = fBaseSourceContainerPath.toOSString();
1587 String path = fileSystemElement.getFileSystemObject().getAbsolutePath(parentContainerPath);
350cae41 1588 TraceTypeHelper traceTypeHelper = null;
c659283d 1589
252c602c 1590 if (fTraceType == null) {
c659283d 1591 // Auto Detection
350cae41
PT
1592 try {
1593 traceTypeHelper = TmfTraceTypeUIUtils.selectTraceType(path, null, null);
1594 } catch (TmfTraceImportException e) {
1595 // the trace did not match any trace type
1596 }
1597 if (traceTypeHelper == null) {
d0e34947 1598 if ((fImportOptionFlags & OPTION_IMPORT_UNRECOGNIZED_TRACES) != 0) {
98bb2f6a 1599 importResource(fileSystemElement, monitor);
350cae41
PT
1600 }
1601 return;
1602 }
252c602c 1603 } else {
a4a116c3 1604 boolean isDirectoryTraceType = TmfTraceType.isDirectoryTraceType(fTraceType);
c659283d 1605 if (fileSystemElement.isDirectory() != isDirectoryTraceType) {
252c602c
BH
1606 return;
1607 }
a4a116c3 1608 traceTypeHelper = TmfTraceType.getTraceType(fTraceType);
16f91bd5 1609
350cae41 1610 if (traceTypeHelper == null) {
c659283d
BH
1611 // Trace type not found
1612 throw new TmfTraceImportException(Messages.ImportTraceWizard_TraceTypeNotFound);
252c602c 1613 }
c659283d 1614
a8ddd783 1615 if (!traceTypeHelper.validate(path).isOK()) {
c659283d 1616 // Trace type exist but doesn't validate for given trace.
350cae41
PT
1617 return;
1618 }
252c602c 1619 }
002f9f07 1620
c659283d 1621 // Finally import trace
0e1d517e
MAL
1622 IResource importedResource = importResource(fileSystemElement, monitor);
1623 if (importedResource != null) {
1624 TmfTraceTypeUIUtils.setTraceType(importedResource, traceTypeHelper);
002f9f07 1625 }
002f9f07 1626
252c602c 1627 }
002f9f07 1628
16f91bd5
BH
1629 /**
1630 * Imports a trace resource to project. In case of name collision the
1631 * user will be asked to confirm overwriting the existing trace,
1632 * overwriting or skipping the trace to be imported.
1633 *
1634 * @param fileSystemElement
1635 * trace file system object to import
1636 * @param monitor
1637 * a progress monitor
0e1d517e 1638 * @return the imported resource or null if no resource was imported
16f91bd5
BH
1639 *
1640 * @throws InvocationTargetException
1641 * if problems during import operation
1642 * @throws InterruptedException
1643 * if cancelled
1644 * @throws CoreException
1645 * if problems with workspace
1646 */
0e1d517e 1647 private IResource importResource(TraceFileSystemElement fileSystemElement, IProgressMonitor monitor)
16f91bd5 1648 throws InvocationTargetException, InterruptedException, CoreException {
0e1d517e 1649
16f91bd5
BH
1650 ImportConfirmation mode = checkForNameClashes(fileSystemElement);
1651 switch (mode) {
1652 case RENAME:
1653 case RENAME_ALL:
1654 rename(fileSystemElement);
1655 break;
1656 case OVERWRITE:
1657 case OVERWRITE_ALL:
1658 delete(fileSystemElement, monitor);
1659 break;
1660 case CONTINUE:
1661 break;
1662 case SKIP:
1663 case SKIP_ALL:
1664 default:
0e1d517e 1665 return null;
16f91bd5
BH
1666 }
1667
1668 List<TraceFileSystemElement> subList = new ArrayList<>();
1669
16f91bd5
BH
1670 FileSystemElement parentFolder = fileSystemElement.getParent();
1671
0e1d517e
MAL
1672 IPath containerPath = fileSystemElement.getDestinationContainerPath();
1673 IPath tracePath = containerPath.addTrailingSeparator().append(fileSystemElement.getLabel());
d0e34947
MAL
1674 boolean createLinksInWorkspace = (fImportOptionFlags & OPTION_CREATE_LINKS_IN_WORKSPACE) != 0;
1675 if (fileSystemElement.isDirectory() && !createLinksInWorkspace) {
0e1d517e 1676 containerPath = tracePath;
16f91bd5
BH
1677
1678 Object[] array = fileSystemElement.getFiles().getChildren();
1679 for (int i = 0; i < array.length; i++) {
1680 subList.add((TraceFileSystemElement)array[i]);
1681 }
1682 parentFolder = fileSystemElement;
1683
1684 } else {
1685 subList.add(fileSystemElement);
1686 }
1687
1688
1689 ImportProvider fileSystemStructureProvider = new ImportProvider();
252c602c 1690
252c602c
BH
1691 IOverwriteQuery myQueryImpl = new IOverwriteQuery() {
1692 @Override
1693 public String queryOverwrite(String file) {
16f91bd5 1694 return IOverwriteQuery.NO_ALL;
252c602c
BH
1695 }
1696 };
1697
c8cf44dc 1698 monitor.setTaskName(Messages.ImportTraceWizard_ImportOperationTaskName + " " + fileSystemElement.getFileSystemObject().getAbsolutePath(fBaseSourceContainerPath.toOSString())); //$NON-NLS-1$
16f91bd5 1699 ImportOperation operation = new ImportOperation(containerPath, parentFolder, fileSystemStructureProvider, myQueryImpl, subList);
002f9f07 1700 operation.setContext(getShell());
002f9f07 1701
252c602c 1702 operation.setCreateContainerStructure(false);
16f91bd5 1703 operation.setOverwriteResources(false);
d0e34947 1704 operation.setCreateLinks(createLinksInWorkspace);
252c602c 1705 operation.setVirtualFolders(false);
002f9f07 1706
252c602c 1707 operation.run(new SubProgressMonitor(monitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK));
c8cf44dc 1708 String sourceLocation = fileSystemElement.getFileSystemObject().getSourceLocation();
0e1d517e 1709 IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(tracePath);
c8cf44dc
MAL
1710 if (sourceLocation != null) {
1711 resource.setPersistentProperty(TmfCommonConstants.SOURCE_LOCATION, sourceLocation);
1712 }
89730b51 1713
0e1d517e 1714 return resource;
16f91bd5 1715 }
002f9f07 1716
c8cf44dc
MAL
1717 private boolean isDirectoryTrace(TraceFileSystemElement fileSystemElement) {
1718 String path = fileSystemElement.getFileSystemObject().getAbsolutePath(fBaseSourceContainerPath.toOSString());
a4a116c3 1719 if (TmfTraceType.isDirectoryTrace(path)) {
252c602c
BH
1720 return true;
1721 }
002f9f07
BH
1722 return false;
1723 }
1724
16f91bd5 1725 private ImportConfirmation checkForNameClashes(TraceFileSystemElement fileSystemElement) throws InterruptedException {
0e1d517e 1726 IPath tracePath = getInitialDestinationPath(fileSystemElement);
16f91bd5
BH
1727
1728 // handle rename
0e1d517e 1729 if (getExistingTrace(tracePath) != null) {
16f91bd5
BH
1730 if ((fConfirmationMode == ImportConfirmation.RENAME_ALL) ||
1731 (fConfirmationMode == ImportConfirmation.OVERWRITE_ALL) ||
1732 (fConfirmationMode == ImportConfirmation.SKIP_ALL)) {
1733 return fConfirmationMode;
1734 }
1735
0e1d517e 1736 int returnCode = promptForOverwrite(tracePath);
16f91bd5
BH
1737 if (returnCode < 0) {
1738 // Cancel
1739 throw new InterruptedException();
1740 }
1741 fConfirmationMode = ImportConfirmation.values()[returnCode];
1742 return fConfirmationMode;
1743 }
1744 return ImportConfirmation.CONTINUE;
1745 }
1746
0e1d517e 1747 private int promptForOverwrite(IPath tracePath) {
16f91bd5 1748 final MessageDialog dialog = new MessageDialog(getContainer()
0e1d517e 1749 .getShell(), null, null, NLS.bind(Messages.ImportTraceWizard_TraceAlreadyExists, tracePath.makeRelativeTo(fTraceFolderElement.getProject().getPath())),
16f91bd5
BH
1750 MessageDialog.QUESTION, new String[] {
1751 ImportConfirmation.RENAME.getInName(),
1752 ImportConfirmation.RENAME_ALL.getInName(),
1753 ImportConfirmation.OVERWRITE.getInName(),
1754 ImportConfirmation.OVERWRITE_ALL.getInName(),
1755 ImportConfirmation.SKIP.getInName(),
1756 ImportConfirmation.SKIP_ALL.getInName(),
1757 }, 4) {
1758 @Override
1759 protected int getShellStyle() {
1760 return super.getShellStyle() | SWT.SHEET;
1761 }
1762 };
1763
1764 final int[] returnValue = new int[1];
1765 getShell().getDisplay().syncExec(new Runnable() {
1766
1767 @Override
1768 public void run() {
1769 returnValue[0] = dialog.open();
1770 }
1771 });
1772 return returnValue[0];
1773 }
1774
0e1d517e
MAL
1775 /**
1776 * @return the initial destination path, before rename, if any
1777 */
1778 private IPath getInitialDestinationPath(TraceFileSystemElement fileSystemElement) {
1779 IPath traceFolderPath = fileSystemElement.getDestinationContainerPath();
c8cf44dc 1780 return traceFolderPath.append(fileSystemElement.getFileSystemObject().getLabel());
0e1d517e
MAL
1781 }
1782
16f91bd5 1783 private void rename(TraceFileSystemElement fileSystemElement) {
0e1d517e
MAL
1784 IPath tracePath = getInitialDestinationPath(fileSystemElement);
1785 TmfTraceElement trace = getExistingTrace(tracePath);
16f91bd5
BH
1786 if (trace == null) {
1787 return;
1788 }
1789
0e1d517e
MAL
1790 // Not using IFolder on purpose to leave the door open to import directly into an IProject
1791 IContainer folder = (IContainer) trace.getParent().getResource();
16f91bd5
BH
1792 int i = 2;
1793 while (true) {
1794 String name = trace.getName() + '(' + Integer.toString(i++) + ')';
1795 IResource resource = folder.findMember(name);
1796 if (resource == null) {
1797 fileSystemElement.setLabel(name);
1798 return;
1799 }
1800 }
1801 }
1802
1803 private void delete(TraceFileSystemElement fileSystemElement, IProgressMonitor monitor) throws CoreException {
0e1d517e
MAL
1804 IPath tracePath = getInitialDestinationPath(fileSystemElement);
1805 TmfTraceElement trace = getExistingTrace(tracePath);
16f91bd5
BH
1806 if (trace == null) {
1807 return;
1808 }
1809
1810 trace.delete(monitor);
1811 }
1812
0e1d517e 1813 private TmfTraceElement getExistingTrace(IPath tracePath) {
16f91bd5
BH
1814 List<TmfTraceElement> traces = fTraceFolderElement.getTraces();
1815 for (TmfTraceElement t : traces) {
0e1d517e 1816 if (t.getPath().equals(tracePath)) {
16f91bd5
BH
1817 return t;
1818 }
1819 }
1820 return null;
1821 }
1822
252c602c
BH
1823 /**
1824 * Set the status for this operation
1825 *
1826 * @param status
1827 * the status
1828 */
1829 protected void setStatus(IStatus status) {
1830 fStatus = status;
002f9f07
BH
1831 }
1832
252c602c
BH
1833 public IStatus getStatus() {
1834 return fStatus;
1835 }
002f9f07
BH
1836 }
1837
252c602c
BH
1838 /**
1839 * The <code>TraceFileSystemElement</code> is a <code>FileSystemElement</code> that knows
1840 * if it has been populated or not.
1841 */
16f91bd5 1842 private static class TraceFileSystemElement extends FileSystemElement {
252c602c 1843
16f91bd5
BH
1844 private boolean fIsPopulated = false;
1845 private String fLabel = null;
0e1d517e 1846 private IPath fDestinationContainerPath;
c8cf44dc 1847 private FileSystemObjectImportStructureProvider fProvider;
252c602c 1848
c8cf44dc 1849 public TraceFileSystemElement(String name, FileSystemElement parent, boolean isDirectory, FileSystemObjectImportStructureProvider provider) {
252c602c 1850 super(name, parent, isDirectory);
c8cf44dc 1851 fProvider = provider;
252c602c
BH
1852 }
1853
0e1d517e
MAL
1854 public void setDestinationContainerPath(IPath destinationContainerPath) {
1855 fDestinationContainerPath = destinationContainerPath;
1856 }
1857
252c602c 1858 public void setPopulated() {
16f91bd5 1859 fIsPopulated = true;
252c602c
BH
1860 }
1861
1862 public boolean isPopulated() {
16f91bd5 1863 return fIsPopulated;
252c602c
BH
1864 }
1865
1866 @Override
1867 public AdaptableList getFiles() {
16f91bd5 1868 if(!fIsPopulated) {
252c602c
BH
1869 populateElementChildren();
1870 }
1871 return super.getFiles();
1872 }
1873
1874 @Override
1875 public AdaptableList getFolders() {
16f91bd5 1876 if(!fIsPopulated) {
252c602c
BH
1877 populateElementChildren();
1878 }
1879 return super.getFolders();
1880 }
002f9f07 1881
16f91bd5
BH
1882 /**
1883 * Sets the label for the trace to be used when importing at trace.
1884 * @param name
1885 * the label for the trace
1886 */
1887 public void setLabel(String name) {
1888 fLabel = name;
1889 }
1890
1891 /**
1892 * Returns the label for the trace to be used when importing at trace.
1893 *
1894 * @return the label of trace resource
1895 */
1896 public String getLabel() {
1897 if (fLabel == null) {
c8cf44dc 1898 return getFileSystemObject().getLabel();
16f91bd5
BH
1899 }
1900 return fLabel;
1901 }
1902
0e1d517e
MAL
1903 /**
1904 * The full path to the container that will contain the trace
1905 *
1906 * @return the destination container path
1907 */
1908 public IPath getDestinationContainerPath() {
1909 return fDestinationContainerPath;
1910 }
1911
252c602c
BH
1912 /**
1913 * Populates the children of the specified parent <code>FileSystemElement</code>
1914 */
1915 private void populateElementChildren() {
c8cf44dc
MAL
1916 List<IFileSystemObject> allchildren = fProvider.getChildren(this.getFileSystemObject());
1917 Object child = null;
252c602c 1918 TraceFileSystemElement newelement = null;
c8cf44dc 1919 Iterator<IFileSystemObject> iter = allchildren.iterator();
252c602c
BH
1920 while(iter.hasNext()) {
1921 child = iter.next();
c8cf44dc 1922 newelement = new TraceFileSystemElement(fProvider.getLabel(child), this, fProvider.isFolder(child), fProvider);
252c602c
BH
1923 newelement.setFileSystemObject(child);
1924 }
1925 setPopulated();
1926 }
c8cf44dc
MAL
1927
1928 public FileSystemObjectImportStructureProvider getProvider() {
1929 return fProvider;
1930 }
1931
1932 @Override
1933 public IFileSystemObject getFileSystemObject() {
1934 Object fileSystemObject = super.getFileSystemObject();
1935 return (IFileSystemObject) fileSystemObject;
1936 }
252c602c 1937 }
16f91bd5 1938
c8cf44dc
MAL
1939 /**
1940 * This interface abstracts the differences between different kinds of
1941 * FileSystemObjects such as File, TarEntry and ZipEntry. This allows
1942 * clients (TraceFileSystemElement, TraceValidateAndImportOperation) to
1943 * handle all the types transparently.
1944 */
1945 private interface IFileSystemObject {
1946 String getLabel();
1947 String getAbsolutePath(String parentContainerPath);
1948 String getSourceLocation();
1949 Object getRawFileSystemObject();
1950 boolean exists();
1951 }
1952
1953 /**
1954 * The "File" implementation of an IFileSystemObject
1955 */
1956 private static class FileFileSystemObject implements IFileSystemObject {
1957
1958 private File fFileSystemObject;
1959
1960 private FileFileSystemObject(File fileSystemObject) {
1961 fFileSystemObject = fileSystemObject;
1962 }
1963
1964 @Override
1965 public String getLabel() {
1966 String name = fFileSystemObject.getName();
1967 if (name.length() == 0) {
1968 return fFileSystemObject.getPath();
1969 }
1970 return name;
1971 }
1972
1973 @Override
1974 public String getAbsolutePath(String parentContainerPath) {
1975 return fFileSystemObject.getAbsolutePath();
1976 }
1977
1978 @Override
1979 public boolean exists() {
1980 return fFileSystemObject.exists();
1981 }
1982
1983 @Override
1984 public String getSourceLocation() {
1985 IResource sourceResource;
1986 String sourceLocation = null;
1987 if (fFileSystemObject.isDirectory()) {
1988 sourceResource = ResourcesPlugin.getWorkspace().getRoot().getContainerForLocation(Path.fromOSString(fFileSystemObject.getAbsolutePath()));
1989 } else {
1990 sourceResource = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(Path.fromOSString(fFileSystemObject.getAbsolutePath()));
1991 }
1992 if (sourceResource != null && sourceResource.exists()) {
1993 try {
1994 sourceLocation = sourceResource.getPersistentProperty(TmfCommonConstants.SOURCE_LOCATION);
1995 } catch (CoreException e) {
1996 // Something went wrong with the already existing resource.
1997 // This is not a problem, we'll assign a new location below.
1998 }
1999 }
2000 if (sourceLocation == null) {
2001 sourceLocation = URIUtil.toUnencodedString(fFileSystemObject.toURI());
2002 }
2003 return sourceLocation;
2004 }
2005
2006 @Override
2007 public Object getRawFileSystemObject() {
2008 return fFileSystemObject;
2009 }
2010 }
2011
2012 /**
2013 * The "Tar" implementation of an IFileSystemObject
2014 */
2015 private static class TarFileSystemObject implements IFileSystemObject {
2016
2017 private TarEntry fFileSystemObject;
2018 private String fArchivePath;
2019
2020 private TarFileSystemObject(TarEntry fileSystemObject, String archivePath) {
2021 fFileSystemObject = fileSystemObject;
2022 fArchivePath = archivePath;
2023 }
16f91bd5 2024
c8cf44dc
MAL
2025 @Override
2026 public String getLabel() {
2027 return new Path(fFileSystemObject.getName()).lastSegment();
2028 }
2029
2030 @Override
2031 public String getAbsolutePath(String parentContainerPath) {
2032 return new Path(parentContainerPath).append(fFileSystemObject.getName()).toOSString();
2033 }
2034
2035 @Override
2036 public boolean exists() {
2037 return true;
2038 }
2039
2040 @Override
2041 public String getSourceLocation() {
2042 URI uri = new File(fArchivePath).toURI();
2043 IPath entryPath = new Path(fFileSystemObject.getName());
2044 return URIUtil.toUnencodedString(URIUtil.toJarURI(uri, entryPath));
2045 }
2046
2047 @Override
2048 public Object getRawFileSystemObject() {
2049 return fFileSystemObject;
2050 }
2051 }
2052
2053 /**
2054 * The "Zip" implementation of an IFileSystemObject
2055 */
2056 private static class ZipFileSystemObject implements IFileSystemObject {
2057
2058 private ZipEntry fFileSystemObject;
2059 private String fArchivePath;
2060
2061 private ZipFileSystemObject(ZipEntry fileSystemObject, String archivePath) {
2062 fFileSystemObject = fileSystemObject;
2063 fArchivePath = archivePath;
2064 }
2065
2066 @Override
2067 public String getLabel() {
2068 return new Path(fFileSystemObject.getName()).lastSegment();
2069 }
2070
2071 @Override
2072 public String getAbsolutePath(String parentContainerPath) {
2073 return new Path(parentContainerPath).append(fFileSystemObject.getName()).toOSString();
2074 }
2075
2076 @Override
2077 public boolean exists() {
2078 return true;
2079 }
2080
2081 @Override
2082 public String getSourceLocation() {
2083 URI uri = new File(fArchivePath).toURI();
2084 IPath entryPath = new Path(fFileSystemObject.getName());
2085 return URIUtil.toUnencodedString(URIUtil.toJarURI(uri, entryPath));
2086 }
2087
2088 @Override
2089 public Object getRawFileSystemObject() {
2090 return fFileSystemObject;
2091 }
2092 }
2093
2094 private class ImportProvider implements IImportStructureProvider {
16f91bd5
BH
2095
2096 ImportProvider() {
2097 }
2098
2099 @Override
2100 public String getLabel(Object element) {
2101 TraceFileSystemElement resource = (TraceFileSystemElement)element;
2102 return resource.getLabel();
2103 }
2104
2105 @Override
2106 public List getChildren(Object element) {
2107 TraceFileSystemElement resource = (TraceFileSystemElement)element;
2108 Object[] array = resource.getFiles().getChildren();
2109 List<Object> list = new ArrayList<>();
2110 for (int i = 0; i < array.length; i++) {
2111 list.add(array[i]);
2112 }
2113 return list;
2114 }
2115
2116 @Override
2117 public InputStream getContents(Object element) {
2118 TraceFileSystemElement resource = (TraceFileSystemElement)element;
c8cf44dc 2119 return resource.getProvider().getContents(resource.getFileSystemObject());
16f91bd5
BH
2120 }
2121
2122 @Override
2123 public String getFullPath(Object element) {
2124 TraceFileSystemElement resource = (TraceFileSystemElement)element;
c8cf44dc 2125 return resource.getProvider().getFullPath(resource.getFileSystemObject());
16f91bd5
BH
2126 }
2127
2128 @Override
2129 public boolean isFolder(Object element) {
2130 TraceFileSystemElement resource = (TraceFileSystemElement)element;
2131 return resource.isDirectory();
2132 }
2133 }
2134
2135 private enum ImportConfirmation {
2136 // ------------------------------------------------------------------------
2137 // Enum definition
2138 // ------------------------------------------------------------------------
2139 RENAME(Messages.ImportTraceWizard_ImportConfigurationRename),
2140 RENAME_ALL(Messages.ImportTraceWizard_ImportConfigurationRenameAll),
2141 OVERWRITE(Messages.ImportTraceWizard_ImportConfigurationOverwrite),
2142 OVERWRITE_ALL(Messages.ImportTraceWizard_ImportConfigurationOverwriteAll),
2143 SKIP(Messages.ImportTraceWizard_ImportConfigurationSkip),
2144 SKIP_ALL(Messages.ImportTraceWizard_ImportConfigurationSkipAll),
2145 CONTINUE("CONTINUE"); //$NON-NLS-1$
2146
2147 // ------------------------------------------------------------------------
2148 // Attributes
2149 // ------------------------------------------------------------------------
2150 /**
2151 * Name of enum
2152 */
2153 private final String fInName;
2154
2155 // ------------------------------------------------------------------------
2156 // Constuctors
2157 // ------------------------------------------------------------------------
2158
2159 /**
2160 * Private constructor
2161 * @param name the name of state
2162 */
2163 private ImportConfirmation(String name) {
2164 fInName = name;
2165 }
2166
2167 // ------------------------------------------------------------------------
2168 // Accessors
2169 // ------------------------------------------------------------------------
2170 /**
2171 * @return state name
2172 */
2173 public String getInName() {
2174 return fInName;
2175 }
2176 }
002f9f07 2177}
This page took 0.197721 seconds and 5 git commands to generate.