1 /*******************************************************************************
2 * Copyright (c) 2009, 2014 Ericsson and others.
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
10 * Francois Chouinard - Initial API and implementation
11 * Francois Chouinard - Got rid of dependency on internal platform class
12 * Francois Chouinard - Complete re-design
13 * Anna Dushistova(Montavista) - [383047] NPE while importing a CFT trace
14 * Matthew Khouzam - Moved out some common functions
15 * Patrick Tasse - Add sorting of file system elements
16 * Bernd Hufmann - Re-design of trace selection and trace validation
17 *******************************************************************************/
19 package org
.eclipse
.linuxtools
.tmf
.ui
.project
.wizards
.importtrace
;
22 import java
.io
.InputStream
;
23 import java
.lang
.reflect
.InvocationTargetException
;
24 import java
.util
.ArrayList
;
25 import java
.util
.HashMap
;
26 import java
.util
.Iterator
;
27 import java
.util
.List
;
30 import org
.eclipse
.core
.resources
.IContainer
;
31 import org
.eclipse
.core
.resources
.IFolder
;
32 import org
.eclipse
.core
.resources
.IProject
;
33 import org
.eclipse
.core
.resources
.IResource
;
34 import org
.eclipse
.core
.resources
.ResourcesPlugin
;
35 import org
.eclipse
.core
.runtime
.CoreException
;
36 import org
.eclipse
.core
.runtime
.IPath
;
37 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
38 import org
.eclipse
.core
.runtime
.IStatus
;
39 import org
.eclipse
.core
.runtime
.NullProgressMonitor
;
40 import org
.eclipse
.core
.runtime
.Path
;
41 import org
.eclipse
.core
.runtime
.Platform
;
42 import org
.eclipse
.core
.runtime
.Status
;
43 import org
.eclipse
.core
.runtime
.SubMonitor
;
44 import org
.eclipse
.core
.runtime
.SubProgressMonitor
;
45 import org
.eclipse
.jface
.dialogs
.IDialogSettings
;
46 import org
.eclipse
.jface
.dialogs
.MessageDialog
;
47 import org
.eclipse
.jface
.operation
.IRunnableWithProgress
;
48 import org
.eclipse
.jface
.operation
.ModalContext
;
49 import org
.eclipse
.jface
.viewers
.IStructuredSelection
;
50 import org
.eclipse
.jface
.viewers
.ITreeContentProvider
;
51 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.Activator
;
52 import org
.eclipse
.linuxtools
.tmf
.core
.TmfCommonConstants
;
53 import org
.eclipse
.linuxtools
.tmf
.core
.TmfProjectNature
;
54 import org
.eclipse
.linuxtools
.tmf
.core
.project
.model
.TmfTraceImportException
;
55 import org
.eclipse
.linuxtools
.tmf
.core
.project
.model
.TmfTraceType
;
56 import org
.eclipse
.linuxtools
.tmf
.core
.project
.model
.TraceTypeHelper
;
57 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
.TmfProjectRegistry
;
58 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
.TmfTraceElement
;
59 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
.TmfTraceFolder
;
60 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
.TmfTraceTypeUIUtils
;
61 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.wizards
.Messages
;
62 import org
.eclipse
.osgi
.util
.NLS
;
63 import org
.eclipse
.swt
.SWT
;
64 import org
.eclipse
.swt
.custom
.BusyIndicator
;
65 import org
.eclipse
.swt
.events
.FocusEvent
;
66 import org
.eclipse
.swt
.events
.FocusListener
;
67 import org
.eclipse
.swt
.events
.KeyEvent
;
68 import org
.eclipse
.swt
.events
.KeyListener
;
69 import org
.eclipse
.swt
.events
.SelectionAdapter
;
70 import org
.eclipse
.swt
.events
.SelectionEvent
;
71 import org
.eclipse
.swt
.events
.SelectionListener
;
72 import org
.eclipse
.swt
.layout
.GridData
;
73 import org
.eclipse
.swt
.layout
.GridLayout
;
74 import org
.eclipse
.swt
.widgets
.Button
;
75 import org
.eclipse
.swt
.widgets
.Combo
;
76 import org
.eclipse
.swt
.widgets
.Composite
;
77 import org
.eclipse
.swt
.widgets
.DirectoryDialog
;
78 import org
.eclipse
.swt
.widgets
.Event
;
79 import org
.eclipse
.swt
.widgets
.Group
;
80 import org
.eclipse
.swt
.widgets
.Label
;
81 import org
.eclipse
.ui
.IWorkbench
;
82 import org
.eclipse
.ui
.dialogs
.FileSystemElement
;
83 import org
.eclipse
.ui
.dialogs
.IOverwriteQuery
;
84 import org
.eclipse
.ui
.dialogs
.WizardResourceImportPage
;
85 import org
.eclipse
.ui
.model
.AdaptableList
;
86 import org
.eclipse
.ui
.model
.WorkbenchContentProvider
;
87 import org
.eclipse
.ui
.wizards
.datatransfer
.FileSystemStructureProvider
;
88 import org
.eclipse
.ui
.wizards
.datatransfer
.IImportStructureProvider
;
89 import org
.eclipse
.ui
.wizards
.datatransfer
.ImportOperation
;
92 * A variant of the standard resource import wizard for importing traces
93 * to given tracing project. If no project or tracing project was selected
94 * the wizard imports it to the default tracing project which is created
97 * In our case traces could be files or a directory structure. This wizard
98 * supports both cases. It imports traces for a selected trace type or, if
99 * no trace type is selected, it tries to detect the trace type automatically.
100 * However, the automatic detection is a best-effort and cannot guarantee
101 * that the detection is successful. The reason for this is that there might
102 * be multiple trace types that can be assigned to a single trace.
105 * @author Francois Chouinard
108 public class ImportTraceWizardPage
extends WizardResourceImportPage
{
110 // ------------------------------------------------------------------------
112 // ------------------------------------------------------------------------
113 private static final String IMPORT_WIZARD_PAGE
= "ImportTraceWizardPage"; //$NON-NLS-1$
114 private static final String IMPORT_WIZARD_IMPORT_UNRECOGNIZED_ID
= IMPORT_WIZARD_PAGE
+ ".import_unrecognized_traces_id"; //$NON-NLS-1$
115 private static final String SEPARATOR
= ":"; //$NON-NLS-1$
116 private static final String AUTO_DETECT
= Messages
.ImportTraceWizard_AutoDetection
;
118 // ------------------------------------------------------------------------
120 // ------------------------------------------------------------------------
122 // Folder navigation start point (saved between invocations)
123 private static String fRootDirectory
= null;
124 // Target import directory ('Traces' folder)
125 private IFolder fTargetFolder
;
126 // Target Trace folder element
127 private TmfTraceFolder fTraceFolderElement
;
128 // Flag to handle destination folder change event
129 private Boolean fIsDestinationChanged
= false;
130 // Combo box containing trace types
131 private Combo fTraceTypes
;
132 // Button to ignore unrecognized traces or not
133 private Button fImportUnrecognizedButton
;
134 // Button to overwrite existing resources or not
135 private Button fOverwriteExistingResourcesCheckbox
;
136 // Button to link or copy traces to workspace
137 private Button fCreateLinksInWorkspaceButton
;
138 private boolean entryChanged
= false;
139 /** The directory name field */
140 protected Combo directoryNameField
;
141 /** The directory browse button. */
142 protected Button directoryBrowseButton
;
144 // ------------------------------------------------------------------------
146 // ------------------------------------------------------------------------
149 * Constructor. Creates the trace wizard page.
152 * The name of the page.
154 * The current selection
156 protected ImportTraceWizardPage(String name
, IStructuredSelection selection
) {
157 super(name
, selection
);
164 * The workbench reference.
166 * The current selection
168 public ImportTraceWizardPage(IWorkbench workbench
, IStructuredSelection selection
) {
169 this(IMPORT_WIZARD_PAGE
, selection
);
170 setTitle(Messages
.ImportTraceWizard_FileSystemTitle
);
171 setDescription(Messages
.ImportTraceWizard_ImportTrace
);
173 // Locate the target trace folder
174 IFolder traceFolder
= null;
175 Object element
= selection
.getFirstElement();
177 if (element
instanceof TmfTraceFolder
) {
178 fTraceFolderElement
= (TmfTraceFolder
) element
;
179 fTraceFolderElement
.getProject().getResource();
180 traceFolder
= fTraceFolderElement
.getResource();
181 } else if (element
instanceof IProject
) {
182 IProject project
= (IProject
) element
;
184 if (project
.hasNature(TmfProjectNature
.ID
)) {
185 traceFolder
= project
.getFolder(TmfTraceFolder
.TRACE_FOLDER_NAME
);
186 fTraceFolderElement
= TmfProjectRegistry
.getProject(project
).getTracesFolder();
188 } catch (CoreException e
) {
193 * If no tracing project was selected or trace folder doesn't exist use
195 if (traceFolder
== null) {
196 IProject project
= TmfProjectRegistry
.createProject(
197 TmfCommonConstants
.DEFAULT_TRACE_PROJECT_NAME
, null, new NullProgressMonitor());
198 traceFolder
= project
.getFolder(TmfTraceFolder
.TRACE_FOLDER_NAME
);
199 fTraceFolderElement
= TmfProjectRegistry
.getProject(project
).getTracesFolder();
202 // Set the target trace folder
203 if (traceFolder
!= null) {
204 fTargetFolder
= traceFolder
;
205 String path
= traceFolder
.getFullPath().toOSString();
206 setContainerFieldValue(path
);
210 // ------------------------------------------------------------------------
211 // WizardResourceImportPage
212 // ------------------------------------------------------------------------
215 public void createControl(Composite parent
) {
216 super.createControl(parent
);
217 // Restore last directory if applicable
218 if (fRootDirectory
!= null) {
219 directoryNameField
.setText(fRootDirectory
);
220 updateFromSourceField();
225 protected void createSourceGroup(Composite parent
) {
226 createDirectorySelectionGroup(parent
);
227 createFileSelectionGroup(parent
);
228 createTraceTypeGroup(parent
);
229 validateSourceGroup();
233 protected ITreeContentProvider
getFileProvider() {
234 return new WorkbenchContentProvider() {
236 public Object
[] getChildren(Object object
) {
237 if (object
instanceof TraceFileSystemElement
) {
238 TraceFileSystemElement element
= (TraceFileSystemElement
) object
;
239 return element
.getFiles().getChildren(element
);
241 return new Object
[0];
247 protected ITreeContentProvider
getFolderProvider() {
248 return new WorkbenchContentProvider() {
250 public Object
[] getChildren(Object o
) {
251 if (o
instanceof TraceFileSystemElement
) {
252 TraceFileSystemElement element
= (TraceFileSystemElement
) o
;
253 return element
.getFolders().getChildren();
255 return new Object
[0];
259 public boolean hasChildren(Object o
) {
260 if (o
instanceof TraceFileSystemElement
) {
261 TraceFileSystemElement element
= (TraceFileSystemElement
) o
;
262 if (element
.isPopulated()) {
263 return getChildren(element
).length
> 0;
265 //If we have not populated then wait until asked
273 // ------------------------------------------------------------------------
274 // Directory Selection Group (forked WizardFileSystemResourceImportPage1)
275 // ------------------------------------------------------------------------
278 * creates the directory selection group.
281 * the parent composite
283 protected void createDirectorySelectionGroup(Composite parent
) {
285 Composite directoryContainerGroup
= new Composite(parent
, SWT
.NONE
);
286 GridLayout layout
= new GridLayout();
287 layout
.numColumns
= 3;
288 directoryContainerGroup
.setLayout(layout
);
289 directoryContainerGroup
.setFont(parent
.getFont());
290 directoryContainerGroup
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, false));
292 // Label ("Trace directory:")
293 Label groupLabel
= new Label(directoryContainerGroup
, SWT
.NONE
);
294 groupLabel
.setText(Messages
.ImportTraceWizard_DirectoryLocation
);
295 groupLabel
.setFont(parent
.getFont());
297 // Directory name entry field
298 directoryNameField
= new Combo(directoryContainerGroup
, SWT
.BORDER
);
299 GridData data
= new GridData(SWT
.FILL
, SWT
.FILL
, true, false);
300 data
.widthHint
= SIZING_TEXT_FIELD_WIDTH
;
301 directoryNameField
.setLayoutData(data
);
302 directoryNameField
.setFont(parent
.getFont());
304 directoryNameField
.addSelectionListener(new SelectionAdapter() {
306 public void widgetSelected(SelectionEvent e
) {
307 updateFromSourceField();
311 directoryNameField
.addKeyListener(new KeyListener() {
313 public void keyPressed(KeyEvent e
) {
314 // If there has been a key pressed then mark as dirty
316 if (e
.character
== SWT
.CR
) { // Windows...
317 entryChanged
= false;
318 updateFromSourceField();
323 public void keyReleased(KeyEvent e
) {
327 directoryNameField
.addFocusListener(new FocusListener() {
329 public void focusGained(FocusEvent e
) {
330 // Do nothing when getting focus
333 public void focusLost(FocusEvent e
) {
334 // Clear the flag to prevent constant update
336 entryChanged
= false;
337 updateFromSourceField();
343 directoryBrowseButton
= new Button(directoryContainerGroup
, SWT
.PUSH
);
344 directoryBrowseButton
.setText(Messages
.ImportTraceWizard_BrowseButton
);
345 directoryBrowseButton
.addListener(SWT
.Selection
, this);
346 directoryBrowseButton
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, false, false));
347 directoryBrowseButton
.setFont(parent
.getFont());
348 setButtonLayoutData(directoryBrowseButton
);
351 // ------------------------------------------------------------------------
352 // Browse for the source directory
353 // ------------------------------------------------------------------------
356 public void handleEvent(Event event
) {
357 if (event
.widget
== directoryBrowseButton
) {
358 handleSourceDirectoryBrowseButtonPressed();
361 // Avoid overwriting destination path without repeatedly trigger
362 // call of handleEvent();
363 synchronized (fIsDestinationChanged
) {
364 if (fIsDestinationChanged
== false) {
365 event
.display
.asyncExec(new Runnable() {
368 synchronized (fIsDestinationChanged
) {
369 fIsDestinationChanged
= true;
370 String path
= fTargetFolder
.getFullPath().toOSString();
371 setContainerFieldValue(path
);
376 fIsDestinationChanged
= false;
379 super.handleEvent(event
);
383 protected void handleContainerBrowseButtonPressed() {
384 // Do nothing so that destination directory cannot be changed.
388 * Handle the button pressed event
390 protected void handleSourceDirectoryBrowseButtonPressed() {
391 String currentSource
= directoryNameField
.getText();
392 DirectoryDialog dialog
= new DirectoryDialog(directoryNameField
.getShell(), SWT
.SAVE
| SWT
.SHEET
);
393 dialog
.setText(Messages
.ImportTraceWizard_SelectTraceDirectoryTitle
);
394 dialog
.setMessage(Messages
.ImportTraceWizard_SelectTraceDirectoryMessage
);
395 dialog
.setFilterPath(getSourceDirectoryName(currentSource
));
397 String selectedDirectory
= dialog
.open();
398 if (selectedDirectory
!= null) {
399 // Just quit if the directory is not valid
400 if ((getSourceDirectory(selectedDirectory
) == null) || selectedDirectory
.equals(currentSource
)) {
403 // If it is valid then proceed to populate
404 setErrorMessage(null);
405 setSourceName(selectedDirectory
);
409 private File
getSourceDirectory() {
410 return getSourceDirectory(directoryNameField
.getText());
413 private static File
getSourceDirectory(String path
) {
414 File sourceDirectory
= new File(getSourceDirectoryName(path
));
415 if (!sourceDirectory
.exists() || !sourceDirectory
.isDirectory()) {
419 return sourceDirectory
;
422 private static String
getSourceDirectoryName(String sourceName
) {
423 IPath result
= new Path(sourceName
.trim());
424 if (result
.getDevice() != null && result
.segmentCount() == 0) {
425 result
= result
.addTrailingSeparator();
427 result
= result
.removeTrailingSeparator();
429 return result
.toOSString();
432 private String
getSourceDirectoryName() {
433 return getSourceDirectoryName(directoryNameField
.getText());
436 private void updateFromSourceField() {
437 setSourceName(directoryNameField
.getText());
438 updateWidgetEnablements();
441 private void setSourceName(String path
) {
442 if (path
.length() > 0) {
443 String
[] currentItems
= directoryNameField
.getItems();
444 int selectionIndex
= -1;
445 for (int i
= 0; i
< currentItems
.length
; i
++) {
446 if (currentItems
[i
].equals(path
)) {
450 if (selectionIndex
< 0) {
451 int oldLength
= currentItems
.length
;
452 String
[] newItems
= new String
[oldLength
+ 1];
453 System
.arraycopy(currentItems
, 0, newItems
, 0, oldLength
);
454 newItems
[oldLength
] = path
;
455 directoryNameField
.setItems(newItems
);
456 selectionIndex
= oldLength
;
458 directoryNameField
.select(selectionIndex
);
463 // ------------------------------------------------------------------------
464 // File Selection Group (forked WizardFileSystemResourceImportPage1)
465 // ------------------------------------------------------------------------
466 private void resetSelection() {
467 TraceFileSystemElement root
= getFileSystemTree();
468 selectionGroup
.setRoot(root
);
471 private TraceFileSystemElement
getFileSystemTree() {
472 File sourceDirectory
= getSourceDirectory();
473 if (sourceDirectory
== null) {
476 return selectFiles(sourceDirectory
, FileSystemStructureProvider
.INSTANCE
);
479 private TraceFileSystemElement
selectFiles(final Object rootFileSystemObject
,
480 final IImportStructureProvider structureProvider
) {
481 final TraceFileSystemElement
[] results
= new TraceFileSystemElement
[1];
482 BusyIndicator
.showWhile(getShell().getDisplay(), new Runnable() {
485 // Create the root element from the supplied file system object
486 results
[0] = createRootElement(rootFileSystemObject
, structureProvider
);
492 private static TraceFileSystemElement
createRootElement(Object fileSystemObject
,
493 IImportStructureProvider provider
) {
495 boolean isContainer
= provider
.isFolder(fileSystemObject
);
496 String elementLabel
= provider
.getLabel(fileSystemObject
);
498 // Use an empty label so that display of the element's full name
499 // doesn't include a confusing label
500 TraceFileSystemElement dummyParent
= new TraceFileSystemElement("", null, true);//$NON-NLS-1$
501 dummyParent
.setFileSystemObject(((File
)fileSystemObject
).getParentFile());
502 dummyParent
.setPopulated();
503 TraceFileSystemElement result
= new TraceFileSystemElement(
504 elementLabel
, dummyParent
, isContainer
);
505 result
.setFileSystemObject(fileSystemObject
);
507 //Get the files for the element so as to build the first level
513 // ------------------------------------------------------------------------
515 // ------------------------------------------------------------------------
516 private final void createTraceTypeGroup(Composite parent
) {
517 Composite composite
= new Composite(parent
, SWT
.NONE
);
518 GridLayout layout
= new GridLayout();
519 layout
.numColumns
= 3;
520 layout
.makeColumnsEqualWidth
= false;
521 composite
.setLayout(layout
);
522 composite
.setFont(parent
.getFont());
523 GridData buttonData
= new GridData(SWT
.FILL
, SWT
.FILL
, true, false);
524 composite
.setLayoutData(buttonData
);
526 // Trace type label ("Trace Type:")
527 Label typeLabel
= new Label(composite
, SWT
.NONE
);
528 typeLabel
.setText(Messages
.ImportTraceWizard_TraceType
);
529 typeLabel
.setFont(parent
.getFont());
532 fTraceTypes
= new Combo(composite
, SWT
.BORDER
| SWT
.READ_ONLY
);
533 GridData data
= new GridData(SWT
.FILL
, SWT
.FILL
, true, false, 2, 1);
534 fTraceTypes
.setLayoutData(data
);
535 fTraceTypes
.setFont(parent
.getFont());
537 String
[] availableTraceTypes
= TmfTraceType
.getInstance().getAvailableTraceTypes();
538 String
[] traceTypeList
= new String
[availableTraceTypes
.length
+ 1];
539 traceTypeList
[0] = AUTO_DETECT
;
540 for (int i
= 0; i
< availableTraceTypes
.length
; i
++) {
541 traceTypeList
[i
+ 1] = availableTraceTypes
[i
];
543 fTraceTypes
.setItems(traceTypeList
);
544 fTraceTypes
.addSelectionListener(new SelectionListener() {
546 public void widgetSelected(SelectionEvent e
) {
547 updateWidgetEnablements();
551 public void widgetDefaultSelected(SelectionEvent e
) {
554 fTraceTypes
.select(0);
556 // Unrecognized checkbox
557 fImportUnrecognizedButton
= new Button(composite
, SWT
.CHECK
);
558 fImportUnrecognizedButton
.setSelection(true);
559 fImportUnrecognizedButton
.setText(Messages
.ImportTraceWizard_ImportUnrecognized
);
561 IDialogSettings settings
= getDialogSettings();
563 if (settings
.get(IMPORT_WIZARD_IMPORT_UNRECOGNIZED_ID
) == null) {
566 value
= settings
.getBoolean(IMPORT_WIZARD_IMPORT_UNRECOGNIZED_ID
);
568 fImportUnrecognizedButton
.setSelection(value
);
571 // ------------------------------------------------------------------------
573 // ------------------------------------------------------------------------
576 protected void createOptionsGroupButtons(Group optionsGroup
) {
578 // Overwrite checkbox
579 fOverwriteExistingResourcesCheckbox
= new Button(optionsGroup
, SWT
.CHECK
);
580 fOverwriteExistingResourcesCheckbox
.setFont(optionsGroup
.getFont());
581 fOverwriteExistingResourcesCheckbox
.setText(Messages
.ImportTraceWizard_OverwriteExistingTrace
);
582 fOverwriteExistingResourcesCheckbox
.setSelection(false);
584 // Create links checkbox
585 fCreateLinksInWorkspaceButton
= new Button(optionsGroup
, SWT
.CHECK
);
586 fCreateLinksInWorkspaceButton
.setFont(optionsGroup
.getFont());
587 fCreateLinksInWorkspaceButton
.setText(Messages
.ImportTraceWizard_CreateLinksInWorkspace
);
588 fCreateLinksInWorkspaceButton
.setSelection(true);
590 fCreateLinksInWorkspaceButton
.addSelectionListener(new SelectionAdapter() {
592 public void widgetSelected(SelectionEvent e
) {
593 updateWidgetEnablements();
597 updateWidgetEnablements();
600 // ------------------------------------------------------------------------
601 // Determine if the finish button can be enabled
602 // ------------------------------------------------------------------------
605 public boolean validateSourceGroup() {
607 File sourceDirectory
= getSourceDirectory();
608 if (sourceDirectory
== null) {
609 setMessage(Messages
.ImportTraceWizard_SelectTraceSourceEmpty
);
613 if (sourceConflictsWithDestination(new Path(sourceDirectory
.getPath()))) {
615 setErrorMessage(getSourceConflictMessage());
619 List
<FileSystemElement
> resourcesToImport
= getSelectedResources();
620 if (resourcesToImport
.size() == 0) {
622 setErrorMessage(Messages
.ImportTraceWizard_SelectTraceNoneSelected
);
626 IContainer container
= getSpecifiedContainer();
627 if (container
!= null && container
.isVirtual()) {
628 if (Platform
.getPreferencesService().getBoolean(Activator
.PLUGIN_ID
, ResourcesPlugin
.PREF_DISABLE_LINKING
, false, null)) {
630 setErrorMessage(Messages
.ImportTraceWizard_CannotImportFilesUnderAVirtualFolder
);
633 if (fCreateLinksInWorkspaceButton
== null || !fCreateLinksInWorkspaceButton
.getSelection()) {
635 setErrorMessage(Messages
.ImportTraceWizard_HaveToCreateLinksUnderAVirtualFolder
);
640 setErrorMessage(null);
644 // ------------------------------------------------------------------------
645 // Import the trace(s)
646 // ------------------------------------------------------------------------
651 * @return <code>true</code> if successful else <code>false</code>
653 public boolean finish() {
654 IDialogSettings settings
= getDialogSettings();
655 settings
.put(IMPORT_WIZARD_IMPORT_UNRECOGNIZED_ID
, fImportUnrecognizedButton
.getSelection());
657 String traceTypeName
= fTraceTypes
.getText();
658 String traceId
= null;
659 if (!AUTO_DETECT
.equals(traceTypeName
)) {
660 String tokens
[] = traceTypeName
.split(SEPARATOR
, 2);
661 if (tokens
.length
< 2) {
664 traceId
= TmfTraceType
.getInstance().getTraceTypeId(tokens
[0], tokens
[1]);
667 // Save directory for next import operation
668 fRootDirectory
= getSourceDirectoryName();
670 final TraceValidateAndImportOperation operation
= new TraceValidateAndImportOperation(traceId
, getContainerFullPath(),
671 fImportUnrecognizedButton
.getSelection(), fOverwriteExistingResourcesCheckbox
.getSelection(), fCreateLinksInWorkspaceButton
.getSelection());
673 IStatus status
= Status
.OK_STATUS
;
675 getContainer().run(true, true, new IRunnableWithProgress() {
677 public void run(IProgressMonitor monitor
) throws InvocationTargetException
, InterruptedException
{
678 operation
.run(monitor
);
683 status
= operation
.getStatus();
684 } catch (InvocationTargetException e
) {
685 status
= new Status(IStatus
.ERROR
, Activator
.PLUGIN_ID
, Messages
.ImportTraceWizard_ImportProblem
, e
);
686 } catch (InterruptedException e
) {
687 status
= Status
.CANCEL_STATUS
;
689 if (!status
.isOK()) {
690 if (status
.getSeverity() == IStatus
.CANCEL
) {
691 setMessage(Messages
.ImportTraceWizard_ImportOperationCancelled
);
692 setErrorMessage(null);
694 if (status
.getException() != null) {
695 displayErrorDialog(status
.getMessage() + ": " + status
.getException()); //$NON-NLS-1$
698 setErrorMessage(Messages
.ImportTraceWizard_ImportProblem
);
703 setErrorMessage(null);
708 // ------------------------------------------------------------------------
710 // ------------------------------------------------------------------------
712 private class TraceValidateAndImportOperation
{
713 private IStatus fStatus
;
714 private String fTraceType
;
715 private IPath fContainerPath
;
716 private boolean fImportUnrecognizedTraces
;
717 private boolean fLink
;
718 private ImportConfirmation fConfirmationMode
= ImportConfirmation
.SKIP
;
720 private TraceValidateAndImportOperation(String traceId
, IPath containerPath
, boolean doImport
, boolean overwrite
, boolean link
) {
721 fTraceType
= traceId
;
722 fContainerPath
= containerPath
;
723 fImportUnrecognizedTraces
= doImport
;
725 fConfirmationMode
= ImportConfirmation
.OVERWRITE_ALL
;
730 public void run(IProgressMonitor progressMonitor
) {
731 String currentPath
= null;
732 final Map
<String
, TraceFileSystemElement
> folderElements
= new HashMap
<>();
734 List
<TraceFileSystemElement
> fileSystemElements
= getSelectedResources();
735 Iterator
<TraceFileSystemElement
> fileSystemElementsIter
= fileSystemElements
.iterator();
736 SubMonitor subMonitor
= SubMonitor
.convert(progressMonitor
, fileSystemElements
.size());
738 while (fileSystemElementsIter
.hasNext()) {
739 ModalContext
.checkCanceled(progressMonitor
);
741 TraceFileSystemElement element
= fileSystemElementsIter
.next();
742 File fileResource
= (File
) element
.getFileSystemObject();
743 String resourcePath
= fileResource
.getAbsolutePath();
744 currentPath
= resourcePath
;
745 SubMonitor sub
= subMonitor
.newChild(1);
746 if (element
.isDirectory()) {
747 if (!folderElements
.containsKey(resourcePath
)) {
748 if (isDirectoryTrace(element
)) {
749 folderElements
.put(resourcePath
, element
);
750 validateAndImportDirectoryTrace(element
, sub
);
754 TraceFileSystemElement parentElement
= (TraceFileSystemElement
)element
.getParent();
755 File parentFile
= (File
) parentElement
.getFileSystemObject();
756 String parentPath
= parentFile
.getAbsolutePath();
757 currentPath
= parentPath
;
758 if (!folderElements
.containsKey(parentPath
)) {
759 if (isDirectoryTrace(parentElement
)) {
760 folderElements
.put(parentPath
, parentElement
);
761 validateAndImportDirectoryTrace(parentElement
, sub
);
763 if (fileResource
.exists()) {
764 validateAndImportFileTrace(element
, sub
);
770 setStatus(Status
.OK_STATUS
);
771 } catch (InterruptedException e
) {
772 setStatus(Status
.CANCEL_STATUS
);
773 } catch (Exception e
) {
774 setStatus(new Status(IStatus
.ERROR
, Activator
.PLUGIN_ID
, Messages
.ImportTraceWizard_ImportProblem
+ ": " + //$NON-NLS-1$
775 (currentPath
!= null ? currentPath
: "") , e
)); //$NON-NLS-1$
779 private void validateAndImportDirectoryTrace(TraceFileSystemElement fileSystemElement
, IProgressMonitor monitor
)
780 throws TmfTraceImportException
, CoreException
, InvocationTargetException
, InterruptedException
{
781 File file
= (File
) fileSystemElement
.getFileSystemObject();
782 String path
= file
.getAbsolutePath();
783 TraceTypeHelper traceTypeHelper
= null;
784 boolean sendValidationError
= true;
785 if (fTraceType
== null) {
787 traceTypeHelper
= TmfTraceTypeUIUtils
.selectTraceType(path
, null, null);
788 } catch (TmfTraceImportException e
) {
789 // the trace did not match any trace type
791 if (traceTypeHelper
== null) {
792 if (fImportUnrecognizedTraces
) {
793 importResource(fileSystemElement
, monitor
);
798 if (!TmfTraceType
.getInstance().isDirectoryTraceType(fTraceType
)) {
801 sendValidationError
= false;
802 traceTypeHelper
= TmfTraceType
.getInstance().getTraceType(fTraceType
);
804 validateAndImportTrace(fileSystemElement
, traceTypeHelper
, sendValidationError
, monitor
);
807 private void validateAndImportFileTrace(TraceFileSystemElement fileSystemElement
, IProgressMonitor monitor
)
808 throws TmfTraceImportException
, CoreException
, InvocationTargetException
, InterruptedException
{
811 File file
= (File
) fileSystemElement
.getFileSystemObject();
812 String path
= file
.getAbsolutePath();
813 TraceTypeHelper traceTypeHelper
= null;
814 boolean sendValidationError
= true;
816 if (fTraceType
== null) {
818 traceTypeHelper
= TmfTraceTypeUIUtils
.selectTraceType(path
, null, null);
819 } catch (TmfTraceImportException e
) {
820 // the trace did not match any trace type
822 if (traceTypeHelper
== null) {
823 if (fImportUnrecognizedTraces
) {
824 importResource(fileSystemElement
, monitor
);
829 if (TmfTraceType
.getInstance().isDirectoryTraceType(fTraceType
)) {
832 sendValidationError
= false;
833 traceTypeHelper
= TmfTraceType
.getInstance().getTraceType(fTraceType
);
836 validateAndImportTrace(fileSystemElement
, traceTypeHelper
, sendValidationError
, monitor
);
840 private void validateAndImportTrace(TraceFileSystemElement fileSystemElement
, TraceTypeHelper traceTypeHelper
, boolean sendValidationError
, IProgressMonitor monitor
)
841 throws InvocationTargetException
, InterruptedException
, CoreException
, TmfTraceImportException
{
843 if (traceTypeHelper
== null) {
844 throw new TmfTraceImportException(Messages
.ImportTraceWizard_TraceTypeNotFound
);
846 File file
= (File
) fileSystemElement
.getFileSystemObject();
847 String path
= file
.getAbsolutePath();
849 if (TmfTraceType
.getInstance().validate(traceTypeHelper
.getCanonicalName(), path
)) {
850 if (importResource(fileSystemElement
, monitor
)) {
851 IResource eclipseResource
= fTargetFolder
.findMember(fileSystemElement
.getLabel());
852 TmfTraceTypeUIUtils
.setTraceType(eclipseResource
.getFullPath(), traceTypeHelper
);
856 if (sendValidationError
) {
857 throw new TmfTraceImportException(NLS
.bind(Messages
.ImportTraceWizard_TraceValidationFailed
, path
));
862 * Imports a trace resource to project. In case of name collision the
863 * user will be asked to confirm overwriting the existing trace,
864 * overwriting or skipping the trace to be imported.
866 * @param fileSystemElement
867 * trace file system object to import
870 * @return true if trace was imported else false
872 * @throws InvocationTargetException
873 * if problems during import operation
874 * @throws InterruptedException
876 * @throws CoreException
877 * if problems with workspace
879 private boolean importResource(TraceFileSystemElement fileSystemElement
, IProgressMonitor monitor
)
880 throws InvocationTargetException
, InterruptedException
, CoreException
{
881 ImportConfirmation mode
= checkForNameClashes(fileSystemElement
);
885 rename(fileSystemElement
);
889 delete(fileSystemElement
, monitor
);
899 List
<TraceFileSystemElement
> subList
= new ArrayList
<>();
901 IPath containerPath
= fContainerPath
;
902 FileSystemElement parentFolder
= fileSystemElement
.getParent();
904 if (fileSystemElement
.isDirectory() && (!fLink
)) {
905 containerPath
= containerPath
.addTrailingSeparator().append(fileSystemElement
.getLabel());
907 Object
[] array
= fileSystemElement
.getFiles().getChildren();
908 for (int i
= 0; i
< array
.length
; i
++) {
909 subList
.add((TraceFileSystemElement
)array
[i
]);
911 parentFolder
= fileSystemElement
;
914 subList
.add(fileSystemElement
);
918 ImportProvider fileSystemStructureProvider
= new ImportProvider();
920 IOverwriteQuery myQueryImpl
= new IOverwriteQuery() {
922 public String
queryOverwrite(String file
) {
923 return IOverwriteQuery
.NO_ALL
;
927 monitor
.setTaskName(Messages
.ImportTraceWizard_ImportOperationTaskName
+ " " + ((File
)fileSystemElement
.getFileSystemObject()).getAbsolutePath()); //$NON-NLS-1$
928 ImportOperation operation
= new ImportOperation(containerPath
, parentFolder
, fileSystemStructureProvider
, myQueryImpl
, subList
);
929 operation
.setContext(getShell());
931 operation
.setCreateContainerStructure(false);
932 operation
.setOverwriteResources(false);
933 operation
.setCreateLinks(fLink
);
934 operation
.setVirtualFolders(false);
936 operation
.run(new SubProgressMonitor(monitor
, 1, SubProgressMonitor
.PREPEND_MAIN_LABEL_TO_SUBTASK
));
940 private boolean isDirectoryTrace(FileSystemElement fileSystemElement
) {
941 File file
= (File
) fileSystemElement
.getFileSystemObject();
942 String path
= file
.getAbsolutePath();
943 if (TmfTraceType
.getInstance().isDirectoryTrace(path
)) {
949 private ImportConfirmation
checkForNameClashes(TraceFileSystemElement fileSystemElement
) throws InterruptedException
{
951 String traceName
= ((File
)fileSystemElement
.getFileSystemObject()).getName();
954 if (getExistingTrace(traceName
) != null) {
955 if ((fConfirmationMode
== ImportConfirmation
.RENAME_ALL
) ||
956 (fConfirmationMode
== ImportConfirmation
.OVERWRITE_ALL
) ||
957 (fConfirmationMode
== ImportConfirmation
.SKIP_ALL
)) {
958 return fConfirmationMode
;
961 int returnCode
= promptForOverwrite(traceName
);
962 if (returnCode
< 0) {
964 throw new InterruptedException();
966 fConfirmationMode
= ImportConfirmation
.values()[returnCode
];
967 return fConfirmationMode
;
969 return ImportConfirmation
.CONTINUE
;
972 private int promptForOverwrite(String traceName
) {
973 final MessageDialog dialog
= new MessageDialog(getContainer()
974 .getShell(), null, null, NLS
.bind(Messages
.ImportTraceWizard_TraceAlreadyExists
, traceName
),
975 MessageDialog
.QUESTION
, new String
[] {
976 ImportConfirmation
.RENAME
.getInName(),
977 ImportConfirmation
.RENAME_ALL
.getInName(),
978 ImportConfirmation
.OVERWRITE
.getInName(),
979 ImportConfirmation
.OVERWRITE_ALL
.getInName(),
980 ImportConfirmation
.SKIP
.getInName(),
981 ImportConfirmation
.SKIP_ALL
.getInName(),
984 protected int getShellStyle() {
985 return super.getShellStyle() | SWT
.SHEET
;
989 final int[] returnValue
= new int[1];
990 getShell().getDisplay().syncExec(new Runnable() {
994 returnValue
[0] = dialog
.open();
997 return returnValue
[0];
1000 private void rename(TraceFileSystemElement fileSystemElement
) {
1001 String traceName
= ((File
)fileSystemElement
.getFileSystemObject()).getName();
1002 TmfTraceElement trace
= getExistingTrace(traceName
);
1003 if (trace
== null) {
1007 IFolder folder
= trace
.getProject().getTracesFolder().getResource();
1010 String name
= trace
.getName() + '(' + Integer
.toString(i
++) + ')';
1011 IResource resource
= folder
.findMember(name
);
1012 if (resource
== null) {
1013 fileSystemElement
.setLabel(name
);
1019 private void delete(TraceFileSystemElement fileSystemElement
, IProgressMonitor monitor
) throws CoreException
{
1020 String traceName
= ((File
)fileSystemElement
.getFileSystemObject()).getName();
1021 TmfTraceElement trace
= getExistingTrace(traceName
);
1022 if (trace
== null) {
1026 trace
.delete(monitor
);
1029 private TmfTraceElement
getExistingTrace(String traceName
) {
1030 List
<TmfTraceElement
> traces
= fTraceFolderElement
.getTraces();
1031 for (TmfTraceElement t
: traces
) {
1032 if (t
.getName().equals(traceName
)) {
1040 * Set the status for this operation
1045 protected void setStatus(IStatus status
) {
1049 public IStatus
getStatus() {
1055 * The <code>TraceFileSystemElement</code> is a <code>FileSystemElement</code> that knows
1056 * if it has been populated or not.
1058 private static class TraceFileSystemElement
extends FileSystemElement
{
1060 private boolean fIsPopulated
= false;
1061 private String fLabel
= null;
1063 public TraceFileSystemElement(String name
, FileSystemElement parent
, boolean isDirectory
) {
1064 super(name
, parent
, isDirectory
);
1067 public void setPopulated() {
1068 fIsPopulated
= true;
1071 public boolean isPopulated() {
1072 return fIsPopulated
;
1076 public AdaptableList
getFiles() {
1078 populateElementChildren();
1080 return super.getFiles();
1084 public AdaptableList
getFolders() {
1086 populateElementChildren();
1088 return super.getFolders();
1092 * Sets the label for the trace to be used when importing at trace.
1094 * the label for the trace
1096 public void setLabel(String name
) {
1101 * Returns the label for the trace to be used when importing at trace.
1103 * @return the label of trace resource
1105 public String
getLabel() {
1106 if (fLabel
== null) {
1107 //Get the name - if it is empty then return the path as it is a file root
1108 File file
= (File
) getFileSystemObject();
1109 String name
= file
.getName();
1110 if (name
.length() == 0) {
1111 return file
.getPath();
1119 * Populates the children of the specified parent <code>FileSystemElement</code>
1121 private void populateElementChildren() {
1122 FileSystemStructureProvider provider
= FileSystemStructureProvider
.INSTANCE
;
1123 List
<File
> allchildren
= provider
.getChildren(this.getFileSystemObject());
1125 TraceFileSystemElement newelement
= null;
1126 Iterator
<File
> iter
= allchildren
.iterator();
1127 while(iter
.hasNext()) {
1128 child
= iter
.next();
1129 newelement
= new TraceFileSystemElement(provider
.getLabel(child
), this, provider
.isFolder(child
));
1130 newelement
.setFileSystemObject(child
);
1136 private class ImportProvider
implements IImportStructureProvider
{
1138 private FileSystemStructureProvider provider
= FileSystemStructureProvider
.INSTANCE
;
1144 public String
getLabel(Object element
) {
1145 TraceFileSystemElement resource
= (TraceFileSystemElement
)element
;
1146 return resource
.getLabel();
1150 public List
getChildren(Object element
) {
1151 TraceFileSystemElement resource
= (TraceFileSystemElement
)element
;
1152 Object
[] array
= resource
.getFiles().getChildren();
1153 List
<Object
> list
= new ArrayList
<>();
1154 for (int i
= 0; i
< array
.length
; i
++) {
1161 public InputStream
getContents(Object element
) {
1162 TraceFileSystemElement resource
= (TraceFileSystemElement
)element
;
1163 return provider
.getContents(resource
.getFileSystemObject());
1167 public String
getFullPath(Object element
) {
1168 TraceFileSystemElement resource
= (TraceFileSystemElement
)element
;
1169 return provider
.getFullPath(resource
.getFileSystemObject());
1173 public boolean isFolder(Object element
) {
1174 TraceFileSystemElement resource
= (TraceFileSystemElement
)element
;
1175 return resource
.isDirectory();
1179 private enum ImportConfirmation
{
1180 // ------------------------------------------------------------------------
1182 // ------------------------------------------------------------------------
1183 RENAME(Messages
.ImportTraceWizard_ImportConfigurationRename
),
1184 RENAME_ALL(Messages
.ImportTraceWizard_ImportConfigurationRenameAll
),
1185 OVERWRITE(Messages
.ImportTraceWizard_ImportConfigurationOverwrite
),
1186 OVERWRITE_ALL(Messages
.ImportTraceWizard_ImportConfigurationOverwriteAll
),
1187 SKIP(Messages
.ImportTraceWizard_ImportConfigurationSkip
),
1188 SKIP_ALL(Messages
.ImportTraceWizard_ImportConfigurationSkipAll
),
1189 CONTINUE("CONTINUE"); //$NON-NLS-1$
1191 // ------------------------------------------------------------------------
1193 // ------------------------------------------------------------------------
1197 private final String fInName
;
1199 // ------------------------------------------------------------------------
1201 // ------------------------------------------------------------------------
1204 * Private constructor
1205 * @param name the name of state
1207 private ImportConfirmation(String name
) {
1211 // ------------------------------------------------------------------------
1213 // ------------------------------------------------------------------------
1215 * @return state name
1217 public String
getInName() {