1 /*******************************************************************************
2 * Copyright (c) 2009, 2010, 2011 Ericsson
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 *******************************************************************************/
15 package org
.eclipse
.linuxtools
.tmf
.ui
.project
.wizards
;
18 import java
.io
.IOException
;
19 import java
.lang
.reflect
.InvocationTargetException
;
20 import java
.util
.ArrayList
;
21 import java
.util
.Collections
;
22 import java
.util
.HashMap
;
23 import java
.util
.Iterator
;
24 import java
.util
.LinkedList
;
25 import java
.util
.List
;
28 import org
.eclipse
.core
.resources
.IContainer
;
29 import org
.eclipse
.core
.resources
.IFolder
;
30 import org
.eclipse
.core
.resources
.IProject
;
31 import org
.eclipse
.core
.resources
.IResource
;
32 import org
.eclipse
.core
.resources
.ResourcesPlugin
;
33 import org
.eclipse
.core
.runtime
.CoreException
;
34 import org
.eclipse
.core
.runtime
.IConfigurationElement
;
35 import org
.eclipse
.core
.runtime
.IPath
;
36 import org
.eclipse
.core
.runtime
.IStatus
;
37 import org
.eclipse
.core
.runtime
.Path
;
38 import org
.eclipse
.core
.runtime
.Platform
;
39 import org
.eclipse
.jface
.dialogs
.ErrorDialog
;
40 import org
.eclipse
.jface
.dialogs
.MessageDialog
;
41 import org
.eclipse
.jface
.viewers
.CheckStateChangedEvent
;
42 import org
.eclipse
.jface
.viewers
.CheckboxTreeViewer
;
43 import org
.eclipse
.jface
.viewers
.ICheckStateListener
;
44 import org
.eclipse
.jface
.viewers
.IStructuredSelection
;
45 import org
.eclipse
.jface
.viewers
.ITreeContentProvider
;
46 import org
.eclipse
.linuxtools
.tmf
.TmfCorePlugin
;
47 import org
.eclipse
.linuxtools
.tmf
.TmfProjectNature
;
48 import org
.eclipse
.linuxtools
.tmf
.trace
.ITmfTrace
;
49 import org
.eclipse
.linuxtools
.tmf
.ui
.TmfUiPlugin
;
50 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
.TmfTraceElement
;
51 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
.TmfTraceFolder
;
52 import org
.eclipse
.swt
.SWT
;
53 import org
.eclipse
.swt
.custom
.BusyIndicator
;
54 import org
.eclipse
.swt
.events
.FocusEvent
;
55 import org
.eclipse
.swt
.events
.FocusListener
;
56 import org
.eclipse
.swt
.events
.KeyEvent
;
57 import org
.eclipse
.swt
.events
.KeyListener
;
58 import org
.eclipse
.swt
.events
.SelectionAdapter
;
59 import org
.eclipse
.swt
.events
.SelectionEvent
;
60 import org
.eclipse
.swt
.events
.SelectionListener
;
61 import org
.eclipse
.swt
.layout
.GridData
;
62 import org
.eclipse
.swt
.layout
.GridLayout
;
63 import org
.eclipse
.swt
.widgets
.Button
;
64 import org
.eclipse
.swt
.widgets
.Combo
;
65 import org
.eclipse
.swt
.widgets
.Composite
;
66 import org
.eclipse
.swt
.widgets
.DirectoryDialog
;
67 import org
.eclipse
.swt
.widgets
.Event
;
68 import org
.eclipse
.swt
.widgets
.Group
;
69 import org
.eclipse
.swt
.widgets
.Label
;
70 import org
.eclipse
.swt
.widgets
.Listener
;
71 import org
.eclipse
.ui
.IWorkbench
;
72 import org
.eclipse
.ui
.dialogs
.FileSystemElement
;
73 import org
.eclipse
.ui
.dialogs
.WizardResourceImportPage
;
74 import org
.eclipse
.ui
.model
.WorkbenchContentProvider
;
75 import org
.eclipse
.ui
.model
.WorkbenchLabelProvider
;
76 import org
.eclipse
.ui
.wizards
.datatransfer
.FileSystemStructureProvider
;
77 import org
.eclipse
.ui
.wizards
.datatransfer
.IImportStructureProvider
;
78 import org
.eclipse
.ui
.wizards
.datatransfer
.ImportOperation
;
81 * <b><u>ImportTraceWizardPage</u></b>
83 * A variant of the standard resource import wizard with the following changes:
85 * <li>A folder/file combined checkbox tree viewer to select traces
86 * <li>Cherry-picking of traces in the file structure without re-creating the file hierarchy
87 * <li>A trace types dropbox for optional characterization
89 * For our purpose, a trace can either be a single file or a whole directory sub-tree, whichever is reached first from
92 * TODO: Consider adding Filter/Select/Deselect buttons
94 public class ImportTraceWizardPage
extends WizardResourceImportPage
implements Listener
{
96 // ------------------------------------------------------------------------
98 // ------------------------------------------------------------------------
100 static private final String IMPORT_WIZARD_PAGE
= "ImportTraceWizardPage"; //$NON-NLS-1$
102 // ------------------------------------------------------------------------
104 // ------------------------------------------------------------------------
106 // Folder navigation start point (saved between invocations)
107 private static String fRootDirectory
= null;
109 // Navigation folder content viewer and selector
110 private CheckboxTreeViewer fFolderViewer
;
112 // Parent tracing project
113 private IProject fProject
;
115 // Target import directory ('Traces' folder)
116 private IFolder fTargetFolder
;
118 // Selected trace attributes
119 private final Map
<String
, IConfigurationElement
> fTraceAttributes
= new HashMap
<String
, IConfigurationElement
>();
121 // ------------------------------------------------------------------------
123 // ------------------------------------------------------------------------
125 protected ImportTraceWizardPage(String name
, IStructuredSelection selection
) {
126 super(name
, selection
);
129 public ImportTraceWizardPage(IWorkbench workbench
, IStructuredSelection selection
) {
130 this(IMPORT_WIZARD_PAGE
, selection
);
131 setTitle(Messages
.ImportTraceWizard_FileSystemTitle
);
132 setDescription(Messages
.ImportTraceWizard_ImportTrace
);
134 // Locate the target trace folder
135 IFolder traceFolder
= null;
136 Object element
= selection
.getFirstElement();
138 if (element
instanceof TmfTraceFolder
) {
139 TmfTraceFolder tmfTraceFolder
= (TmfTraceFolder
) element
;
140 fProject
= tmfTraceFolder
.getProject().getResource();
141 traceFolder
= tmfTraceFolder
.getResource();
142 } else if (element
instanceof IProject
) {
143 IProject project
= (IProject
) element
;
145 if (project
.hasNature(TmfProjectNature
.ID
)) {
146 traceFolder
= (IFolder
) project
.findMember(TmfTraceFolder
.TRACE_FOLDER_NAME
);
148 } catch (CoreException e
) {
152 // Set the target trace folder
153 if (traceFolder
!= null) {
154 fTargetFolder
= traceFolder
;
155 String path
= traceFolder
.getFullPath().toOSString();
156 setContainerFieldValue(path
);
160 // ------------------------------------------------------------------------
161 // WizardResourceImportPage
162 // ------------------------------------------------------------------------
165 public void createControl(Composite parent
) {
166 super.createControl(parent
);
167 // Restore last directory if applicable
168 if (fRootDirectory
!= null) {
169 directoryNameField
.setText(fRootDirectory
);
170 updateFromSourceField();
175 protected void createSourceGroup(Composite parent
) {
176 createDirectorySelectionGroup(parent
);
177 createFileSelectionGroup(parent
);
178 createTraceTypeGroup(parent
);
179 validateSourceGroup();
183 protected void createFileSelectionGroup(Composite parent
) {
185 // This Composite is only used for widget alignment purposes
186 Composite composite
= new Composite(parent
, SWT
.NONE
);
187 composite
.setFont(parent
.getFont());
188 GridLayout layout
= new GridLayout();
189 composite
.setLayout(layout
);
190 composite
.setLayoutData(new GridData(GridData
.FILL_BOTH
));
192 final int PREFERRED_LIST_HEIGHT
= 150;
194 fFolderViewer
= new CheckboxTreeViewer(composite
, SWT
.BORDER
);
195 GridData data
= new GridData(GridData
.FILL_BOTH
);
196 data
.heightHint
= PREFERRED_LIST_HEIGHT
;
197 fFolderViewer
.getTree().setLayoutData(data
);
198 fFolderViewer
.getTree().setFont(parent
.getFont());
200 fFolderViewer
.setContentProvider(getFileProvider());
201 fFolderViewer
.setLabelProvider(new WorkbenchLabelProvider());
202 fFolderViewer
.addCheckStateListener(new ICheckStateListener() {
204 public void checkStateChanged(CheckStateChangedEvent event
) {
205 Object elem
= event
.getElement();
206 if (elem
instanceof FileSystemElement
) {
207 FileSystemElement element
= (FileSystemElement
) elem
;
208 if (fFolderViewer
.getGrayed(element
)) {
209 fFolderViewer
.setSubtreeChecked(element
, false);
210 fFolderViewer
.setGrayed(element
, false);
211 } else if (event
.getChecked()) {
212 fFolderViewer
.setSubtreeChecked(event
.getElement(), true);
214 fFolderViewer
.setParentsGrayed(element
, true);
215 if (!element
.isDirectory()) {
216 fFolderViewer
.setGrayed(element
, false);
219 updateWidgetEnablements();
226 protected ITreeContentProvider
getFolderProvider() {
231 protected ITreeContentProvider
getFileProvider() {
232 return new WorkbenchContentProvider() {
234 public Object
[] getChildren(Object o
) {
235 if (o
instanceof FileSystemElement
) {
236 FileSystemElement element
= (FileSystemElement
) o
;
237 populateChildren(element
);
238 // For our purpose, we need folders + files
239 Object
[] folders
= element
.getFolders().getChildren();
240 Object
[] files
= element
.getFiles().getChildren();
242 List
<Object
> result
= new LinkedList
<Object
>();
243 for (Object folder
: folders
)
245 for (Object file
: files
)
248 return result
.toArray();
250 return new Object
[0];
255 private void populateChildren(FileSystemElement parent
) {
256 // Do not re-populate if the job was done already...
257 FileSystemStructureProvider provider
= FileSystemStructureProvider
.INSTANCE
;
258 if (parent
.getFolders().size() == 0 && parent
.getFiles().size() == 0) {
259 Object fileSystemObject
= parent
.getFileSystemObject();
260 List
<?
> children
= provider
.getChildren(fileSystemObject
);
261 if (children
!= null) {
262 Iterator
<?
> iterator
= children
.iterator();
263 while (iterator
.hasNext()) {
264 Object child
= iterator
.next();
265 String label
= provider
.getLabel(child
);
266 FileSystemElement element
= new FileSystemElement(label
, parent
, provider
.isFolder(child
));
267 element
.setFileSystemObject(child
);
274 protected List
<FileSystemElement
> getSelectedResources() {
275 List
<FileSystemElement
> resources
= new ArrayList
<FileSystemElement
>();
276 Object
[] checkedItems
= fFolderViewer
.getCheckedElements();
277 for (Object item
: checkedItems
) {
278 if (item
instanceof FileSystemElement
&& !fFolderViewer
.getGrayed(item
)) {
279 resources
.add((FileSystemElement
) item
);
285 // ------------------------------------------------------------------------
286 // Directory Selection Group (forked WizardFileSystemResourceImportPage1)
287 // ------------------------------------------------------------------------
289 protected Combo directoryNameField
;
290 protected Button directoryBrowseButton
;
291 private boolean entryChanged
= false;
293 protected void createDirectorySelectionGroup(Composite parent
) {
295 Composite directoryContainerGroup
= new Composite(parent
, SWT
.NONE
);
296 GridLayout layout
= new GridLayout();
297 layout
.numColumns
= 3;
298 directoryContainerGroup
.setLayout(layout
);
299 directoryContainerGroup
.setFont(parent
.getFont());
300 directoryContainerGroup
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, false));
302 // Label ("Trace directory:")
303 Label groupLabel
= new Label(directoryContainerGroup
, SWT
.NONE
);
304 groupLabel
.setText(Messages
.ImportTraceWizard_DirectoryLocation
);
305 groupLabel
.setFont(parent
.getFont());
307 // Directory name entry field
308 directoryNameField
= new Combo(directoryContainerGroup
, SWT
.BORDER
);
309 GridData data
= new GridData(SWT
.FILL
, SWT
.FILL
, true, false);
310 data
.widthHint
= SIZING_TEXT_FIELD_WIDTH
;
311 directoryNameField
.setLayoutData(data
);
312 directoryNameField
.setFont(parent
.getFont());
314 directoryNameField
.addSelectionListener(new SelectionAdapter() {
316 public void widgetSelected(SelectionEvent e
) {
317 updateFromSourceField();
321 directoryNameField
.addKeyListener(new KeyListener() {
323 public void keyPressed(KeyEvent e
) {
324 // If there has been a key pressed then mark as dirty
326 if (e
.character
== SWT
.CR
) { // Windows...
327 entryChanged
= false;
328 updateFromSourceField();
333 public void keyReleased(KeyEvent e
) {
337 directoryNameField
.addFocusListener(new FocusListener() {
339 public void focusGained(FocusEvent e
) {
340 // Do nothing when getting focus
344 public void focusLost(FocusEvent e
) {
345 // Clear the flag to prevent constant update
347 entryChanged
= false;
348 updateFromSourceField();
354 directoryBrowseButton
= new Button(directoryContainerGroup
, SWT
.PUSH
);
355 directoryBrowseButton
.setText(Messages
.ImportTraceWizard_BrowseButton
);
356 directoryBrowseButton
.addListener(SWT
.Selection
, this);
357 directoryBrowseButton
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, false, false));
358 directoryBrowseButton
.setFont(parent
.getFont());
359 setButtonLayoutData(directoryBrowseButton
);
362 // ------------------------------------------------------------------------
363 // Browse for the source directory
364 // ------------------------------------------------------------------------
367 public void handleEvent(Event event
) {
368 if (event
.widget
== directoryBrowseButton
) {
369 handleSourceDirectoryBrowseButtonPressed();
371 super.handleEvent(event
);
374 protected void handleSourceDirectoryBrowseButtonPressed() {
375 String currentSource
= directoryNameField
.getText();
376 DirectoryDialog dialog
= new DirectoryDialog(directoryNameField
.getShell(), SWT
.SAVE
| SWT
.SHEET
);
377 dialog
.setText(Messages
.ImportTraceWizard_SelectTraceDirectoryTitle
);
378 dialog
.setMessage(Messages
.ImportTraceWizard_SelectTraceDirectoryMessage
);
379 dialog
.setFilterPath(getSourceDirectoryName(currentSource
));
381 String selectedDirectory
= dialog
.open();
382 if (selectedDirectory
!= null) {
383 // Just quit if the directory is not valid
384 if ((getSourceDirectory(selectedDirectory
) == null) || selectedDirectory
.equals(currentSource
)) {
387 // If it is valid then proceed to populate
388 setErrorMessage(null);
389 setSourceName(selectedDirectory
);
393 private File
getSourceDirectory() {
394 return getSourceDirectory(directoryNameField
.getText());
397 private File
getSourceDirectory(String path
) {
398 File sourceDirectory
= new File(getSourceDirectoryName(path
));
399 if (!sourceDirectory
.exists() || !sourceDirectory
.isDirectory()) {
403 return sourceDirectory
;
406 private String
getSourceDirectoryName(String sourceName
) {
407 IPath result
= new Path(sourceName
.trim());
408 if (result
.getDevice() != null && result
.segmentCount() == 0) {
409 result
= result
.addTrailingSeparator();
411 result
= result
.removeTrailingSeparator();
413 return result
.toOSString();
416 private String
getSourceDirectoryName() {
417 return getSourceDirectoryName(directoryNameField
.getText());
420 private void updateFromSourceField() {
421 setSourceName(directoryNameField
.getText());
422 updateWidgetEnablements();
425 private void setSourceName(String path
) {
426 if (path
.length() > 0) {
427 String
[] currentItems
= directoryNameField
.getItems();
428 int selectionIndex
= -1;
429 for (int i
= 0; i
< currentItems
.length
; i
++) {
430 if (currentItems
[i
].equals(path
)) {
434 if (selectionIndex
< 0) {
435 int oldLength
= currentItems
.length
;
436 String
[] newItems
= new String
[oldLength
+ 1];
437 System
.arraycopy(currentItems
, 0, newItems
, 0, oldLength
);
438 newItems
[oldLength
] = path
;
439 directoryNameField
.setItems(newItems
);
440 selectionIndex
= oldLength
;
442 directoryNameField
.select(selectionIndex
);
447 // ------------------------------------------------------------------------
448 // File Selection Group (forked WizardFileSystemResourceImportPage1)
449 // ------------------------------------------------------------------------
451 private void resetSelection() {
452 FileSystemElement root
= getFileSystemTree();
453 populateListViewer(root
);
456 private void populateListViewer(final Object treeElement
) {
457 fFolderViewer
.setInput(treeElement
);
460 private FileSystemElement
getFileSystemTree() {
461 File sourceDirectory
= getSourceDirectory();
462 if (sourceDirectory
== null) {
465 return selectFiles(sourceDirectory
, FileSystemStructureProvider
.INSTANCE
);
468 private FileSystemElement
selectFiles(final Object rootFileSystemObject
,
469 final IImportStructureProvider structureProvider
) {
470 final FileSystemElement
[] results
= new FileSystemElement
[1];
471 BusyIndicator
.showWhile(getShell().getDisplay(), new Runnable() {
474 // Create the root element from the supplied file system object
475 results
[0] = createRootElement(rootFileSystemObject
, structureProvider
);
481 private FileSystemElement
createRootElement(Object fileSystemObject
, IImportStructureProvider provider
) {
483 boolean isContainer
= provider
.isFolder(fileSystemObject
);
484 String elementLabel
= provider
.getLabel(fileSystemObject
);
486 FileSystemElement dummyParent
= new FileSystemElement("", null, true); //$NON-NLS-1$
487 FileSystemElement element
= new FileSystemElement(elementLabel
, dummyParent
, isContainer
);
488 element
.setFileSystemObject(fileSystemObject
);
490 // Get the first level
491 populateChildren(element
);
496 // ------------------------------------------------------------------------
498 // ------------------------------------------------------------------------
500 private Combo fTraceTypes
;
502 private final void createTraceTypeGroup(Composite parent
) {
503 Composite composite
= new Composite(parent
, SWT
.NONE
);
504 GridLayout layout
= new GridLayout();
505 layout
.numColumns
= 3;
506 layout
.makeColumnsEqualWidth
= false;
507 composite
.setLayout(layout
);
508 composite
.setFont(parent
.getFont());
509 GridData buttonData
= new GridData(SWT
.FILL
, SWT
.FILL
, true, false);
510 composite
.setLayoutData(buttonData
);
512 // Trace type label ("Trace Type:")
513 Label typeLabel
= new Label(composite
, SWT
.NONE
);
514 typeLabel
.setText(Messages
.ImportTraceWizard_TraceType
);
515 typeLabel
.setFont(parent
.getFont());
518 fTraceTypes
= new Combo(composite
, SWT
.BORDER
);
519 GridData data
= new GridData(SWT
.FILL
, SWT
.FILL
, true, false, 2, 1);
520 fTraceTypes
.setLayoutData(data
);
521 fTraceTypes
.setFont(parent
.getFont());
523 String
[] availableTraceTypes
= getAvailableTraceTypes();
524 fTraceTypes
.setItems(availableTraceTypes
);
526 fTraceTypes
.addSelectionListener(new SelectionListener() {
528 public void widgetSelected(SelectionEvent e
) {
529 validateSourceGroup();
533 public void widgetDefaultSelected(SelectionEvent e
) {
538 private String
[] getAvailableTraceTypes() {
539 List
<String
> traceTypes
= new ArrayList
<String
>();
540 IConfigurationElement
[] config
= Platform
.getExtensionRegistry().getConfigurationElementsFor(
541 TmfCorePlugin
.TMF_TRACE_TYPE_ID
);
542 for (IConfigurationElement ce
: config
) {
543 String traceTypeName
= ce
.getAttribute("name"); //$NON-NLS-1$
544 fTraceAttributes
.put(traceTypeName
, ce
);
545 traceTypes
.add(traceTypeName
);
547 Collections
.sort(traceTypes
);
549 // TODO: Add Custom Parsers
552 String
[] result
= new String
[traceTypes
.size()];
553 result
= traceTypes
.toArray(result
);
557 // ------------------------------------------------------------------------
559 // ------------------------------------------------------------------------
561 private Button overwriteExistingResourcesCheckbox
;
562 private Button createLinksInWorkspaceButton
;
565 protected void createOptionsGroupButtons(Group optionsGroup
) {
567 // Overwrite checkbox
568 overwriteExistingResourcesCheckbox
= new Button(optionsGroup
, SWT
.CHECK
);
569 overwriteExistingResourcesCheckbox
.setFont(optionsGroup
.getFont());
570 overwriteExistingResourcesCheckbox
.setText(Messages
.ImportTraceWizard_OverwriteExistingTrace
);
571 overwriteExistingResourcesCheckbox
.setSelection(false);
573 // Create links checkbox
574 createLinksInWorkspaceButton
= new Button(optionsGroup
, SWT
.CHECK
);
575 createLinksInWorkspaceButton
.setFont(optionsGroup
.getFont());
576 createLinksInWorkspaceButton
.setText(Messages
.ImportTraceWizard_CreateLinksInWorkspace
);
577 createLinksInWorkspaceButton
.setSelection(true);
579 createLinksInWorkspaceButton
.addSelectionListener(new SelectionAdapter() {
581 public void widgetSelected(SelectionEvent e
) {
582 updateWidgetEnablements();
586 updateWidgetEnablements();
589 // ------------------------------------------------------------------------
590 // Determine if the finish button can be enabled
591 // ------------------------------------------------------------------------
594 public boolean validateSourceGroup() {
596 File sourceDirectory
= getSourceDirectory();
597 if (sourceDirectory
== null) {
598 setMessage(Messages
.ImportTraceWizard_SelectTraceSourceEmpty
);
602 if (sourceConflictsWithDestination(new Path(sourceDirectory
.getPath()))) {
604 setErrorMessage(getSourceConflictMessage());
608 List
<FileSystemElement
> resourcesToImport
= getSelectedResources();
609 if (resourcesToImport
.size() == 0) {
611 setErrorMessage(Messages
.ImportTraceWizard_SelectTraceNoneSelected
);
615 IContainer container
= getSpecifiedContainer();
616 if (container
!= null && container
.isVirtual()) {
617 if (Platform
.getPreferencesService().getBoolean(TmfUiPlugin
.PLUGIN_ID
,
618 ResourcesPlugin
.PREF_DISABLE_LINKING
, false, null)) {
620 setErrorMessage(Messages
.ImportTraceWizard_CannotImportFilesUnderAVirtualFolder
);
623 if (createLinksInWorkspaceButton
== null || createLinksInWorkspaceButton
.getSelection() == false) {
625 setErrorMessage(Messages
.ImportTraceWizard_HaveToCreateLinksUnderAVirtualFolder
);
630 // Perform trace validation
631 String traceTypeName
= fTraceTypes
.getText();
632 if (traceTypeName
!= null && !"".equals(traceTypeName
)) { //$NON-NLS-1$
633 List
<File
> traces
= isolateTraces();
634 for (File trace
: traces
) {
635 IConfigurationElement ce
= fTraceAttributes
.get(traceTypeName
);
636 ITmfTrace
<?
> tmfTrace
= null;
638 tmfTrace
= (ITmfTrace
<?
>) ce
.createExecutableExtension(TmfTraceElement
.TRACE_TYPE
);
639 if (!tmfTrace
.validate(fProject
, trace
.getAbsolutePath())) {
641 setErrorMessage(Messages
.ImportTraceWizard_TraceValidationFailed
);
644 if (tmfTrace
!= null)
646 } catch (CoreException e
) {
648 if (tmfTrace
!= null)
654 setErrorMessage(null);
658 private List
<File
> isolateTraces() {
660 List
<File
> traces
= new ArrayList
<File
>();
663 List
<FileSystemElement
> selectedResources
= getSelectedResources();
664 Iterator
<FileSystemElement
> resources
= selectedResources
.iterator();
666 // Get the sorted list of unique entries
667 Map
<String
, File
> fileSystemObjects
= new HashMap
<String
, File
>();
668 while (resources
.hasNext()) {
669 File resource
= (File
) resources
.next().getFileSystemObject();
670 String key
= resource
.getAbsolutePath();
671 fileSystemObjects
.put(key
, resource
);
673 List
<String
> files
= new ArrayList
<String
>(fileSystemObjects
.keySet());
674 Collections
.sort(files
);
676 // After sorting, traces correspond to the unique prefixes
677 String prefix
= null;
678 for (int i
= 0; i
< files
.size(); i
++) {
679 File file
= fileSystemObjects
.get(files
.get(i
));
680 String name
= file
.getAbsolutePath();
681 if (prefix
== null || !name
.startsWith(prefix
)) {
682 prefix
= name
; // new prefix
690 // ------------------------------------------------------------------------
691 // Import the trace(s)
692 // ------------------------------------------------------------------------
694 public boolean finish() {
695 // Ensure source is valid
696 File sourceDir
= new File(getSourceDirectoryName());
697 if (!sourceDir
.isDirectory()) {
698 setErrorMessage(Messages
.ImportTraceWizard_InvalidTraceDirectory
);
702 String sourceDirPath
;
704 sourceDirPath
= sourceDir
.getCanonicalPath();
705 } catch (IOException e
) {
706 MessageDialog
.openInformation(getContainer().getShell(), Messages
.ImportTraceWizard_Information
,
707 Messages
.ImportTraceWizard_InvalidTraceDirectory
);
711 // Save directory for next import operation
712 fRootDirectory
= getSourceDirectoryName();
714 List
<FileSystemElement
> selectedResources
= getSelectedResources();
715 Iterator
<FileSystemElement
> resources
= selectedResources
.iterator();
717 // Use a map to end up with unique resources (getSelectedResources() can return duplicates)
718 Map
<String
, File
> fileSystemObjects
= new HashMap
<String
, File
>();
719 while (resources
.hasNext()) {
720 File file
= (File
) resources
.next().getFileSystemObject();
721 String key
= file
.getAbsolutePath();
722 fileSystemObjects
.put(key
, file
);
725 if (fileSystemObjects
.size() > 0) {
726 boolean ok
= importResources(sourceDirPath
, fileSystemObjects
);
727 String traceType
= fTraceTypes
.getText();
728 IConfigurationElement ce
= fTraceAttributes
.get(traceType
);
729 if (ok
&& !traceType
.equals("") && ce
!= null) { //$NON-NLS-1$
730 // Tag the selected traces with their type
731 List
<String
> files
= new ArrayList
<String
>(fileSystemObjects
.keySet());
732 Collections
.sort(files
);
733 // After sorting, traces correspond to the unique prefixes
734 String prefix
= null;
735 for (int i
= 0; i
< files
.size(); i
++) {
736 File file
= fileSystemObjects
.get(files
.get(i
));
737 String name
= file
.getAbsolutePath();
738 if (prefix
== null || !name
.startsWith(prefix
)) {
739 prefix
= name
; // new prefix
740 IResource resource
= fTargetFolder
.findMember(file
.getName());
741 if (resource
!= null) {
743 // Set the trace properties for this resource
744 resource
.setPersistentProperty(TmfTraceElement
.TRACEBUNDLE
, ce
.getContributor()
746 resource
.setPersistentProperty(TmfTraceElement
.TRACETYPE
,
747 ce
.getAttribute(TmfTraceElement
.ID
));
748 resource
.setPersistentProperty(TmfTraceElement
.TRACEICON
,
749 ce
.getAttribute(TmfTraceElement
.ICON
));
750 } catch (CoreException e
) {
760 MessageDialog
.openInformation(getContainer().getShell(), Messages
.ImportTraceWizard_Information
,
761 Messages
.ImportTraceWizard_SelectTraceNoneSelected
);
765 private boolean importResources(String rootDirectory
, Map
<String
, File
> fileSystemObjects
) {
767 // Determine the sorted canonical list of items to import
768 List
<File
> fileList
= new ArrayList
<File
>();
769 for (String key
: fileSystemObjects
.keySet()) {
770 fileList
.add(fileSystemObjects
.get(key
));
772 Collections
.sort(fileList
);
774 // Perform a distinct import operation for everything that has the same prefix
775 // (distinct prefixes correspond to traces - we don't want to re-create parent structures)
777 boolean isLinked
= createLinksInWorkspaceButton
.getSelection();
778 for (int i
= 0; i
< fileList
.size(); i
++) {
779 File resource
= fileList
.get(i
);
780 File parentFolder
= new File(resource
.getParent());
782 List
<File
> subList
= new ArrayList
<File
>();
783 subList
.add(resource
);
784 if (resource
.isDirectory()) {
785 String prefix
= resource
.getAbsolutePath();
786 boolean hasSamePrefix
= true;
787 for (int j
= i
; j
< fileList
.size() && hasSamePrefix
; j
++) {
788 File res
= fileList
.get(j
);
789 hasSamePrefix
= res
.getAbsolutePath().startsWith(prefix
);
791 // Import children individually if not linked
800 // Perform the import operation for this subset
801 FileSystemStructureProvider fileSystemStructureProvider
= FileSystemStructureProvider
.INSTANCE
;
802 ImportOperation operation
= new ImportOperation(getContainerFullPath(), parentFolder
,
803 fileSystemStructureProvider
, this, subList
);
804 operation
.setContext(getShell());
805 ok
= executeImportOperation(operation
);
811 private boolean executeImportOperation(ImportOperation op
) {
812 initializeOperation(op
);
815 getContainer().run(true, true, op
);
816 } catch (InterruptedException e
) {
818 } catch (InvocationTargetException e
) {
819 displayErrorDialog(e
.getTargetException());
823 IStatus status
= op
.getStatus();
824 if (!status
.isOK()) {
825 ErrorDialog
.openError(getContainer().getShell(), Messages
.ImportTraceWizard_ImportProblem
, null, status
);
832 private void initializeOperation(ImportOperation op
) {
833 op
.setCreateContainerStructure(false);
834 op
.setOverwriteResources(overwriteExistingResourcesCheckbox
.getSelection());
835 op
.setCreateLinks(createLinksInWorkspaceButton
.getSelection());
836 op
.setVirtualFolders(false);