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
.lang
.reflect
.InvocationTargetException
;
23 import java
.text
.MessageFormat
;
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
.operation
.IRunnableWithProgress
;
47 import org
.eclipse
.jface
.operation
.ModalContext
;
48 import org
.eclipse
.jface
.viewers
.IStructuredSelection
;
49 import org
.eclipse
.jface
.viewers
.ITreeContentProvider
;
50 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.Activator
;
51 import org
.eclipse
.linuxtools
.tmf
.core
.TmfCommonConstants
;
52 import org
.eclipse
.linuxtools
.tmf
.core
.TmfProjectNature
;
53 import org
.eclipse
.linuxtools
.tmf
.core
.project
.model
.TmfTraceImportException
;
54 import org
.eclipse
.linuxtools
.tmf
.core
.project
.model
.TmfTraceType
;
55 import org
.eclipse
.linuxtools
.tmf
.core
.project
.model
.TraceTypeHelper
;
56 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
.TmfProjectRegistry
;
57 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
.TmfTraceFolder
;
58 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
.TmfTraceTypeUIUtils
;
59 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.wizards
.Messages
;
60 import org
.eclipse
.swt
.SWT
;
61 import org
.eclipse
.swt
.custom
.BusyIndicator
;
62 import org
.eclipse
.swt
.events
.FocusEvent
;
63 import org
.eclipse
.swt
.events
.FocusListener
;
64 import org
.eclipse
.swt
.events
.KeyEvent
;
65 import org
.eclipse
.swt
.events
.KeyListener
;
66 import org
.eclipse
.swt
.events
.SelectionAdapter
;
67 import org
.eclipse
.swt
.events
.SelectionEvent
;
68 import org
.eclipse
.swt
.events
.SelectionListener
;
69 import org
.eclipse
.swt
.layout
.GridData
;
70 import org
.eclipse
.swt
.layout
.GridLayout
;
71 import org
.eclipse
.swt
.widgets
.Button
;
72 import org
.eclipse
.swt
.widgets
.Combo
;
73 import org
.eclipse
.swt
.widgets
.Composite
;
74 import org
.eclipse
.swt
.widgets
.DirectoryDialog
;
75 import org
.eclipse
.swt
.widgets
.Event
;
76 import org
.eclipse
.swt
.widgets
.Group
;
77 import org
.eclipse
.swt
.widgets
.Label
;
78 import org
.eclipse
.ui
.IWorkbench
;
79 import org
.eclipse
.ui
.dialogs
.FileSystemElement
;
80 import org
.eclipse
.ui
.dialogs
.IOverwriteQuery
;
81 import org
.eclipse
.ui
.dialogs
.WizardResourceImportPage
;
82 import org
.eclipse
.ui
.model
.AdaptableList
;
83 import org
.eclipse
.ui
.model
.WorkbenchContentProvider
;
84 import org
.eclipse
.ui
.wizards
.datatransfer
.FileSystemStructureProvider
;
85 import org
.eclipse
.ui
.wizards
.datatransfer
.IImportStructureProvider
;
86 import org
.eclipse
.ui
.wizards
.datatransfer
.ImportOperation
;
89 * A variant of the standard resource import wizard for importing traces
90 * to given tracing project. If no project or tracing project was selected
91 * the wizard imports it to the default tracing project which is created
94 * In our case traces could be files or a directory structure. This wizard
95 * supports both cases. It imports traces for a selected trace type or, if
96 * no trace type is selected, it tries to detect the trace type automatically.
97 * However, the automatic detection is a best-effort and cannot guarantee
98 * that the detection is successful. The reason for this is that there might
99 * be multiple trace types that can be assigned to a single trace.
102 * @author Francois Chouinard
105 public class ImportTraceWizardPage
extends WizardResourceImportPage
{
107 // ------------------------------------------------------------------------
109 // ------------------------------------------------------------------------
110 private static final String IMPORT_WIZARD_PAGE
= "ImportTraceWizardPage"; //$NON-NLS-1$
111 private static final String IMPORT_WIZARD_IMPORT_UNRECOGNIZED_ID
= IMPORT_WIZARD_PAGE
+ ".import_unrecognized_traces_id"; //$NON-NLS-1$
112 private static final String SEPARATOR
= ":"; //$NON-NLS-1$
113 private static final String AUTO_DETECT
= Messages
.ImportTraceWizard_AutoDetection
;
115 // ------------------------------------------------------------------------
117 // ------------------------------------------------------------------------
119 // Folder navigation start point (saved between invocations)
120 private static String fRootDirectory
= null;
121 // Target import directory ('Traces' folder)
122 private IFolder fTargetFolder
;
123 // Flag to handle destination folder change event
124 private Boolean fIsDestinationChanged
= false;
125 // Combo box containing trace types
126 private Combo fTraceTypes
;
127 // Button to ignore unrecognized traces or not
128 private Button fImportUnrecognizedButton
;
129 // Button to overwrite existing resources or not
130 private Button fOverwriteExistingResourcesCheckbox
;
131 // Button to link or copy traces to workspace
132 private Button fCreateLinksInWorkspaceButton
;
133 private boolean entryChanged
= false;
134 /** The directory name field */
135 protected Combo directoryNameField
;
136 /** The directory browse button. */
137 protected Button directoryBrowseButton
;
139 // ------------------------------------------------------------------------
141 // ------------------------------------------------------------------------
144 * Constructor. Creates the trace wizard page.
147 * The name of the page.
149 * The current selection
151 protected ImportTraceWizardPage(String name
, IStructuredSelection selection
) {
152 super(name
, selection
);
159 * The workbench reference.
161 * The current selection
163 public ImportTraceWizardPage(IWorkbench workbench
, IStructuredSelection selection
) {
164 this(IMPORT_WIZARD_PAGE
, selection
);
165 setTitle(Messages
.ImportTraceWizard_FileSystemTitle
);
166 setDescription(Messages
.ImportTraceWizard_ImportTrace
);
168 // Locate the target trace folder
169 IFolder traceFolder
= null;
170 Object element
= selection
.getFirstElement();
172 if (element
instanceof TmfTraceFolder
) {
173 TmfTraceFolder tmfTraceFolder
= (TmfTraceFolder
) element
;
174 tmfTraceFolder
.getProject().getResource();
175 traceFolder
= tmfTraceFolder
.getResource();
176 } else if (element
instanceof IProject
) {
177 IProject project
= (IProject
) element
;
179 if (project
.hasNature(TmfProjectNature
.ID
)) {
180 traceFolder
= project
.getFolder(TmfTraceFolder
.TRACE_FOLDER_NAME
);
182 } catch (CoreException e
) {
187 * If no tracing project was selected or trace folder doesn't exist use
189 if (traceFolder
== null) {
190 IProject project
= TmfProjectRegistry
.createProject(
191 TmfCommonConstants
.DEFAULT_TRACE_PROJECT_NAME
, null, new NullProgressMonitor());
192 traceFolder
= project
.getFolder(TmfTraceFolder
.TRACE_FOLDER_NAME
);
195 // Set the target trace folder
196 if (traceFolder
!= null) {
197 fTargetFolder
= traceFolder
;
198 String path
= traceFolder
.getFullPath().toOSString();
199 setContainerFieldValue(path
);
203 // ------------------------------------------------------------------------
204 // WizardResourceImportPage
205 // ------------------------------------------------------------------------
208 public void createControl(Composite parent
) {
209 super.createControl(parent
);
210 // Restore last directory if applicable
211 if (fRootDirectory
!= null) {
212 directoryNameField
.setText(fRootDirectory
);
213 updateFromSourceField();
218 protected void createSourceGroup(Composite parent
) {
219 createDirectorySelectionGroup(parent
);
220 createFileSelectionGroup(parent
);
221 createTraceTypeGroup(parent
);
222 validateSourceGroup();
226 protected ITreeContentProvider
getFileProvider() {
227 return new WorkbenchContentProvider() {
229 public Object
[] getChildren(Object object
) {
230 if (object
instanceof TraceFileSystemElement
) {
231 TraceFileSystemElement element
= (TraceFileSystemElement
) object
;
232 return element
.getFiles().getChildren(element
);
234 return new Object
[0];
240 protected ITreeContentProvider
getFolderProvider() {
241 return new WorkbenchContentProvider() {
243 public Object
[] getChildren(Object o
) {
244 if (o
instanceof TraceFileSystemElement
) {
245 TraceFileSystemElement element
= (TraceFileSystemElement
) o
;
246 return element
.getFolders().getChildren();
248 return new Object
[0];
252 public boolean hasChildren(Object o
) {
253 if (o
instanceof TraceFileSystemElement
) {
254 TraceFileSystemElement element
= (TraceFileSystemElement
) o
;
255 if (element
.isPopulated()) {
256 return getChildren(element
).length
> 0;
258 //If we have not populated then wait until asked
266 // ------------------------------------------------------------------------
267 // Directory Selection Group (forked WizardFileSystemResourceImportPage1)
268 // ------------------------------------------------------------------------
271 * creates the directory selection group.
274 * the parent composite
276 protected void createDirectorySelectionGroup(Composite parent
) {
278 Composite directoryContainerGroup
= new Composite(parent
, SWT
.NONE
);
279 GridLayout layout
= new GridLayout();
280 layout
.numColumns
= 3;
281 directoryContainerGroup
.setLayout(layout
);
282 directoryContainerGroup
.setFont(parent
.getFont());
283 directoryContainerGroup
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, false));
285 // Label ("Trace directory:")
286 Label groupLabel
= new Label(directoryContainerGroup
, SWT
.NONE
);
287 groupLabel
.setText(Messages
.ImportTraceWizard_DirectoryLocation
);
288 groupLabel
.setFont(parent
.getFont());
290 // Directory name entry field
291 directoryNameField
= new Combo(directoryContainerGroup
, SWT
.BORDER
);
292 GridData data
= new GridData(SWT
.FILL
, SWT
.FILL
, true, false);
293 data
.widthHint
= SIZING_TEXT_FIELD_WIDTH
;
294 directoryNameField
.setLayoutData(data
);
295 directoryNameField
.setFont(parent
.getFont());
297 directoryNameField
.addSelectionListener(new SelectionAdapter() {
299 public void widgetSelected(SelectionEvent e
) {
300 updateFromSourceField();
304 directoryNameField
.addKeyListener(new KeyListener() {
306 public void keyPressed(KeyEvent e
) {
307 // If there has been a key pressed then mark as dirty
309 if (e
.character
== SWT
.CR
) { // Windows...
310 entryChanged
= false;
311 updateFromSourceField();
316 public void keyReleased(KeyEvent e
) {
320 directoryNameField
.addFocusListener(new FocusListener() {
322 public void focusGained(FocusEvent e
) {
323 // Do nothing when getting focus
326 public void focusLost(FocusEvent e
) {
327 // Clear the flag to prevent constant update
329 entryChanged
= false;
330 updateFromSourceField();
336 directoryBrowseButton
= new Button(directoryContainerGroup
, SWT
.PUSH
);
337 directoryBrowseButton
.setText(Messages
.ImportTraceWizard_BrowseButton
);
338 directoryBrowseButton
.addListener(SWT
.Selection
, this);
339 directoryBrowseButton
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, false, false));
340 directoryBrowseButton
.setFont(parent
.getFont());
341 setButtonLayoutData(directoryBrowseButton
);
344 // ------------------------------------------------------------------------
345 // Browse for the source directory
346 // ------------------------------------------------------------------------
349 public void handleEvent(Event event
) {
350 if (event
.widget
== directoryBrowseButton
) {
351 handleSourceDirectoryBrowseButtonPressed();
354 // Avoid overwriting destination path without repeatedly trigger
355 // call of handleEvent();
356 synchronized (fIsDestinationChanged
) {
357 if (fIsDestinationChanged
== false) {
358 event
.display
.asyncExec(new Runnable() {
361 synchronized (fIsDestinationChanged
) {
362 fIsDestinationChanged
= true;
363 String path
= fTargetFolder
.getFullPath().toOSString();
364 setContainerFieldValue(path
);
369 fIsDestinationChanged
= false;
372 super.handleEvent(event
);
376 protected void handleContainerBrowseButtonPressed() {
377 // Do nothing so that destination directory cannot be changed.
381 * Handle the button pressed event
383 protected void handleSourceDirectoryBrowseButtonPressed() {
384 String currentSource
= directoryNameField
.getText();
385 DirectoryDialog dialog
= new DirectoryDialog(directoryNameField
.getShell(), SWT
.SAVE
| SWT
.SHEET
);
386 dialog
.setText(Messages
.ImportTraceWizard_SelectTraceDirectoryTitle
);
387 dialog
.setMessage(Messages
.ImportTraceWizard_SelectTraceDirectoryMessage
);
388 dialog
.setFilterPath(getSourceDirectoryName(currentSource
));
390 String selectedDirectory
= dialog
.open();
391 if (selectedDirectory
!= null) {
392 // Just quit if the directory is not valid
393 if ((getSourceDirectory(selectedDirectory
) == null) || selectedDirectory
.equals(currentSource
)) {
396 // If it is valid then proceed to populate
397 setErrorMessage(null);
398 setSourceName(selectedDirectory
);
402 private File
getSourceDirectory() {
403 return getSourceDirectory(directoryNameField
.getText());
406 private static File
getSourceDirectory(String path
) {
407 File sourceDirectory
= new File(getSourceDirectoryName(path
));
408 if (!sourceDirectory
.exists() || !sourceDirectory
.isDirectory()) {
412 return sourceDirectory
;
415 private static String
getSourceDirectoryName(String sourceName
) {
416 IPath result
= new Path(sourceName
.trim());
417 if (result
.getDevice() != null && result
.segmentCount() == 0) {
418 result
= result
.addTrailingSeparator();
420 result
= result
.removeTrailingSeparator();
422 return result
.toOSString();
425 private String
getSourceDirectoryName() {
426 return getSourceDirectoryName(directoryNameField
.getText());
429 private void updateFromSourceField() {
430 setSourceName(directoryNameField
.getText());
431 updateWidgetEnablements();
434 private void setSourceName(String path
) {
435 if (path
.length() > 0) {
436 String
[] currentItems
= directoryNameField
.getItems();
437 int selectionIndex
= -1;
438 for (int i
= 0; i
< currentItems
.length
; i
++) {
439 if (currentItems
[i
].equals(path
)) {
443 if (selectionIndex
< 0) {
444 int oldLength
= currentItems
.length
;
445 String
[] newItems
= new String
[oldLength
+ 1];
446 System
.arraycopy(currentItems
, 0, newItems
, 0, oldLength
);
447 newItems
[oldLength
] = path
;
448 directoryNameField
.setItems(newItems
);
449 selectionIndex
= oldLength
;
451 directoryNameField
.select(selectionIndex
);
456 // ------------------------------------------------------------------------
457 // File Selection Group (forked WizardFileSystemResourceImportPage1)
458 // ------------------------------------------------------------------------
459 private void resetSelection() {
460 TraceFileSystemElement root
= getFileSystemTree();
461 selectionGroup
.setRoot(root
);
464 private TraceFileSystemElement
getFileSystemTree() {
465 File sourceDirectory
= getSourceDirectory();
466 if (sourceDirectory
== null) {
469 return selectFiles(sourceDirectory
, FileSystemStructureProvider
.INSTANCE
);
472 private TraceFileSystemElement
selectFiles(final Object rootFileSystemObject
,
473 final IImportStructureProvider structureProvider
) {
474 final TraceFileSystemElement
[] results
= new TraceFileSystemElement
[1];
475 BusyIndicator
.showWhile(getShell().getDisplay(), new Runnable() {
478 // Create the root element from the supplied file system object
479 results
[0] = createRootElement(rootFileSystemObject
, structureProvider
);
485 private static TraceFileSystemElement
createRootElement(Object fileSystemObject
,
486 IImportStructureProvider provider
) {
488 boolean isContainer
= provider
.isFolder(fileSystemObject
);
489 String elementLabel
= provider
.getLabel(fileSystemObject
);
491 // Use an empty label so that display of the element's full name
492 // doesn't include a confusing label
493 TraceFileSystemElement dummyParent
= new TraceFileSystemElement("", null, true);//$NON-NLS-1$
494 dummyParent
.setPopulated();
495 TraceFileSystemElement result
= new TraceFileSystemElement(
496 elementLabel
, dummyParent
, isContainer
);
497 result
.setFileSystemObject(fileSystemObject
);
499 //Get the files for the element so as to build the first level
505 // ------------------------------------------------------------------------
507 // ------------------------------------------------------------------------
508 private final void createTraceTypeGroup(Composite parent
) {
509 Composite composite
= new Composite(parent
, SWT
.NONE
);
510 GridLayout layout
= new GridLayout();
511 layout
.numColumns
= 3;
512 layout
.makeColumnsEqualWidth
= false;
513 composite
.setLayout(layout
);
514 composite
.setFont(parent
.getFont());
515 GridData buttonData
= new GridData(SWT
.FILL
, SWT
.FILL
, true, false);
516 composite
.setLayoutData(buttonData
);
518 // Trace type label ("Trace Type:")
519 Label typeLabel
= new Label(composite
, SWT
.NONE
);
520 typeLabel
.setText(Messages
.ImportTraceWizard_TraceType
);
521 typeLabel
.setFont(parent
.getFont());
524 fTraceTypes
= new Combo(composite
, SWT
.BORDER
| SWT
.READ_ONLY
);
525 GridData data
= new GridData(SWT
.FILL
, SWT
.FILL
, true, false, 2, 1);
526 fTraceTypes
.setLayoutData(data
);
527 fTraceTypes
.setFont(parent
.getFont());
529 String
[] availableTraceTypes
= TmfTraceType
.getInstance().getAvailableTraceTypes();
530 String
[] traceTypeList
= new String
[availableTraceTypes
.length
+ 1];
531 traceTypeList
[0] = AUTO_DETECT
;
532 for (int i
= 0; i
< availableTraceTypes
.length
; i
++) {
533 traceTypeList
[i
+ 1] = availableTraceTypes
[i
];
535 fTraceTypes
.setItems(traceTypeList
);
536 fTraceTypes
.addSelectionListener(new SelectionListener() {
538 public void widgetSelected(SelectionEvent e
) {
539 updateWidgetEnablements();
543 public void widgetDefaultSelected(SelectionEvent e
) {
546 fTraceTypes
.select(0);
548 fImportUnrecognizedButton
= new Button(composite
, SWT
.CHECK
);
549 fImportUnrecognizedButton
.setSelection(true);
550 fImportUnrecognizedButton
.setText(Messages
.ImportTraceWizard_ImportUnrecognized
);
552 IDialogSettings settings
= getDialogSettings();
554 if (settings
.get(IMPORT_WIZARD_IMPORT_UNRECOGNIZED_ID
) == null) {
557 value
= settings
.getBoolean(IMPORT_WIZARD_IMPORT_UNRECOGNIZED_ID
);
559 fImportUnrecognizedButton
.setSelection(value
);
562 // ------------------------------------------------------------------------
564 // ------------------------------------------------------------------------
567 protected void createOptionsGroupButtons(Group optionsGroup
) {
569 // Overwrite checkbox
570 fOverwriteExistingResourcesCheckbox
= new Button(optionsGroup
, SWT
.CHECK
);
571 fOverwriteExistingResourcesCheckbox
.setFont(optionsGroup
.getFont());
572 fOverwriteExistingResourcesCheckbox
.setText(Messages
.ImportTraceWizard_OverwriteExistingTrace
);
573 fOverwriteExistingResourcesCheckbox
.setSelection(false);
575 // Create links checkbox
576 fCreateLinksInWorkspaceButton
= new Button(optionsGroup
, SWT
.CHECK
);
577 fCreateLinksInWorkspaceButton
.setFont(optionsGroup
.getFont());
578 fCreateLinksInWorkspaceButton
.setText(Messages
.ImportTraceWizard_CreateLinksInWorkspace
);
579 fCreateLinksInWorkspaceButton
.setSelection(true);
581 fCreateLinksInWorkspaceButton
.addSelectionListener(new SelectionAdapter() {
583 public void widgetSelected(SelectionEvent e
) {
584 updateWidgetEnablements();
588 updateWidgetEnablements();
591 // ------------------------------------------------------------------------
592 // Determine if the finish button can be enabled
593 // ------------------------------------------------------------------------
596 public boolean validateSourceGroup() {
598 File sourceDirectory
= getSourceDirectory();
599 if (sourceDirectory
== null) {
600 setMessage(Messages
.ImportTraceWizard_SelectTraceSourceEmpty
);
604 if (sourceConflictsWithDestination(new Path(sourceDirectory
.getPath()))) {
606 setErrorMessage(getSourceConflictMessage());
610 List
<FileSystemElement
> resourcesToImport
= getSelectedResources();
611 if (resourcesToImport
.size() == 0) {
613 setErrorMessage(Messages
.ImportTraceWizard_SelectTraceNoneSelected
);
617 IContainer container
= getSpecifiedContainer();
618 if (container
!= null && container
.isVirtual()) {
619 if (Platform
.getPreferencesService().getBoolean(Activator
.PLUGIN_ID
, ResourcesPlugin
.PREF_DISABLE_LINKING
, false, null)) {
621 setErrorMessage(Messages
.ImportTraceWizard_CannotImportFilesUnderAVirtualFolder
);
624 if (fCreateLinksInWorkspaceButton
== null || !fCreateLinksInWorkspaceButton
.getSelection()) {
626 setErrorMessage(Messages
.ImportTraceWizard_HaveToCreateLinksUnderAVirtualFolder
);
631 setErrorMessage(null);
635 // ------------------------------------------------------------------------
636 // Import the trace(s)
637 // ------------------------------------------------------------------------
642 * @return <code>true</code> if successful else <code>false</code>
644 public boolean finish() {
645 IDialogSettings settings
= getDialogSettings();
646 settings
.put(IMPORT_WIZARD_IMPORT_UNRECOGNIZED_ID
, fImportUnrecognizedButton
.getSelection());
648 String traceTypeName
= fTraceTypes
.getText();
649 String traceId
= null;
650 if (!AUTO_DETECT
.equals(traceTypeName
)) {
651 String tokens
[] = traceTypeName
.split(SEPARATOR
, 2);
652 if (tokens
.length
< 2) {
655 traceId
= TmfTraceType
.getInstance().getTraceTypeId(tokens
[0], tokens
[1]);
658 // Save directory for next import operation
659 fRootDirectory
= getSourceDirectoryName();
661 final TraceValidateAndImportOperation operation
= new TraceValidateAndImportOperation(traceId
, getContainerFullPath(),
662 fImportUnrecognizedButton
.getSelection(), fOverwriteExistingResourcesCheckbox
.getSelection(), fCreateLinksInWorkspaceButton
.getSelection());
664 IStatus status
= Status
.OK_STATUS
;
666 getContainer().run(true, true, new IRunnableWithProgress() {
668 public void run(IProgressMonitor monitor
) throws InvocationTargetException
, InterruptedException
{
669 operation
.run(monitor
);
674 status
= operation
.getStatus();
675 } catch (InvocationTargetException e
) {
676 status
= new Status(IStatus
.ERROR
, Activator
.PLUGIN_ID
, Messages
.ImportTraceWizard_ImportProblem
, e
);
677 } catch (InterruptedException e
) {
678 status
= Status
.CANCEL_STATUS
;
680 if (!status
.isOK()) {
681 if (status
.getSeverity() == IStatus
.CANCEL
) {
682 setMessage(Messages
.ImportTraceWizard_ImportOperationCancelled
);
683 setErrorMessage(null);
685 if (status
.getException() != null) {
686 displayErrorDialog(status
.getMessage() + ": " + status
.getException()); //$NON-NLS-1$
689 setErrorMessage(Messages
.ImportTraceWizard_ImportProblem
);
694 if (operation
.getUnrecognizedTraces().size() > 0) {
695 StringBuilder unrecognizedTraces
= new StringBuilder();
696 for(String trace
: operation
.getUnrecognizedTraces()) {
697 unrecognizedTraces
.append(System
.getProperty("line.separator")).append(trace
); //$NON-NLS-1$
699 displayErrorDialog(Messages
.ImportTraceWizard_NoValidTraceTypeFound
+ ":" + unrecognizedTraces
.toString()); //$NON-NLS-1$
701 setErrorMessage(null);
706 // ------------------------------------------------------------------------
708 // ------------------------------------------------------------------------
710 class TraceValidateAndImportOperation
{
711 private IStatus fStatus
;
712 final List
<String
> fUnrecognizedResources
= new ArrayList
<>();
713 private String fTraceType
;
714 private IPath fContainerPath
;
715 private boolean fImportUnrecognizedTraces
;
716 private boolean fOverwrite
;
717 private boolean fLink
;
719 TraceValidateAndImportOperation(String traceId
, IPath containerPath
, boolean doImport
, boolean overwrite
, boolean link
) {
720 fTraceType
= traceId
;
721 fContainerPath
= containerPath
;
722 fImportUnrecognizedTraces
= doImport
;
723 fOverwrite
= overwrite
;
727 public void run(IProgressMonitor progressMonitor
) {
728 String currentPath
= null;
729 final Map
<String
, FileSystemElement
> folderResources
= new HashMap
<>();
731 List
<FileSystemElement
> resources
= getSelectedResources();
732 Iterator
<FileSystemElement
> resourcesEnum
= resources
.iterator();
733 SubMonitor subMonitor
= SubMonitor
.convert(progressMonitor
, resources
.size());
734 // subMonitor.beginTask("Importing: ", resources.size());
736 while (resourcesEnum
.hasNext()) {
737 ModalContext
.checkCanceled(progressMonitor
);
739 FileSystemElement resource
= resourcesEnum
.next();
740 File resourceFile
= (File
) resource
.getFileSystemObject();
741 String resourcePath
= resourceFile
.getAbsolutePath();
742 currentPath
= resourcePath
;
743 SubMonitor sub
= subMonitor
.newChild(1);
744 if (resource
.isDirectory()) {
745 if (!folderResources
.containsKey(resourcePath
)) {
746 if (isDirectoryTrace(resource
)) {
747 folderResources
.put(resourcePath
, resource
);
748 validateAndImportDirectoryTrace(resource
, sub
);
752 FileSystemElement parent
= resource
.getParent();
753 File file
= (File
) parent
.getFileSystemObject();
754 String parentPath
= file
.getAbsolutePath();
755 currentPath
= parentPath
;
756 if (!folderResources
.containsKey(parentPath
)) {
757 if (isDirectoryTrace(parent
)) {
758 folderResources
.put(parentPath
, parent
);
759 validateAndImportDirectoryTrace(parent
, sub
);
761 if (resourceFile
.exists()) {
762 validateAndImportFileTrace(resource
, sub
);
768 setStatus(Status
.OK_STATUS
);
769 } catch (InterruptedException e
) {
770 setStatus(Status
.CANCEL_STATUS
);
771 } catch (Exception e
) {
772 setStatus(new Status(IStatus
.ERROR
, Activator
.PLUGIN_ID
, Messages
.ImportTraceWizard_ImportProblem
+ ": " + //$NON-NLS-1$
773 (currentPath
!= null ? currentPath
: "") , e
)); //$NON-NLS-1$
778 * @return a list of trace file names for that no trace type could be detected.
780 public List
<String
> getUnrecognizedTraces() {
781 return new ArrayList
<>(fUnrecognizedResources
);
784 private void validateAndImportDirectoryTrace(FileSystemElement resource
, IProgressMonitor monitor
)
785 throws TmfTraceImportException
, CoreException
, InvocationTargetException
, InterruptedException
{
786 File file
= (File
) resource
.getFileSystemObject();
787 String path
= file
.getAbsolutePath();
788 TraceTypeHelper traceTypeHelper
;
789 boolean sendValidationError
= true;
790 if (fTraceType
== null) {
791 traceTypeHelper
= TmfTraceTypeUIUtils
.selectTraceType(path
, null, null);
793 if (!TmfTraceType
.getInstance().isDirectoryTraceType(fTraceType
)) {
796 sendValidationError
= false;
797 traceTypeHelper
= TmfTraceType
.getInstance().getTraceType(fTraceType
);
799 validateAndImportTrace(file
, traceTypeHelper
, sendValidationError
, monitor
);
802 private void validateAndImportFileTrace(FileSystemElement resource
, IProgressMonitor monitor
)
803 throws TmfTraceImportException
, CoreException
, InvocationTargetException
, InterruptedException
{
805 File file
= (File
) resource
.getFileSystemObject();
806 String path
= file
.getAbsolutePath();
807 TraceTypeHelper traceTypeHelper
= null;
808 boolean sendValidationError
= true;
809 if (fTraceType
== null) {
810 // TODO add automatic trace type selection for trace file
811 if (fImportUnrecognizedTraces
) {
812 importResource(file
, monitor
);
813 fUnrecognizedResources
.add(path
);
818 if (TmfTraceType
.getInstance().isDirectoryTraceType(fTraceType
)) {
821 sendValidationError
= false;
822 traceTypeHelper
= TmfTraceType
.getInstance().getTraceType(fTraceType
);
823 validateAndImportTrace(file
, traceTypeHelper
, sendValidationError
, monitor
);
827 private void validateAndImportTrace(File file
, TraceTypeHelper traceTypeHelper
, boolean sendValidationError
, IProgressMonitor monitor
)
828 throws InvocationTargetException
, InterruptedException
, CoreException
, TmfTraceImportException
{
830 if (traceTypeHelper
== null) {
831 throw new TmfTraceImportException(Messages
.ImportTraceWizard_TraceTypeNotFound
);
834 String path
= file
.getAbsolutePath();
836 if (TmfTraceType
.getInstance().validate(traceTypeHelper
.getCanonicalName(), path
)) {
837 importResource(file
, monitor
);
838 IResource eclipseResource
= fTargetFolder
.findMember(file
.getName());
839 TmfTraceTypeUIUtils
.setTraceType(eclipseResource
.getFullPath(), traceTypeHelper
);
842 if (sendValidationError
) {
843 throw new TmfTraceImportException(MessageFormat
.format(Messages
.ImportTraceWizard_TraceValidationFailed
, path
));
847 private void importResource(File fileSystemObject
, IProgressMonitor monitor
) throws InvocationTargetException
, InterruptedException
{
848 File parentFolder
= new File(fileSystemObject
.getParent());
849 List
<File
> subList
= new ArrayList
<>();
850 subList
.add(fileSystemObject
);
851 FileSystemStructureProvider fileSystemStructureProvider
= FileSystemStructureProvider
.INSTANCE
;
853 // TODO have own IOverwriteQuery implementation for proper handling of overwrite and renaming
854 IOverwriteQuery myQueryImpl
= new IOverwriteQuery() {
856 public String
queryOverwrite(String file
) {
857 return fOverwrite ? IOverwriteQuery
.ALL
: IOverwriteQuery
.NO_ALL
;
861 monitor
.setTaskName(Messages
.ImportTraceWizard_ImportOperationTaskName
+ " " + fileSystemObject
.getAbsolutePath()); //$NON-NLS-1$
862 ImportOperation operation
= new ImportOperation(fContainerPath
, parentFolder
, fileSystemStructureProvider
, myQueryImpl
, subList
);
863 operation
.setContext(getShell());
865 operation
.setCreateContainerStructure(false);
866 operation
.setOverwriteResources(fOverwrite
);
867 operation
.setCreateLinks(fLink
);
868 operation
.setVirtualFolders(false);
870 operation
.run(new SubProgressMonitor(monitor
, 1, SubProgressMonitor
.PREPEND_MAIN_LABEL_TO_SUBTASK
));
873 private boolean isDirectoryTrace(FileSystemElement resource
) {
874 File file
= (File
) resource
.getFileSystemObject();
875 String path
= file
.getAbsolutePath();
876 if (TmfTraceType
.getInstance().isDirectoryTrace(path
)) {
883 * Set the status for this operation
888 protected void setStatus(IStatus status
) {
892 public IStatus
getStatus() {
898 * The <code>TraceFileSystemElement</code> is a <code>FileSystemElement</code> that knows
899 * if it has been populated or not.
901 static class TraceFileSystemElement
extends FileSystemElement
{
903 private boolean populated
= false;
905 public TraceFileSystemElement(String name
, FileSystemElement parent
, boolean isDirectory
) {
906 super(name
, parent
, isDirectory
);
909 public void setPopulated() {
913 public boolean isPopulated() {
918 public AdaptableList
getFiles() {
920 populateElementChildren();
922 return super.getFiles();
926 public AdaptableList
getFolders() {
928 populateElementChildren();
930 return super.getFolders();
934 * Populates the children of the specified parent <code>FileSystemElement</code>
936 private void populateElementChildren() {
937 FileSystemStructureProvider provider
= FileSystemStructureProvider
.INSTANCE
;
938 List
<File
> allchildren
= provider
.getChildren(this.getFileSystemObject());
940 TraceFileSystemElement newelement
= null;
941 Iterator
<File
> iter
= allchildren
.iterator();
942 while(iter
.hasNext()) {
944 newelement
= new TraceFileSystemElement(provider
.getLabel(child
), this, provider
.isFolder(child
));
945 newelement
.setFileSystemObject(child
);