tmf: Unify import and validate methods
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / 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
002f9f07
BH
17 *******************************************************************************/
18
19package org.eclipse.linuxtools.tmf.ui.project.wizards.importtrace;
20
21import java.io.File;
16f91bd5 22import java.io.InputStream;
002f9f07
BH
23import java.lang.reflect.InvocationTargetException;
24import java.util.ArrayList;
002f9f07
BH
25import java.util.HashMap;
26import java.util.Iterator;
002f9f07
BH
27import java.util.List;
28import java.util.Map;
002f9f07
BH
29
30import org.eclipse.core.resources.IContainer;
31import org.eclipse.core.resources.IFolder;
32import org.eclipse.core.resources.IProject;
33import org.eclipse.core.resources.IResource;
34import org.eclipse.core.resources.ResourcesPlugin;
35import org.eclipse.core.runtime.CoreException;
36import org.eclipse.core.runtime.IPath;
252c602c 37import org.eclipse.core.runtime.IProgressMonitor;
002f9f07 38import org.eclipse.core.runtime.IStatus;
252c602c 39import org.eclipse.core.runtime.NullProgressMonitor;
002f9f07
BH
40import org.eclipse.core.runtime.Path;
41import org.eclipse.core.runtime.Platform;
252c602c
BH
42import org.eclipse.core.runtime.Status;
43import org.eclipse.core.runtime.SubMonitor;
44import org.eclipse.core.runtime.SubProgressMonitor;
45import org.eclipse.jface.dialogs.IDialogSettings;
16f91bd5 46import org.eclipse.jface.dialogs.MessageDialog;
252c602c
BH
47import org.eclipse.jface.operation.IRunnableWithProgress;
48import org.eclipse.jface.operation.ModalContext;
002f9f07
BH
49import org.eclipse.jface.viewers.IStructuredSelection;
50import org.eclipse.jface.viewers.ITreeContentProvider;
51import org.eclipse.linuxtools.internal.tmf.ui.Activator;
252c602c 52import org.eclipse.linuxtools.tmf.core.TmfCommonConstants;
002f9f07 53import org.eclipse.linuxtools.tmf.core.TmfProjectNature;
252c602c 54import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceImportException;
002f9f07
BH
55import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceType;
56import org.eclipse.linuxtools.tmf.core.project.model.TraceTypeHelper;
002f9f07 57import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectRegistry;
16f91bd5 58import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement;
002f9f07
BH
59import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceFolder;
60import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceTypeUIUtils;
61import org.eclipse.linuxtools.tmf.ui.project.wizards.Messages;
16f91bd5 62import org.eclipse.osgi.util.NLS;
002f9f07
BH
63import org.eclipse.swt.SWT;
64import org.eclipse.swt.custom.BusyIndicator;
65import org.eclipse.swt.events.FocusEvent;
66import org.eclipse.swt.events.FocusListener;
67import org.eclipse.swt.events.KeyEvent;
68import org.eclipse.swt.events.KeyListener;
69import org.eclipse.swt.events.SelectionAdapter;
70import org.eclipse.swt.events.SelectionEvent;
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;
78import org.eclipse.swt.widgets.Group;
79import org.eclipse.swt.widgets.Label;
80import org.eclipse.ui.IWorkbench;
81import org.eclipse.ui.dialogs.FileSystemElement;
252c602c 82import org.eclipse.ui.dialogs.IOverwriteQuery;
002f9f07 83import org.eclipse.ui.dialogs.WizardResourceImportPage;
252c602c 84import org.eclipse.ui.model.AdaptableList;
002f9f07 85import org.eclipse.ui.model.WorkbenchContentProvider;
002f9f07
BH
86import org.eclipse.ui.wizards.datatransfer.FileSystemStructureProvider;
87import org.eclipse.ui.wizards.datatransfer.IImportStructureProvider;
88import org.eclipse.ui.wizards.datatransfer.ImportOperation;
89
90/**
252c602c
BH
91 * A variant of the standard resource import wizard for importing traces
92 * to given tracing project. If no project or tracing project was selected
93 * the wizard imports it to the default tracing project which is created
94 * if necessary.
95 *
96 * In our case traces could be files or a directory structure. This wizard
97 * supports both cases. It imports traces for a selected trace type or, if
98 * no trace type is selected, it tries to detect the trace type automatically.
99 * However, the automatic detection is a best-effort and cannot guarantee
100 * that the detection is successful. The reason for this is that there might
101 * be multiple trace types that can be assigned to a single trace.
102 *
002f9f07 103 *
002f9f07
BH
104 * @author Francois Chouinard
105 * @since 2.0
106 */
107public class ImportTraceWizardPage extends WizardResourceImportPage {
108
002f9f07
BH
109 // ------------------------------------------------------------------------
110 // Constants
111 // ------------------------------------------------------------------------
002f9f07 112 private static final String IMPORT_WIZARD_PAGE = "ImportTraceWizardPage"; //$NON-NLS-1$
252c602c
BH
113 private static final String IMPORT_WIZARD_IMPORT_UNRECOGNIZED_ID = IMPORT_WIZARD_PAGE + ".import_unrecognized_traces_id"; //$NON-NLS-1$
114 private static final String SEPARATOR = ":"; //$NON-NLS-1$
115 private static final String AUTO_DETECT = Messages.ImportTraceWizard_AutoDetection;
002f9f07
BH
116
117 // ------------------------------------------------------------------------
118 // Attributes
119 // ------------------------------------------------------------------------
120
121 // Folder navigation start point (saved between invocations)
122 private static String fRootDirectory = null;
002f9f07
BH
123 // Target import directory ('Traces' folder)
124 private IFolder fTargetFolder;
16f91bd5
BH
125 // Target Trace folder element
126 private TmfTraceFolder fTraceFolderElement;
252c602c
BH
127 // Flag to handle destination folder change event
128 private Boolean fIsDestinationChanged = false;
129 // Combo box containing trace types
130 private Combo fTraceTypes;
131 // Button to ignore unrecognized traces or not
132 private Button fImportUnrecognizedButton;
133 // Button to overwrite existing resources or not
134 private Button fOverwriteExistingResourcesCheckbox;
135 // Button to link or copy traces to workspace
136 private Button fCreateLinksInWorkspaceButton;
137 private boolean entryChanged = false;
138 /** The directory name field */
139 protected Combo directoryNameField;
140 /** The directory browse button. */
141 protected Button directoryBrowseButton;
002f9f07
BH
142
143 // ------------------------------------------------------------------------
144 // Constructors
145 // ------------------------------------------------------------------------
146
147 /**
148 * Constructor. Creates the trace wizard page.
149 *
150 * @param name
151 * The name of the page.
152 * @param selection
153 * The current selection
154 */
155 protected ImportTraceWizardPage(String name, IStructuredSelection selection) {
156 super(name, selection);
157 }
158
159 /**
160 * Constructor
161 *
162 * @param workbench
163 * The workbench reference.
164 * @param selection
165 * The current selection
166 */
167 public ImportTraceWizardPage(IWorkbench workbench, IStructuredSelection selection) {
168 this(IMPORT_WIZARD_PAGE, selection);
169 setTitle(Messages.ImportTraceWizard_FileSystemTitle);
170 setDescription(Messages.ImportTraceWizard_ImportTrace);
171
172 // Locate the target trace folder
173 IFolder traceFolder = null;
174 Object element = selection.getFirstElement();
175
176 if (element instanceof TmfTraceFolder) {
16f91bd5
BH
177 fTraceFolderElement = (TmfTraceFolder) element;
178 fTraceFolderElement.getProject().getResource();
179 traceFolder = fTraceFolderElement.getResource();
002f9f07
BH
180 } else if (element instanceof IProject) {
181 IProject project = (IProject) element;
182 try {
183 if (project.hasNature(TmfProjectNature.ID)) {
252c602c 184 traceFolder = project.getFolder(TmfTraceFolder.TRACE_FOLDER_NAME);
16f91bd5 185 fTraceFolderElement = TmfProjectRegistry.getProject(project).getTracesFolder();
002f9f07
BH
186 }
187 } catch (CoreException e) {
188 }
189 }
190
252c602c
BH
191 /*
192 * If no tracing project was selected or trace folder doesn't exist use
193 */
194 if (traceFolder == null) {
195 IProject project = TmfProjectRegistry.createProject(
196 TmfCommonConstants.DEFAULT_TRACE_PROJECT_NAME, null, new NullProgressMonitor());
197 traceFolder = project.getFolder(TmfTraceFolder.TRACE_FOLDER_NAME);
16f91bd5 198 fTraceFolderElement = TmfProjectRegistry.getProject(project).getTracesFolder();
252c602c
BH
199 }
200
002f9f07
BH
201 // Set the target trace folder
202 if (traceFolder != null) {
203 fTargetFolder = traceFolder;
204 String path = traceFolder.getFullPath().toOSString();
205 setContainerFieldValue(path);
206 }
207 }
208
209 // ------------------------------------------------------------------------
210 // WizardResourceImportPage
211 // ------------------------------------------------------------------------
212
213 @Override
214 public void createControl(Composite parent) {
215 super.createControl(parent);
216 // Restore last directory if applicable
217 if (fRootDirectory != null) {
218 directoryNameField.setText(fRootDirectory);
219 updateFromSourceField();
220 }
221 }
222
223 @Override
224 protected void createSourceGroup(Composite parent) {
225 createDirectorySelectionGroup(parent);
226 createFileSelectionGroup(parent);
227 createTraceTypeGroup(parent);
228 validateSourceGroup();
229 }
230
231 @Override
252c602c
BH
232 protected ITreeContentProvider getFileProvider() {
233 return new WorkbenchContentProvider() {
002f9f07 234 @Override
252c602c
BH
235 public Object[] getChildren(Object object) {
236 if (object instanceof TraceFileSystemElement) {
237 TraceFileSystemElement element = (TraceFileSystemElement) object;
238 return element.getFiles().getChildren(element);
002f9f07 239 }
252c602c 240 return new Object[0];
002f9f07 241 }
252c602c 242 };
002f9f07
BH
243 }
244
245 @Override
246 protected ITreeContentProvider getFolderProvider() {
002f9f07
BH
247 return new WorkbenchContentProvider() {
248 @Override
249 public Object[] getChildren(Object o) {
252c602c
BH
250 if (o instanceof TraceFileSystemElement) {
251 TraceFileSystemElement element = (TraceFileSystemElement) o;
252 return element.getFolders().getChildren();
002f9f07
BH
253 }
254 return new Object[0];
255 }
002f9f07 256
252c602c
BH
257 @Override
258 public boolean hasChildren(Object o) {
259 if (o instanceof TraceFileSystemElement) {
260 TraceFileSystemElement element = (TraceFileSystemElement) o;
261 if (element.isPopulated()) {
262 return getChildren(element).length > 0;
263 }
264 //If we have not populated then wait until asked
265 return true;
002f9f07 266 }
252c602c 267 return false;
002f9f07 268 }
252c602c 269 };
002f9f07
BH
270 }
271
272 // ------------------------------------------------------------------------
273 // Directory Selection Group (forked WizardFileSystemResourceImportPage1)
274 // ------------------------------------------------------------------------
275
002f9f07
BH
276 /**
277 * creates the directory selection group.
278 *
279 * @param parent
280 * the parent composite
281 */
282 protected void createDirectorySelectionGroup(Composite parent) {
283
284 Composite directoryContainerGroup = new Composite(parent, SWT.NONE);
285 GridLayout layout = new GridLayout();
286 layout.numColumns = 3;
287 directoryContainerGroup.setLayout(layout);
288 directoryContainerGroup.setFont(parent.getFont());
289 directoryContainerGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
290
291 // Label ("Trace directory:")
292 Label groupLabel = new Label(directoryContainerGroup, SWT.NONE);
293 groupLabel.setText(Messages.ImportTraceWizard_DirectoryLocation);
294 groupLabel.setFont(parent.getFont());
295
296 // Directory name entry field
297 directoryNameField = new Combo(directoryContainerGroup, SWT.BORDER);
298 GridData data = new GridData(SWT.FILL, SWT.FILL, true, false);
299 data.widthHint = SIZING_TEXT_FIELD_WIDTH;
300 directoryNameField.setLayoutData(data);
301 directoryNameField.setFont(parent.getFont());
302
303 directoryNameField.addSelectionListener(new SelectionAdapter() {
304 @Override
305 public void widgetSelected(SelectionEvent e) {
306 updateFromSourceField();
307 }
308 });
309
310 directoryNameField.addKeyListener(new KeyListener() {
311 @Override
312 public void keyPressed(KeyEvent e) {
313 // If there has been a key pressed then mark as dirty
314 entryChanged = true;
315 if (e.character == SWT.CR) { // Windows...
316 entryChanged = false;
317 updateFromSourceField();
318 }
319 }
320
321 @Override
322 public void keyReleased(KeyEvent e) {
323 }
324 });
325
326 directoryNameField.addFocusListener(new FocusListener() {
327 @Override
328 public void focusGained(FocusEvent e) {
329 // Do nothing when getting focus
330 }
002f9f07
BH
331 @Override
332 public void focusLost(FocusEvent e) {
333 // Clear the flag to prevent constant update
334 if (entryChanged) {
335 entryChanged = false;
336 updateFromSourceField();
337 }
338 }
339 });
340
341 // Browse button
342 directoryBrowseButton = new Button(directoryContainerGroup, SWT.PUSH);
343 directoryBrowseButton.setText(Messages.ImportTraceWizard_BrowseButton);
344 directoryBrowseButton.addListener(SWT.Selection, this);
345 directoryBrowseButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
346 directoryBrowseButton.setFont(parent.getFont());
347 setButtonLayoutData(directoryBrowseButton);
348 }
349
350 // ------------------------------------------------------------------------
351 // Browse for the source directory
352 // ------------------------------------------------------------------------
353
354 @Override
355 public void handleEvent(Event event) {
356 if (event.widget == directoryBrowseButton) {
357 handleSourceDirectoryBrowseButtonPressed();
358 }
252c602c
BH
359
360 // Avoid overwriting destination path without repeatedly trigger
361 // call of handleEvent();
362 synchronized (fIsDestinationChanged) {
363 if (fIsDestinationChanged == false) {
364 event.display.asyncExec(new Runnable() {
365 @Override
366 public void run() {
367 synchronized (fIsDestinationChanged) {
368 fIsDestinationChanged = true;
369 String path = fTargetFolder.getFullPath().toOSString();
370 setContainerFieldValue(path);
371 }
372 }
373 });
374 } else {
375 fIsDestinationChanged = false;
376 }
377 }
002f9f07
BH
378 super.handleEvent(event);
379 }
380
252c602c
BH
381 @Override
382 protected void handleContainerBrowseButtonPressed() {
383 // Do nothing so that destination directory cannot be changed.
384 }
385
002f9f07
BH
386 /**
387 * Handle the button pressed event
388 */
389 protected void handleSourceDirectoryBrowseButtonPressed() {
390 String currentSource = directoryNameField.getText();
391 DirectoryDialog dialog = new DirectoryDialog(directoryNameField.getShell(), SWT.SAVE | SWT.SHEET);
392 dialog.setText(Messages.ImportTraceWizard_SelectTraceDirectoryTitle);
393 dialog.setMessage(Messages.ImportTraceWizard_SelectTraceDirectoryMessage);
394 dialog.setFilterPath(getSourceDirectoryName(currentSource));
395
396 String selectedDirectory = dialog.open();
397 if (selectedDirectory != null) {
398 // Just quit if the directory is not valid
399 if ((getSourceDirectory(selectedDirectory) == null) || selectedDirectory.equals(currentSource)) {
400 return;
401 }
402 // If it is valid then proceed to populate
403 setErrorMessage(null);
404 setSourceName(selectedDirectory);
405 }
406 }
407
408 private File getSourceDirectory() {
409 return getSourceDirectory(directoryNameField.getText());
410 }
411
412 private static File getSourceDirectory(String path) {
413 File sourceDirectory = new File(getSourceDirectoryName(path));
414 if (!sourceDirectory.exists() || !sourceDirectory.isDirectory()) {
415 return null;
416 }
417
418 return sourceDirectory;
419 }
420
421 private static String getSourceDirectoryName(String sourceName) {
422 IPath result = new Path(sourceName.trim());
423 if (result.getDevice() != null && result.segmentCount() == 0) {
424 result = result.addTrailingSeparator();
425 } else {
426 result = result.removeTrailingSeparator();
427 }
428 return result.toOSString();
429 }
430
431 private String getSourceDirectoryName() {
432 return getSourceDirectoryName(directoryNameField.getText());
433 }
434
435 private void updateFromSourceField() {
436 setSourceName(directoryNameField.getText());
437 updateWidgetEnablements();
438 }
439
440 private void setSourceName(String path) {
441 if (path.length() > 0) {
442 String[] currentItems = directoryNameField.getItems();
443 int selectionIndex = -1;
444 for (int i = 0; i < currentItems.length; i++) {
445 if (currentItems[i].equals(path)) {
446 selectionIndex = i;
447 }
448 }
449 if (selectionIndex < 0) {
450 int oldLength = currentItems.length;
451 String[] newItems = new String[oldLength + 1];
452 System.arraycopy(currentItems, 0, newItems, 0, oldLength);
453 newItems[oldLength] = path;
454 directoryNameField.setItems(newItems);
455 selectionIndex = oldLength;
456 }
457 directoryNameField.select(selectionIndex);
458 }
459 resetSelection();
460 }
461
462 // ------------------------------------------------------------------------
463 // File Selection Group (forked WizardFileSystemResourceImportPage1)
464 // ------------------------------------------------------------------------
002f9f07 465 private void resetSelection() {
252c602c
BH
466 TraceFileSystemElement root = getFileSystemTree();
467 selectionGroup.setRoot(root);
002f9f07
BH
468 }
469
252c602c 470 private TraceFileSystemElement getFileSystemTree() {
002f9f07
BH
471 File sourceDirectory = getSourceDirectory();
472 if (sourceDirectory == null) {
473 return null;
474 }
475 return selectFiles(sourceDirectory, FileSystemStructureProvider.INSTANCE);
476 }
477
252c602c
BH
478 private TraceFileSystemElement selectFiles(final Object rootFileSystemObject,
479 final IImportStructureProvider structureProvider) {
480 final TraceFileSystemElement[] results = new TraceFileSystemElement[1];
002f9f07
BH
481 BusyIndicator.showWhile(getShell().getDisplay(), new Runnable() {
482 @Override
483 public void run() {
484 // Create the root element from the supplied file system object
485 results[0] = createRootElement(rootFileSystemObject, structureProvider);
486 }
487 });
488 return results[0];
489 }
490
252c602c 491 private static TraceFileSystemElement createRootElement(Object fileSystemObject,
002f9f07
BH
492 IImportStructureProvider provider) {
493
494 boolean isContainer = provider.isFolder(fileSystemObject);
495 String elementLabel = provider.getLabel(fileSystemObject);
496
252c602c
BH
497 // Use an empty label so that display of the element's full name
498 // doesn't include a confusing label
499 TraceFileSystemElement dummyParent = new TraceFileSystemElement("", null, true);//$NON-NLS-1$
16f91bd5 500 dummyParent.setFileSystemObject(((File)fileSystemObject).getParentFile());
252c602c
BH
501 dummyParent.setPopulated();
502 TraceFileSystemElement result = new TraceFileSystemElement(
503 elementLabel, dummyParent, isContainer);
504 result.setFileSystemObject(fileSystemObject);
002f9f07 505
252c602c
BH
506 //Get the files for the element so as to build the first level
507 result.getFiles();
002f9f07
BH
508
509 return dummyParent;
510 }
511
512 // ------------------------------------------------------------------------
513 // Trace Type Group
514 // ------------------------------------------------------------------------
002f9f07
BH
515 private final void createTraceTypeGroup(Composite parent) {
516 Composite composite = new Composite(parent, SWT.NONE);
517 GridLayout layout = new GridLayout();
518 layout.numColumns = 3;
519 layout.makeColumnsEqualWidth = false;
520 composite.setLayout(layout);
521 composite.setFont(parent.getFont());
522 GridData buttonData = new GridData(SWT.FILL, SWT.FILL, true, false);
523 composite.setLayoutData(buttonData);
524
525 // Trace type label ("Trace Type:")
526 Label typeLabel = new Label(composite, SWT.NONE);
527 typeLabel.setText(Messages.ImportTraceWizard_TraceType);
528 typeLabel.setFont(parent.getFont());
529
530 // Trace type combo
252c602c 531 fTraceTypes = new Combo(composite, SWT.BORDER | SWT.READ_ONLY);
002f9f07
BH
532 GridData data = new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1);
533 fTraceTypes.setLayoutData(data);
534 fTraceTypes.setFont(parent.getFont());
535
536 String[] availableTraceTypes = TmfTraceType.getInstance().getAvailableTraceTypes();
252c602c
BH
537 String[] traceTypeList = new String[availableTraceTypes.length + 1];
538 traceTypeList[0] = AUTO_DETECT;
539 for (int i = 0; i < availableTraceTypes.length; i++) {
540 traceTypeList[i + 1] = availableTraceTypes[i];
541 }
542 fTraceTypes.setItems(traceTypeList);
e2a50e26 543 fTraceTypes.addSelectionListener(new SelectionAdapter() {
002f9f07
BH
544 @Override
545 public void widgetSelected(SelectionEvent e) {
546 updateWidgetEnablements();
e2a50e26
BH
547 boolean enabled = fTraceTypes.getText().equals(AUTO_DETECT);
548 fImportUnrecognizedButton.setEnabled(enabled);
002f9f07
BH
549 }
550 });
252c602c
BH
551 fTraceTypes.select(0);
552
16f91bd5 553 // Unrecognized checkbox
252c602c
BH
554 fImportUnrecognizedButton = new Button(composite, SWT.CHECK);
555 fImportUnrecognizedButton.setSelection(true);
556 fImportUnrecognizedButton.setText(Messages.ImportTraceWizard_ImportUnrecognized);
557
558 IDialogSettings settings = getDialogSettings();
559 boolean value;
560 if (settings.get(IMPORT_WIZARD_IMPORT_UNRECOGNIZED_ID) == null) {
561 value = true;
562 } else {
563 value = settings.getBoolean(IMPORT_WIZARD_IMPORT_UNRECOGNIZED_ID);
564 }
565 fImportUnrecognizedButton.setSelection(value);
002f9f07
BH
566 }
567
568 // ------------------------------------------------------------------------
569 // Options
570 // ------------------------------------------------------------------------
571
002f9f07
BH
572 @Override
573 protected void createOptionsGroupButtons(Group optionsGroup) {
574
575 // Overwrite checkbox
252c602c
BH
576 fOverwriteExistingResourcesCheckbox = new Button(optionsGroup, SWT.CHECK);
577 fOverwriteExistingResourcesCheckbox.setFont(optionsGroup.getFont());
578 fOverwriteExistingResourcesCheckbox.setText(Messages.ImportTraceWizard_OverwriteExistingTrace);
579 fOverwriteExistingResourcesCheckbox.setSelection(false);
002f9f07
BH
580
581 // Create links checkbox
252c602c
BH
582 fCreateLinksInWorkspaceButton = new Button(optionsGroup, SWT.CHECK);
583 fCreateLinksInWorkspaceButton.setFont(optionsGroup.getFont());
584 fCreateLinksInWorkspaceButton.setText(Messages.ImportTraceWizard_CreateLinksInWorkspace);
585 fCreateLinksInWorkspaceButton.setSelection(true);
002f9f07 586
252c602c 587 fCreateLinksInWorkspaceButton.addSelectionListener(new SelectionAdapter() {
002f9f07
BH
588 @Override
589 public void widgetSelected(SelectionEvent e) {
590 updateWidgetEnablements();
591 }
592 });
593
594 updateWidgetEnablements();
595 }
596
597 // ------------------------------------------------------------------------
598 // Determine if the finish button can be enabled
599 // ------------------------------------------------------------------------
600
601 @Override
602 public boolean validateSourceGroup() {
603
604 File sourceDirectory = getSourceDirectory();
605 if (sourceDirectory == null) {
606 setMessage(Messages.ImportTraceWizard_SelectTraceSourceEmpty);
607 return false;
608 }
609
610 if (sourceConflictsWithDestination(new Path(sourceDirectory.getPath()))) {
611 setMessage(null);
612 setErrorMessage(getSourceConflictMessage());
613 return false;
614 }
615
616 List<FileSystemElement> resourcesToImport = getSelectedResources();
617 if (resourcesToImport.size() == 0) {
618 setMessage(null);
619 setErrorMessage(Messages.ImportTraceWizard_SelectTraceNoneSelected);
620 return false;
621 }
622
623 IContainer container = getSpecifiedContainer();
624 if (container != null && container.isVirtual()) {
625 if (Platform.getPreferencesService().getBoolean(Activator.PLUGIN_ID, ResourcesPlugin.PREF_DISABLE_LINKING, false, null)) {
626 setMessage(null);
627 setErrorMessage(Messages.ImportTraceWizard_CannotImportFilesUnderAVirtualFolder);
628 return false;
629 }
252c602c 630 if (fCreateLinksInWorkspaceButton == null || !fCreateLinksInWorkspaceButton.getSelection()) {
002f9f07
BH
631 setMessage(null);
632 setErrorMessage(Messages.ImportTraceWizard_HaveToCreateLinksUnderAVirtualFolder);
633 return false;
634 }
635 }
636
002f9f07
BH
637 setErrorMessage(null);
638 return true;
639 }
640
641 // ------------------------------------------------------------------------
642 // Import the trace(s)
643 // ------------------------------------------------------------------------
644
645 /**
646 * Finish the import.
647 *
252c602c 648 * @return <code>true</code> if successful else <code>false</code>
002f9f07
BH
649 */
650 public boolean finish() {
252c602c
BH
651 IDialogSettings settings = getDialogSettings();
652 settings.put(IMPORT_WIZARD_IMPORT_UNRECOGNIZED_ID, fImportUnrecognizedButton.getSelection());
002f9f07 653
252c602c
BH
654 String traceTypeName = fTraceTypes.getText();
655 String traceId = null;
656 if (!AUTO_DETECT.equals(traceTypeName)) {
657 String tokens[] = traceTypeName.split(SEPARATOR, 2);
658 if (tokens.length < 2) {
659 return false;
660 }
661 traceId = TmfTraceType.getInstance().getTraceTypeId(tokens[0], tokens[1]);
002f9f07
BH
662 }
663
664 // Save directory for next import operation
665 fRootDirectory = getSourceDirectoryName();
666
252c602c
BH
667 final TraceValidateAndImportOperation operation = new TraceValidateAndImportOperation(traceId, getContainerFullPath(),
668 fImportUnrecognizedButton.getSelection(), fOverwriteExistingResourcesCheckbox.getSelection(), fCreateLinksInWorkspaceButton.getSelection());
002f9f07 669
252c602c
BH
670 IStatus status = Status.OK_STATUS;
671 try {
672 getContainer().run(true, true, new IRunnableWithProgress() {
673 @Override
674 public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
675 operation.run(monitor);
676 monitor.done();
002f9f07 677 }
252c602c 678 });
002f9f07 679
252c602c
BH
680 status = operation.getStatus();
681 } catch (InvocationTargetException e) {
682 status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.ImportTraceWizard_ImportProblem, e);
683 } catch (InterruptedException e) {
684 status = Status.CANCEL_STATUS;
685 } finally {
686 if (!status.isOK()) {
687 if (status.getSeverity() == IStatus.CANCEL) {
688 setMessage(Messages.ImportTraceWizard_ImportOperationCancelled);
689 setErrorMessage(null);
002f9f07 690 } else {
252c602c
BH
691 if (status.getException() != null) {
692 displayErrorDialog(status.getMessage() + ": " + status.getException()); //$NON-NLS-1$
693 }
002f9f07 694 setMessage(null);
252c602c 695 setErrorMessage(Messages.ImportTraceWizard_ImportProblem);
002f9f07 696 }
252c602c
BH
697 return false;
698 }
699 }
252c602c
BH
700 setErrorMessage(null);
701 return true;
702 }
002f9f07 703
252c602c
BH
704
705 // ------------------------------------------------------------------------
706 // Classes
707 // ------------------------------------------------------------------------
708
16f91bd5 709 private class TraceValidateAndImportOperation {
252c602c 710 private IStatus fStatus;
252c602c
BH
711 private String fTraceType;
712 private IPath fContainerPath;
713 private boolean fImportUnrecognizedTraces;
252c602c 714 private boolean fLink;
16f91bd5 715 private ImportConfirmation fConfirmationMode = ImportConfirmation.SKIP;
252c602c 716
16f91bd5 717 private TraceValidateAndImportOperation(String traceId, IPath containerPath, boolean doImport, boolean overwrite, boolean link) {
252c602c
BH
718 fTraceType = traceId;
719 fContainerPath = containerPath;
720 fImportUnrecognizedTraces = doImport;
16f91bd5
BH
721 if (overwrite) {
722 fConfirmationMode = ImportConfirmation.OVERWRITE_ALL;
723 }
252c602c
BH
724 fLink = link;
725 }
726
727 public void run(IProgressMonitor progressMonitor) {
728 String currentPath = null;
16f91bd5 729 final Map<String, TraceFileSystemElement> folderElements = new HashMap<>();
252c602c 730 try {
16f91bd5
BH
731 List<TraceFileSystemElement> fileSystemElements = getSelectedResources();
732 Iterator<TraceFileSystemElement> fileSystemElementsIter = fileSystemElements.iterator();
733 SubMonitor subMonitor = SubMonitor.convert(progressMonitor, fileSystemElements.size());
252c602c 734
16f91bd5 735 while (fileSystemElementsIter.hasNext()) {
252c602c
BH
736 ModalContext.checkCanceled(progressMonitor);
737 currentPath = null;
16f91bd5
BH
738 TraceFileSystemElement element = fileSystemElementsIter.next();
739 File fileResource = (File) element.getFileSystemObject();
740 String resourcePath = fileResource.getAbsolutePath();
252c602c
BH
741 currentPath = resourcePath;
742 SubMonitor sub = subMonitor.newChild(1);
16f91bd5
BH
743 if (element.isDirectory()) {
744 if (!folderElements.containsKey(resourcePath)) {
745 if (isDirectoryTrace(element)) {
746 folderElements.put(resourcePath, element);
c659283d 747 validateAndImportTrace(element, sub);
252c602c
BH
748 }
749 }
750 } else {
16f91bd5
BH
751 TraceFileSystemElement parentElement = (TraceFileSystemElement)element.getParent();
752 File parentFile = (File) parentElement.getFileSystemObject();
753 String parentPath = parentFile.getAbsolutePath();
252c602c 754 currentPath = parentPath;
16f91bd5
BH
755 if (!folderElements.containsKey(parentPath)) {
756 if (isDirectoryTrace(parentElement)) {
757 folderElements.put(parentPath, parentElement);
c659283d 758 validateAndImportTrace(parentElement, sub);
252c602c 759 } else {
16f91bd5 760 if (fileResource.exists()) {
c659283d 761 validateAndImportTrace(element, sub);
002f9f07 762 }
002f9f07
BH
763 }
764 }
765 }
766 }
252c602c
BH
767 setStatus(Status.OK_STATUS);
768 } catch (InterruptedException e) {
769 setStatus(Status.CANCEL_STATUS);
770 } catch (Exception e) {
771 setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.ImportTraceWizard_ImportProblem + ": " + //$NON-NLS-1$
772 (currentPath != null ? currentPath : "") , e)); //$NON-NLS-1$
002f9f07 773 }
002f9f07
BH
774 }
775
c659283d 776 private void validateAndImportTrace(TraceFileSystemElement fileSystemElement, IProgressMonitor monitor)
252c602c 777 throws TmfTraceImportException, CoreException, InvocationTargetException, InterruptedException {
16f91bd5 778 File file = (File) fileSystemElement.getFileSystemObject();
252c602c 779 String path = file.getAbsolutePath();
350cae41 780 TraceTypeHelper traceTypeHelper = null;
c659283d 781
252c602c 782 if (fTraceType == null) {
c659283d 783 // Auto Detection
350cae41
PT
784 try {
785 traceTypeHelper = TmfTraceTypeUIUtils.selectTraceType(path, null, null);
786 } catch (TmfTraceImportException e) {
787 // the trace did not match any trace type
788 }
789 if (traceTypeHelper == null) {
790 if (fImportUnrecognizedTraces) {
98bb2f6a 791 importResource(fileSystemElement, monitor);
350cae41
PT
792 }
793 return;
794 }
252c602c 795 } else {
c659283d
BH
796 boolean isDirectoryTraceType = TmfTraceType.getInstance().isDirectoryTraceType(fTraceType);
797 if (fileSystemElement.isDirectory() != isDirectoryTraceType) {
252c602c
BH
798 return;
799 }
252c602c 800 traceTypeHelper = TmfTraceType.getInstance().getTraceType(fTraceType);
16f91bd5 801
350cae41 802 if (traceTypeHelper == null) {
c659283d
BH
803 // Trace type not found
804 throw new TmfTraceImportException(Messages.ImportTraceWizard_TraceTypeNotFound);
252c602c 805 }
c659283d
BH
806
807 if (!traceTypeHelper.validate(path)) {
808 // Trace type exist but doesn't validate for given trace.
350cae41
PT
809 return;
810 }
252c602c 811 }
002f9f07 812
c659283d
BH
813 // Finally import trace
814 if (importResource(fileSystemElement, monitor)) {
815 IResource eclipseResource = fTargetFolder.findMember(fileSystemElement.getLabel());
816 TmfTraceTypeUIUtils.setTraceType(eclipseResource.getFullPath(), traceTypeHelper);
002f9f07 817 }
002f9f07 818
252c602c 819 }
002f9f07 820
16f91bd5
BH
821 /**
822 * Imports a trace resource to project. In case of name collision the
823 * user will be asked to confirm overwriting the existing trace,
824 * overwriting or skipping the trace to be imported.
825 *
826 * @param fileSystemElement
827 * trace file system object to import
828 * @param monitor
829 * a progress monitor
830 * @return true if trace was imported else false
831 *
832 * @throws InvocationTargetException
833 * if problems during import operation
834 * @throws InterruptedException
835 * if cancelled
836 * @throws CoreException
837 * if problems with workspace
838 */
839 private boolean importResource(TraceFileSystemElement fileSystemElement, IProgressMonitor monitor)
840 throws InvocationTargetException, InterruptedException, CoreException {
841 ImportConfirmation mode = checkForNameClashes(fileSystemElement);
842 switch (mode) {
843 case RENAME:
844 case RENAME_ALL:
845 rename(fileSystemElement);
846 break;
847 case OVERWRITE:
848 case OVERWRITE_ALL:
849 delete(fileSystemElement, monitor);
850 break;
851 case CONTINUE:
852 break;
853 case SKIP:
854 case SKIP_ALL:
855 default:
856 return false;
857 }
858
859 List<TraceFileSystemElement> subList = new ArrayList<>();
860
861 IPath containerPath = fContainerPath;
862 FileSystemElement parentFolder = fileSystemElement.getParent();
863
864 if (fileSystemElement.isDirectory() && (!fLink)) {
865 containerPath = containerPath.addTrailingSeparator().append(fileSystemElement.getLabel());
866
867 Object[] array = fileSystemElement.getFiles().getChildren();
868 for (int i = 0; i < array.length; i++) {
869 subList.add((TraceFileSystemElement)array[i]);
870 }
871 parentFolder = fileSystemElement;
872
873 } else {
874 subList.add(fileSystemElement);
875 }
876
877
878 ImportProvider fileSystemStructureProvider = new ImportProvider();
252c602c 879
252c602c
BH
880 IOverwriteQuery myQueryImpl = new IOverwriteQuery() {
881 @Override
882 public String queryOverwrite(String file) {
16f91bd5 883 return IOverwriteQuery.NO_ALL;
252c602c
BH
884 }
885 };
886
16f91bd5
BH
887 monitor.setTaskName(Messages.ImportTraceWizard_ImportOperationTaskName + " " + ((File)fileSystemElement.getFileSystemObject()).getAbsolutePath()); //$NON-NLS-1$
888 ImportOperation operation = new ImportOperation(containerPath, parentFolder, fileSystemStructureProvider, myQueryImpl, subList);
002f9f07 889 operation.setContext(getShell());
002f9f07 890
252c602c 891 operation.setCreateContainerStructure(false);
16f91bd5 892 operation.setOverwriteResources(false);
252c602c
BH
893 operation.setCreateLinks(fLink);
894 operation.setVirtualFolders(false);
002f9f07 895
252c602c 896 operation.run(new SubProgressMonitor(monitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK));
16f91bd5
BH
897 return true;
898 }
002f9f07 899
16f91bd5
BH
900 private boolean isDirectoryTrace(FileSystemElement fileSystemElement) {
901 File file = (File) fileSystemElement.getFileSystemObject();
252c602c
BH
902 String path = file.getAbsolutePath();
903 if (TmfTraceType.getInstance().isDirectoryTrace(path)) {
904 return true;
905 }
002f9f07
BH
906 return false;
907 }
908
16f91bd5
BH
909 private ImportConfirmation checkForNameClashes(TraceFileSystemElement fileSystemElement) throws InterruptedException {
910
911 String traceName = ((File)fileSystemElement.getFileSystemObject()).getName();
912
913 // handle rename
914 if (getExistingTrace(traceName) != null) {
915 if ((fConfirmationMode == ImportConfirmation.RENAME_ALL) ||
916 (fConfirmationMode == ImportConfirmation.OVERWRITE_ALL) ||
917 (fConfirmationMode == ImportConfirmation.SKIP_ALL)) {
918 return fConfirmationMode;
919 }
920
921 int returnCode = promptForOverwrite(traceName);
922 if (returnCode < 0) {
923 // Cancel
924 throw new InterruptedException();
925 }
926 fConfirmationMode = ImportConfirmation.values()[returnCode];
927 return fConfirmationMode;
928 }
929 return ImportConfirmation.CONTINUE;
930 }
931
932 private int promptForOverwrite(String traceName) {
933 final MessageDialog dialog = new MessageDialog(getContainer()
934 .getShell(), null, null, NLS.bind(Messages.ImportTraceWizard_TraceAlreadyExists, traceName),
935 MessageDialog.QUESTION, new String[] {
936 ImportConfirmation.RENAME.getInName(),
937 ImportConfirmation.RENAME_ALL.getInName(),
938 ImportConfirmation.OVERWRITE.getInName(),
939 ImportConfirmation.OVERWRITE_ALL.getInName(),
940 ImportConfirmation.SKIP.getInName(),
941 ImportConfirmation.SKIP_ALL.getInName(),
942 }, 4) {
943 @Override
944 protected int getShellStyle() {
945 return super.getShellStyle() | SWT.SHEET;
946 }
947 };
948
949 final int[] returnValue = new int[1];
950 getShell().getDisplay().syncExec(new Runnable() {
951
952 @Override
953 public void run() {
954 returnValue[0] = dialog.open();
955 }
956 });
957 return returnValue[0];
958 }
959
960 private void rename(TraceFileSystemElement fileSystemElement) {
961 String traceName = ((File)fileSystemElement.getFileSystemObject()).getName();
962 TmfTraceElement trace = getExistingTrace(traceName);
963 if (trace == null) {
964 return;
965 }
966
967 IFolder folder = trace.getProject().getTracesFolder().getResource();
968 int i = 2;
969 while (true) {
970 String name = trace.getName() + '(' + Integer.toString(i++) + ')';
971 IResource resource = folder.findMember(name);
972 if (resource == null) {
973 fileSystemElement.setLabel(name);
974 return;
975 }
976 }
977 }
978
979 private void delete(TraceFileSystemElement fileSystemElement, IProgressMonitor monitor) throws CoreException {
980 String traceName = ((File)fileSystemElement.getFileSystemObject()).getName();
981 TmfTraceElement trace = getExistingTrace(traceName);
982 if (trace == null) {
983 return;
984 }
985
986 trace.delete(monitor);
987 }
988
989 private TmfTraceElement getExistingTrace(String traceName) {
990 List<TmfTraceElement> traces = fTraceFolderElement.getTraces();
991 for (TmfTraceElement t : traces) {
992 if (t.getName().equals(traceName)) {
993 return t;
994 }
995 }
996 return null;
997 }
998
252c602c
BH
999 /**
1000 * Set the status for this operation
1001 *
1002 * @param status
1003 * the status
1004 */
1005 protected void setStatus(IStatus status) {
1006 fStatus = status;
002f9f07
BH
1007 }
1008
252c602c
BH
1009 public IStatus getStatus() {
1010 return fStatus;
1011 }
002f9f07
BH
1012 }
1013
252c602c
BH
1014 /**
1015 * The <code>TraceFileSystemElement</code> is a <code>FileSystemElement</code> that knows
1016 * if it has been populated or not.
1017 */
16f91bd5 1018 private static class TraceFileSystemElement extends FileSystemElement {
252c602c 1019
16f91bd5
BH
1020 private boolean fIsPopulated = false;
1021 private String fLabel = null;
252c602c
BH
1022
1023 public TraceFileSystemElement(String name, FileSystemElement parent, boolean isDirectory) {
1024 super(name, parent, isDirectory);
1025 }
1026
1027 public void setPopulated() {
16f91bd5 1028 fIsPopulated = true;
252c602c
BH
1029 }
1030
1031 public boolean isPopulated() {
16f91bd5 1032 return fIsPopulated;
252c602c
BH
1033 }
1034
1035 @Override
1036 public AdaptableList getFiles() {
16f91bd5 1037 if(!fIsPopulated) {
252c602c
BH
1038 populateElementChildren();
1039 }
1040 return super.getFiles();
1041 }
1042
1043 @Override
1044 public AdaptableList getFolders() {
16f91bd5 1045 if(!fIsPopulated) {
252c602c
BH
1046 populateElementChildren();
1047 }
1048 return super.getFolders();
1049 }
002f9f07 1050
16f91bd5
BH
1051 /**
1052 * Sets the label for the trace to be used when importing at trace.
1053 * @param name
1054 * the label for the trace
1055 */
1056 public void setLabel(String name) {
1057 fLabel = name;
1058 }
1059
1060 /**
1061 * Returns the label for the trace to be used when importing at trace.
1062 *
1063 * @return the label of trace resource
1064 */
1065 public String getLabel() {
1066 if (fLabel == null) {
1067 //Get the name - if it is empty then return the path as it is a file root
1068 File file = (File) getFileSystemObject();
1069 String name = file.getName();
1070 if (name.length() == 0) {
1071 return file.getPath();
1072 }
1073 return name;
1074 }
1075 return fLabel;
1076 }
1077
252c602c
BH
1078 /**
1079 * Populates the children of the specified parent <code>FileSystemElement</code>
1080 */
1081 private void populateElementChildren() {
1082 FileSystemStructureProvider provider = FileSystemStructureProvider.INSTANCE;
1083 List<File> allchildren = provider.getChildren(this.getFileSystemObject());
1084 File child = null;
1085 TraceFileSystemElement newelement = null;
1086 Iterator<File> iter = allchildren.iterator();
1087 while(iter.hasNext()) {
1088 child = iter.next();
1089 newelement = new TraceFileSystemElement(provider.getLabel(child), this, provider.isFolder(child));
1090 newelement.setFileSystemObject(child);
1091 }
1092 setPopulated();
1093 }
1094 }
16f91bd5
BH
1095
1096 private class ImportProvider implements IImportStructureProvider {
1097
1098 private FileSystemStructureProvider provider = FileSystemStructureProvider.INSTANCE;
1099
1100 ImportProvider() {
1101 }
1102
1103 @Override
1104 public String getLabel(Object element) {
1105 TraceFileSystemElement resource = (TraceFileSystemElement)element;
1106 return resource.getLabel();
1107 }
1108
1109 @Override
1110 public List getChildren(Object element) {
1111 TraceFileSystemElement resource = (TraceFileSystemElement)element;
1112 Object[] array = resource.getFiles().getChildren();
1113 List<Object> list = new ArrayList<>();
1114 for (int i = 0; i < array.length; i++) {
1115 list.add(array[i]);
1116 }
1117 return list;
1118 }
1119
1120 @Override
1121 public InputStream getContents(Object element) {
1122 TraceFileSystemElement resource = (TraceFileSystemElement)element;
1123 return provider.getContents(resource.getFileSystemObject());
1124 }
1125
1126 @Override
1127 public String getFullPath(Object element) {
1128 TraceFileSystemElement resource = (TraceFileSystemElement)element;
1129 return provider.getFullPath(resource.getFileSystemObject());
1130 }
1131
1132 @Override
1133 public boolean isFolder(Object element) {
1134 TraceFileSystemElement resource = (TraceFileSystemElement)element;
1135 return resource.isDirectory();
1136 }
1137 }
1138
1139 private enum ImportConfirmation {
1140 // ------------------------------------------------------------------------
1141 // Enum definition
1142 // ------------------------------------------------------------------------
1143 RENAME(Messages.ImportTraceWizard_ImportConfigurationRename),
1144 RENAME_ALL(Messages.ImportTraceWizard_ImportConfigurationRenameAll),
1145 OVERWRITE(Messages.ImportTraceWizard_ImportConfigurationOverwrite),
1146 OVERWRITE_ALL(Messages.ImportTraceWizard_ImportConfigurationOverwriteAll),
1147 SKIP(Messages.ImportTraceWizard_ImportConfigurationSkip),
1148 SKIP_ALL(Messages.ImportTraceWizard_ImportConfigurationSkipAll),
1149 CONTINUE("CONTINUE"); //$NON-NLS-1$
1150
1151 // ------------------------------------------------------------------------
1152 // Attributes
1153 // ------------------------------------------------------------------------
1154 /**
1155 * Name of enum
1156 */
1157 private final String fInName;
1158
1159 // ------------------------------------------------------------------------
1160 // Constuctors
1161 // ------------------------------------------------------------------------
1162
1163 /**
1164 * Private constructor
1165 * @param name the name of state
1166 */
1167 private ImportConfirmation(String name) {
1168 fInName = name;
1169 }
1170
1171 // ------------------------------------------------------------------------
1172 // Accessors
1173 // ------------------------------------------------------------------------
1174 /**
1175 * @return state name
1176 */
1177 public String getInName() {
1178 return fInName;
1179 }
1180 }
002f9f07 1181}
This page took 0.07716 seconds and 5 git commands to generate.