1 /*******************************************************************************
2 * Copyright (c) 2009, 2013 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 *******************************************************************************/
18 package org
.eclipse
.linuxtools
.tmf
.ui
.project
.wizards
.importtrace
;
21 import java
.io
.IOException
;
22 import java
.lang
.reflect
.InvocationTargetException
;
23 import java
.util
.ArrayList
;
24 import java
.util
.Collections
;
25 import java
.util
.Comparator
;
26 import java
.util
.HashMap
;
27 import java
.util
.Iterator
;
28 import java
.util
.LinkedList
;
29 import java
.util
.List
;
31 import java
.util
.Map
.Entry
;
33 import org
.eclipse
.core
.resources
.IContainer
;
34 import org
.eclipse
.core
.resources
.IFolder
;
35 import org
.eclipse
.core
.resources
.IProject
;
36 import org
.eclipse
.core
.resources
.IResource
;
37 import org
.eclipse
.core
.resources
.ResourcesPlugin
;
38 import org
.eclipse
.core
.runtime
.CoreException
;
39 import org
.eclipse
.core
.runtime
.IConfigurationElement
;
40 import org
.eclipse
.core
.runtime
.IPath
;
41 import org
.eclipse
.core
.runtime
.IStatus
;
42 import org
.eclipse
.core
.runtime
.Path
;
43 import org
.eclipse
.core
.runtime
.Platform
;
44 import org
.eclipse
.jface
.dialogs
.ErrorDialog
;
45 import org
.eclipse
.jface
.dialogs
.MessageDialog
;
46 import org
.eclipse
.jface
.viewers
.CheckStateChangedEvent
;
47 import org
.eclipse
.jface
.viewers
.CheckboxTreeViewer
;
48 import org
.eclipse
.jface
.viewers
.ICheckStateListener
;
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
.internal
.tmf
.ui
.parsers
.custom
.CustomTxtTrace
;
53 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.parsers
.custom
.CustomTxtTraceDefinition
;
54 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.parsers
.custom
.CustomXmlTrace
;
55 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.parsers
.custom
.CustomXmlTraceDefinition
;
56 import org
.eclipse
.linuxtools
.tmf
.core
.TmfCommonConstants
;
57 import org
.eclipse
.linuxtools
.tmf
.core
.TmfProjectNature
;
58 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
.TmfProjectElement
;
59 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
.TmfProjectRegistry
;
60 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
.TmfTraceElement
;
61 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
.TmfTraceFolder
;
62 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
.TmfTraceType
;
63 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.wizards
.Messages
;
64 import org
.eclipse
.swt
.SWT
;
65 import org
.eclipse
.swt
.custom
.BusyIndicator
;
66 import org
.eclipse
.swt
.events
.FocusEvent
;
67 import org
.eclipse
.swt
.events
.FocusListener
;
68 import org
.eclipse
.swt
.events
.KeyEvent
;
69 import org
.eclipse
.swt
.events
.KeyListener
;
70 import org
.eclipse
.swt
.events
.SelectionAdapter
;
71 import org
.eclipse
.swt
.events
.SelectionEvent
;
72 import org
.eclipse
.swt
.events
.SelectionListener
;
73 import org
.eclipse
.swt
.layout
.GridData
;
74 import org
.eclipse
.swt
.layout
.GridLayout
;
75 import org
.eclipse
.swt
.widgets
.Button
;
76 import org
.eclipse
.swt
.widgets
.Combo
;
77 import org
.eclipse
.swt
.widgets
.Composite
;
78 import org
.eclipse
.swt
.widgets
.DirectoryDialog
;
79 import org
.eclipse
.swt
.widgets
.Event
;
80 import org
.eclipse
.swt
.widgets
.Group
;
81 import org
.eclipse
.swt
.widgets
.Label
;
82 import org
.eclipse
.ui
.IWorkbench
;
83 import org
.eclipse
.ui
.dialogs
.FileSystemElement
;
84 import org
.eclipse
.ui
.dialogs
.WizardResourceImportPage
;
85 import org
.eclipse
.ui
.model
.WorkbenchContentProvider
;
86 import org
.eclipse
.ui
.model
.WorkbenchLabelProvider
;
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 with the following changes:
94 * <li>A folder/file combined checkbox tree viewer to select traces
95 * <li>Cherry-picking of traces in the file structure without re-creating the
97 * <li>A trace types dropbox for optional characterization
99 * For our purpose, a trace can either be a single file or a whole directory
100 * sub-tree, whichever is reached first from the root directory.
104 * @author Francois Chouinard
107 public class ImportTraceWizardPage
extends WizardResourceImportPage
{
109 // ------------------------------------------------------------------------
111 // ------------------------------------------------------------------------
113 private static class FileSystemElementComparator
implements Comparator
<Object
> {
115 FileSystemStructureProvider provider
= FileSystemStructureProvider
.INSTANCE
;
118 public int compare(Object o1
, Object o2
) {
119 String label1
= provider
.getLabel(o1
);
120 String label2
= provider
.getLabel(o2
);
121 return label1
.compareTo(label2
);
126 // ------------------------------------------------------------------------
128 // ------------------------------------------------------------------------
130 private static final String IMPORT_WIZARD_PAGE
= "ImportTraceWizardPage"; //$NON-NLS-1$
131 private static final String DEFAULT_TRACE_ICON_PATH
= "icons/elcl16/trace.gif"; //$NON-NLS-1$
132 private static final FileSystemElementComparator FILE_SYSTEM_ELEMENT_COMPARATOR
= new FileSystemElementComparator();
134 // ------------------------------------------------------------------------
136 // ------------------------------------------------------------------------
138 // Folder navigation start point (saved between invocations)
139 private static String fRootDirectory
= null;
141 // Navigation folder content viewer and selector
142 private CheckboxTreeViewer fFolderViewer
;
144 // Target import directory ('Traces' folder)
145 private IFolder fTargetFolder
;
146 private static final String SEPARATOR
= ":"; //$NON-NLS-1$
148 // ------------------------------------------------------------------------
150 // ------------------------------------------------------------------------
153 * Constructor. Creates the trace wizard page.
156 * The name of the page.
158 * The current selection
160 protected ImportTraceWizardPage(String name
, IStructuredSelection selection
) {
161 super(name
, selection
);
168 * The workbench reference.
170 * The current selection
172 public ImportTraceWizardPage(IWorkbench workbench
, IStructuredSelection selection
) {
173 this(IMPORT_WIZARD_PAGE
, selection
);
174 setTitle(Messages
.ImportTraceWizard_FileSystemTitle
);
175 setDescription(Messages
.ImportTraceWizard_ImportTrace
);
177 // Locate the target trace folder
178 IFolder traceFolder
= null;
179 Object element
= selection
.getFirstElement();
181 if (element
instanceof TmfTraceFolder
) {
182 TmfTraceFolder tmfTraceFolder
= (TmfTraceFolder
) element
;
183 tmfTraceFolder
.getProject().getResource();
184 traceFolder
= tmfTraceFolder
.getResource();
185 } else if (element
instanceof IProject
) {
186 IProject project
= (IProject
) element
;
188 if (project
.hasNature(TmfProjectNature
.ID
)) {
189 traceFolder
= (IFolder
) project
.findMember(TmfTraceFolder
.TRACE_FOLDER_NAME
);
191 } catch (CoreException e
) {
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 void createFileSelectionGroup(Composite parent
) {
228 // This Composite is only used for widget alignment purposes
229 Composite composite
= new Composite(parent
, SWT
.NONE
);
230 composite
.setFont(parent
.getFont());
231 GridLayout layout
= new GridLayout();
232 composite
.setLayout(layout
);
233 composite
.setLayoutData(new GridData(GridData
.FILL_BOTH
));
235 final int PREFERRED_LIST_HEIGHT
= 150;
237 fFolderViewer
= new CheckboxTreeViewer(composite
, SWT
.BORDER
);
238 GridData data
= new GridData(GridData
.FILL_BOTH
);
239 data
.heightHint
= PREFERRED_LIST_HEIGHT
;
240 fFolderViewer
.getTree().setLayoutData(data
);
241 fFolderViewer
.getTree().setFont(parent
.getFont());
243 fFolderViewer
.setContentProvider(getFileProvider());
244 fFolderViewer
.setLabelProvider(new WorkbenchLabelProvider());
245 fFolderViewer
.addCheckStateListener(new ICheckStateListener() {
247 public void checkStateChanged(CheckStateChangedEvent event
) {
248 Object elem
= event
.getElement();
249 if (elem
instanceof FileSystemElement
) {
250 FileSystemElement element
= (FileSystemElement
) elem
;
251 if (fFolderViewer
.getGrayed(element
)) {
252 fFolderViewer
.setSubtreeChecked(element
, false);
253 fFolderViewer
.setGrayed(element
, false);
254 } else if (event
.getChecked()) {
255 fFolderViewer
.setSubtreeChecked(event
.getElement(), true);
257 fFolderViewer
.setParentsGrayed(element
, true);
258 if (!element
.isDirectory()) {
259 fFolderViewer
.setGrayed(element
, false);
262 updateWidgetEnablements();
269 protected ITreeContentProvider
getFolderProvider() {
274 protected ITreeContentProvider
getFileProvider() {
275 return new WorkbenchContentProvider() {
277 public Object
[] getChildren(Object o
) {
278 if (o
instanceof FileSystemElement
) {
279 FileSystemElement element
= (FileSystemElement
) o
;
280 populateChildren(element
);
281 // For our purpose, we need folders + files
282 Object
[] folders
= element
.getFolders().getChildren();
283 Object
[] files
= element
.getFiles().getChildren();
285 List
<Object
> result
= new LinkedList
<Object
>();
286 for (Object folder
: folders
) {
289 for (Object file
: files
) {
293 return result
.toArray();
295 return new Object
[0];
300 private static void populateChildren(FileSystemElement parent
) {
301 // Do not re-populate if the job was done already...
302 FileSystemStructureProvider provider
= FileSystemStructureProvider
.INSTANCE
;
303 if (parent
.getFolders().size() == 0 && parent
.getFiles().size() == 0) {
304 Object fileSystemObject
= parent
.getFileSystemObject();
305 List
<?
> children
= provider
.getChildren(fileSystemObject
);
306 if (children
!= null) {
307 Collections
.sort(children
, FILE_SYSTEM_ELEMENT_COMPARATOR
);
308 Iterator
<?
> iterator
= children
.iterator();
309 while (iterator
.hasNext()) {
310 Object child
= iterator
.next();
311 String label
= provider
.getLabel(child
);
312 FileSystemElement element
= new FileSystemElement(label
, parent
, provider
.isFolder(child
));
313 element
.setFileSystemObject(child
);
320 protected List
<FileSystemElement
> getSelectedResources() {
321 List
<FileSystemElement
> resources
= new ArrayList
<FileSystemElement
>();
322 Object
[] checkedItems
= fFolderViewer
.getCheckedElements();
323 for (Object item
: checkedItems
) {
324 if (item
instanceof FileSystemElement
&& !fFolderViewer
.getGrayed(item
)) {
325 resources
.add((FileSystemElement
) item
);
331 // ------------------------------------------------------------------------
332 // Directory Selection Group (forked WizardFileSystemResourceImportPage1)
333 // ------------------------------------------------------------------------
336 * The directory name field
338 protected Combo directoryNameField
;
340 * The directory browse button.
342 protected Button directoryBrowseButton
;
344 private boolean entryChanged
= false;
347 * creates the directory selection group.
350 * the parent composite
352 protected void createDirectorySelectionGroup(Composite parent
) {
354 Composite directoryContainerGroup
= new Composite(parent
, SWT
.NONE
);
355 GridLayout layout
= new GridLayout();
356 layout
.numColumns
= 3;
357 directoryContainerGroup
.setLayout(layout
);
358 directoryContainerGroup
.setFont(parent
.getFont());
359 directoryContainerGroup
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, false));
361 // Label ("Trace directory:")
362 Label groupLabel
= new Label(directoryContainerGroup
, SWT
.NONE
);
363 groupLabel
.setText(Messages
.ImportTraceWizard_DirectoryLocation
);
364 groupLabel
.setFont(parent
.getFont());
366 // Directory name entry field
367 directoryNameField
= new Combo(directoryContainerGroup
, SWT
.BORDER
);
368 GridData data
= new GridData(SWT
.FILL
, SWT
.FILL
, true, false);
369 data
.widthHint
= SIZING_TEXT_FIELD_WIDTH
;
370 directoryNameField
.setLayoutData(data
);
371 directoryNameField
.setFont(parent
.getFont());
373 directoryNameField
.addSelectionListener(new SelectionAdapter() {
375 public void widgetSelected(SelectionEvent e
) {
376 updateFromSourceField();
380 directoryNameField
.addKeyListener(new KeyListener() {
382 public void keyPressed(KeyEvent e
) {
383 // If there has been a key pressed then mark as dirty
385 if (e
.character
== SWT
.CR
) { // Windows...
386 entryChanged
= false;
387 updateFromSourceField();
392 public void keyReleased(KeyEvent e
) {
396 directoryNameField
.addFocusListener(new FocusListener() {
398 public void focusGained(FocusEvent e
) {
399 // Do nothing when getting focus
403 public void focusLost(FocusEvent e
) {
404 // Clear the flag to prevent constant update
406 entryChanged
= false;
407 updateFromSourceField();
413 directoryBrowseButton
= new Button(directoryContainerGroup
, SWT
.PUSH
);
414 directoryBrowseButton
.setText(Messages
.ImportTraceWizard_BrowseButton
);
415 directoryBrowseButton
.addListener(SWT
.Selection
, this);
416 directoryBrowseButton
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, false, false));
417 directoryBrowseButton
.setFont(parent
.getFont());
418 setButtonLayoutData(directoryBrowseButton
);
421 // ------------------------------------------------------------------------
422 // Browse for the source directory
423 // ------------------------------------------------------------------------
426 public void handleEvent(Event event
) {
427 if (event
.widget
== directoryBrowseButton
) {
428 handleSourceDirectoryBrowseButtonPressed();
430 super.handleEvent(event
);
434 * Handle the button pressed event
436 protected void handleSourceDirectoryBrowseButtonPressed() {
437 String currentSource
= directoryNameField
.getText();
438 DirectoryDialog dialog
= new DirectoryDialog(directoryNameField
.getShell(), SWT
.SAVE
| SWT
.SHEET
);
439 dialog
.setText(Messages
.ImportTraceWizard_SelectTraceDirectoryTitle
);
440 dialog
.setMessage(Messages
.ImportTraceWizard_SelectTraceDirectoryMessage
);
441 dialog
.setFilterPath(getSourceDirectoryName(currentSource
));
443 String selectedDirectory
= dialog
.open();
444 if (selectedDirectory
!= null) {
445 // Just quit if the directory is not valid
446 if ((getSourceDirectory(selectedDirectory
) == null) || selectedDirectory
.equals(currentSource
)) {
449 // If it is valid then proceed to populate
450 setErrorMessage(null);
451 setSourceName(selectedDirectory
);
455 private File
getSourceDirectory() {
456 return getSourceDirectory(directoryNameField
.getText());
459 private static File
getSourceDirectory(String path
) {
460 File sourceDirectory
= new File(getSourceDirectoryName(path
));
461 if (!sourceDirectory
.exists() || !sourceDirectory
.isDirectory()) {
465 return sourceDirectory
;
468 private static String
getSourceDirectoryName(String sourceName
) {
469 IPath result
= new Path(sourceName
.trim());
470 if (result
.getDevice() != null && result
.segmentCount() == 0) {
471 result
= result
.addTrailingSeparator();
473 result
= result
.removeTrailingSeparator();
475 return result
.toOSString();
478 private String
getSourceDirectoryName() {
479 return getSourceDirectoryName(directoryNameField
.getText());
482 private void updateFromSourceField() {
483 setSourceName(directoryNameField
.getText());
484 updateWidgetEnablements();
487 private void setSourceName(String path
) {
488 if (path
.length() > 0) {
489 String
[] currentItems
= directoryNameField
.getItems();
490 int selectionIndex
= -1;
491 for (int i
= 0; i
< currentItems
.length
; i
++) {
492 if (currentItems
[i
].equals(path
)) {
496 if (selectionIndex
< 0) {
497 int oldLength
= currentItems
.length
;
498 String
[] newItems
= new String
[oldLength
+ 1];
499 System
.arraycopy(currentItems
, 0, newItems
, 0, oldLength
);
500 newItems
[oldLength
] = path
;
501 directoryNameField
.setItems(newItems
);
502 selectionIndex
= oldLength
;
504 directoryNameField
.select(selectionIndex
);
509 // ------------------------------------------------------------------------
510 // File Selection Group (forked WizardFileSystemResourceImportPage1)
511 // ------------------------------------------------------------------------
513 private void resetSelection() {
514 FileSystemElement root
= getFileSystemTree();
515 populateListViewer(root
);
518 private void populateListViewer(final Object treeElement
) {
519 fFolderViewer
.setInput(treeElement
);
522 private FileSystemElement
getFileSystemTree() {
523 File sourceDirectory
= getSourceDirectory();
524 if (sourceDirectory
== null) {
527 return selectFiles(sourceDirectory
, FileSystemStructureProvider
.INSTANCE
);
530 private FileSystemElement
selectFiles(final Object rootFileSystemObject
, final IImportStructureProvider structureProvider
) {
531 final FileSystemElement
[] results
= new FileSystemElement
[1];
532 BusyIndicator
.showWhile(getShell().getDisplay(), new Runnable() {
535 // Create the root element from the supplied file system object
536 results
[0] = createRootElement(rootFileSystemObject
, structureProvider
);
542 private static FileSystemElement
createRootElement(Object fileSystemObject
,
543 IImportStructureProvider provider
) {
545 boolean isContainer
= provider
.isFolder(fileSystemObject
);
546 String elementLabel
= provider
.getLabel(fileSystemObject
);
548 FileSystemElement dummyParent
= new FileSystemElement("", null, true); //$NON-NLS-1$
549 FileSystemElement element
= new FileSystemElement(elementLabel
, dummyParent
, isContainer
);
550 element
.setFileSystemObject(fileSystemObject
);
552 // Get the first level
553 populateChildren(element
);
558 // ------------------------------------------------------------------------
560 // ------------------------------------------------------------------------
562 private Combo fTraceTypes
;
564 private final void createTraceTypeGroup(Composite parent
) {
565 Composite composite
= new Composite(parent
, SWT
.NONE
);
566 GridLayout layout
= new GridLayout();
567 layout
.numColumns
= 3;
568 layout
.makeColumnsEqualWidth
= false;
569 composite
.setLayout(layout
);
570 composite
.setFont(parent
.getFont());
571 GridData buttonData
= new GridData(SWT
.FILL
, SWT
.FILL
, true, false);
572 composite
.setLayoutData(buttonData
);
574 // Trace type label ("Trace Type:")
575 Label typeLabel
= new Label(composite
, SWT
.NONE
);
576 typeLabel
.setText(Messages
.ImportTraceWizard_TraceType
);
577 typeLabel
.setFont(parent
.getFont());
580 fTraceTypes
= new Combo(composite
, SWT
.BORDER
);
581 GridData data
= new GridData(SWT
.FILL
, SWT
.FILL
, true, false, 2, 1);
582 fTraceTypes
.setLayoutData(data
);
583 fTraceTypes
.setFont(parent
.getFont());
585 String
[] availableTraceTypes
= TmfTraceType
.getInstance().getAvailableTraceTypes();
586 fTraceTypes
.setItems(availableTraceTypes
);
588 fTraceTypes
.addSelectionListener(new SelectionListener() {
590 public void widgetSelected(SelectionEvent e
) {
591 updateWidgetEnablements();
595 public void widgetDefaultSelected(SelectionEvent e
) {
600 // ------------------------------------------------------------------------
602 // ------------------------------------------------------------------------
604 private Button overwriteExistingResourcesCheckbox
;
605 private Button createLinksInWorkspaceButton
;
608 protected void createOptionsGroupButtons(Group optionsGroup
) {
610 // Overwrite checkbox
611 overwriteExistingResourcesCheckbox
= new Button(optionsGroup
, SWT
.CHECK
);
612 overwriteExistingResourcesCheckbox
.setFont(optionsGroup
.getFont());
613 overwriteExistingResourcesCheckbox
.setText(Messages
.ImportTraceWizard_OverwriteExistingTrace
);
614 overwriteExistingResourcesCheckbox
.setSelection(false);
616 // Create links checkbox
617 createLinksInWorkspaceButton
= new Button(optionsGroup
, SWT
.CHECK
);
618 createLinksInWorkspaceButton
.setFont(optionsGroup
.getFont());
619 createLinksInWorkspaceButton
.setText(Messages
.ImportTraceWizard_CreateLinksInWorkspace
);
620 createLinksInWorkspaceButton
.setSelection(true);
622 createLinksInWorkspaceButton
.addSelectionListener(new SelectionAdapter() {
624 public void widgetSelected(SelectionEvent e
) {
625 updateWidgetEnablements();
629 updateWidgetEnablements();
632 // ------------------------------------------------------------------------
633 // Determine if the finish button can be enabled
634 // ------------------------------------------------------------------------
637 public boolean validateSourceGroup() {
639 File sourceDirectory
= getSourceDirectory();
640 if (sourceDirectory
== null) {
641 setMessage(Messages
.ImportTraceWizard_SelectTraceSourceEmpty
);
645 if (sourceConflictsWithDestination(new Path(sourceDirectory
.getPath()))) {
647 setErrorMessage(getSourceConflictMessage());
651 List
<FileSystemElement
> resourcesToImport
= getSelectedResources();
652 if (resourcesToImport
.size() == 0) {
654 setErrorMessage(Messages
.ImportTraceWizard_SelectTraceNoneSelected
);
658 IContainer container
= getSpecifiedContainer();
659 if (container
!= null && container
.isVirtual()) {
660 if (Platform
.getPreferencesService().getBoolean(Activator
.PLUGIN_ID
, ResourcesPlugin
.PREF_DISABLE_LINKING
, false, null)) {
662 setErrorMessage(Messages
.ImportTraceWizard_CannotImportFilesUnderAVirtualFolder
);
665 if (createLinksInWorkspaceButton
== null || !createLinksInWorkspaceButton
.getSelection()) {
667 setErrorMessage(Messages
.ImportTraceWizard_HaveToCreateLinksUnderAVirtualFolder
);
672 // Perform trace validation
673 String traceTypeName
= fTraceTypes
.getText();
674 String tokens
[] = traceTypeName
.split(SEPARATOR
, 2);
675 if (tokens
.length
>= 2) {
676 String id
= TmfTraceType
.getInstance().getTraceTypeId(tokens
[0], tokens
[1]);
677 if (!TmfTraceType
.getInstance().validateTrace(id
, getSelectedResources())) {
679 setErrorMessage(Messages
.ImportTraceWizard_TraceValidationFailed
);
683 setErrorMessage(null);
687 // ------------------------------------------------------------------------
688 // Import the trace(s)
689 // ------------------------------------------------------------------------
694 * @return <code>true</code> if successful else false
696 public boolean finish() {
697 // Ensure source is valid
698 File sourceDir
= new File(getSourceDirectoryName());
699 if (!sourceDir
.isDirectory()) {
700 setErrorMessage(Messages
.ImportTraceWizard_InvalidTraceDirectory
);
705 sourceDir
.getCanonicalPath();
706 } catch (IOException e
) {
707 MessageDialog
.openInformation(getContainer().getShell(), Messages
.ImportTraceWizard_Information
,
708 Messages
.ImportTraceWizard_InvalidTraceDirectory
);
712 // Save directory for next import operation
713 fRootDirectory
= getSourceDirectoryName();
715 List
<FileSystemElement
> selectedResources
= getSelectedResources();
716 Iterator
<FileSystemElement
> resources
= selectedResources
.iterator();
718 // Use a map to end up with unique resources (getSelectedResources() can
719 // return duplicates)
720 Map
<String
, File
> fileSystemObjects
= new HashMap
<String
, File
>();
721 while (resources
.hasNext()) {
722 File file
= (File
) resources
.next().getFileSystemObject();
723 String key
= file
.getAbsolutePath();
724 fileSystemObjects
.put(key
, file
);
727 if (fileSystemObjects
.size() > 0) {
728 boolean ok
= importResources(fileSystemObjects
);
729 String traceBundle
= null;
730 String traceTypeId
= null;
731 String traceIcon
= null;
732 String traceType
= fTraceTypes
.getText();
733 boolean traceTypeOK
= false;
734 if (traceType
.startsWith(TmfTraceType
.CUSTOM_TXT_CATEGORY
)) {
735 for (CustomTxtTraceDefinition def
: CustomTxtTraceDefinition
.loadAll()) {
736 if (traceType
.equals(TmfTraceType
.CUSTOM_TXT_CATEGORY
+ SEPARATOR
+ def
.definitionName
)) {
738 traceBundle
= Activator
.getDefault().getBundle().getSymbolicName();
739 traceTypeId
= CustomTxtTrace
.class.getCanonicalName() + SEPARATOR
+ def
.definitionName
;
740 traceIcon
= DEFAULT_TRACE_ICON_PATH
;
744 } else if (traceType
.startsWith(TmfTraceType
.CUSTOM_XML_CATEGORY
)) {
745 for (CustomXmlTraceDefinition def
: CustomXmlTraceDefinition
.loadAll()) {
746 if (traceType
.equals(TmfTraceType
.CUSTOM_XML_CATEGORY
+ SEPARATOR
+ def
.definitionName
)) {
748 traceBundle
= Activator
.getDefault().getBundle().getSymbolicName();
749 traceTypeId
= CustomXmlTrace
.class.getCanonicalName() + SEPARATOR
+ def
.definitionName
;
750 traceIcon
= DEFAULT_TRACE_ICON_PATH
;
755 if (!traceType
.equals("")) { //$NON-NLS-1$
756 // Trace type was selected
757 String temp
[] = traceType
.split(SEPARATOR
, 2);
758 if (temp
.length
< 2) {
759 Activator
.getDefault().logError("Error with trace type " + traceType
); //$NON-NLS-1$
762 final String traceId
= TmfTraceType
.getInstance().getTraceTypeId(temp
[0], temp
[1]);
763 if (traceId
!= null) {
764 if (!TmfTraceType
.getInstance().validateTrace(traceId
, getSelectedResources())) {
766 setErrorMessage(Messages
.ImportTraceWizard_TraceValidationFailed
);
771 setErrorMessage(Messages
.ImportTraceWizard_TraceValidationFailed
);
774 IConfigurationElement ce
= TmfTraceType
.getInstance().getTraceAttributes(traceId
);
777 traceBundle
= ce
.getContributor().getName();
778 traceTypeId
= ce
.getAttribute(TmfTraceType
.ID_ATTR
);
779 traceIcon
= ce
.getAttribute(TmfTraceType
.ICON_ATTR
);
783 if (ok
&& traceTypeOK
&& !traceType
.equals("")) { //$NON-NLS-1$
784 // Tag the selected traces with their type
785 List
<String
> files
= new ArrayList
<String
>(fileSystemObjects
.keySet());
786 Collections
.sort(files
, new Comparator
<String
>() {
788 public int compare(String o1
, String o2
) {
789 String v1
= o1
+ File
.separatorChar
;
790 String v2
= o2
+ File
.separatorChar
;
791 return v1
.compareTo(v2
);
794 // After sorting, traces correspond to the unique prefixes
795 String prefix
= null;
796 for (int i
= 0; i
< files
.size(); i
++) {
797 File file
= fileSystemObjects
.get(files
.get(i
));
798 String name
= file
.getAbsolutePath() + File
.separatorChar
;
799 if (fTargetFolder
!= null && (prefix
== null || !name
.startsWith(prefix
))) {
800 prefix
= name
; // new prefix
801 IResource resource
= fTargetFolder
.findMember(file
.getName());
802 if (resource
!= null) {
804 // Set the trace properties for this resource
805 resource
.setPersistentProperty(TmfCommonConstants
.TRACEBUNDLE
, traceBundle
);
806 resource
.setPersistentProperty(TmfCommonConstants
.TRACETYPE
, traceTypeId
);
807 resource
.setPersistentProperty(TmfCommonConstants
.TRACEICON
, traceIcon
);
808 TmfProjectElement tmfProject
= TmfProjectRegistry
.getProject(resource
.getProject());
809 if (tmfProject
!= null) {
810 for (TmfTraceElement traceElement
: tmfProject
.getTracesFolder().getTraces()) {
811 if (traceElement
.getName().equals(resource
.getName())) {
812 traceElement
.refreshTraceType();
817 } catch (CoreException e
) {
818 Activator
.getDefault().logError("Error importing trace resource " + resource
.getName(), e
); //$NON-NLS-1$
827 MessageDialog
.openInformation(getContainer().getShell(), Messages
.ImportTraceWizard_Information
,
828 Messages
.ImportTraceWizard_SelectTraceNoneSelected
);
832 private boolean importResources(Map
<String
, File
> fileSystemObjects
) {
834 // Determine the sorted canonical list of items to import
835 List
<File
> fileList
= new ArrayList
<File
>();
836 for (Entry
<String
, File
> entry
: fileSystemObjects
.entrySet()) {
837 fileList
.add(entry
.getValue());
839 Collections
.sort(fileList
, new Comparator
<File
>() {
841 public int compare(File o1
, File o2
) {
842 String v1
= o1
.getAbsolutePath() + File
.separatorChar
;
843 String v2
= o2
.getAbsolutePath() + File
.separatorChar
;
844 return v1
.compareTo(v2
);
848 // Perform a distinct import operation for everything that has the same
850 // (distinct prefixes correspond to traces - we don't want to re-create
851 // parent structures)
853 boolean isLinked
= createLinksInWorkspaceButton
.getSelection();
854 for (int i
= 0; i
< fileList
.size(); i
++) {
855 File resource
= fileList
.get(i
);
856 File parentFolder
= new File(resource
.getParent());
858 List
<File
> subList
= new ArrayList
<File
>();
859 subList
.add(resource
);
860 if (resource
.isDirectory()) {
861 String prefix
= resource
.getAbsolutePath() + File
.separatorChar
;
862 boolean hasSamePrefix
= true;
863 for (int j
= i
+ 1; j
< fileList
.size() && hasSamePrefix
; j
++) {
864 File res
= fileList
.get(j
);
865 hasSamePrefix
= res
.getAbsolutePath().startsWith(prefix
);
867 // Import children individually if not linked
876 // Perform the import operation for this subset
877 FileSystemStructureProvider fileSystemStructureProvider
= FileSystemStructureProvider
.INSTANCE
;
878 ImportOperation operation
= new ImportOperation(getContainerFullPath(), parentFolder
, fileSystemStructureProvider
, this,
880 operation
.setContext(getShell());
881 ok
= executeImportOperation(operation
);
887 private boolean executeImportOperation(ImportOperation op
) {
888 initializeOperation(op
);
891 getContainer().run(true, true, op
);
892 } catch (InterruptedException e
) {
894 } catch (InvocationTargetException e
) {
895 displayErrorDialog(e
.getTargetException());
899 IStatus status
= op
.getStatus();
900 if (!status
.isOK()) {
901 ErrorDialog
.openError(getContainer().getShell(), Messages
.ImportTraceWizard_ImportProblem
, null, status
);
908 private void initializeOperation(ImportOperation op
) {
909 op
.setCreateContainerStructure(false);
910 op
.setOverwriteResources(overwriteExistingResourcesCheckbox
.getSelection());
911 op
.setCreateLinks(createLinksInWorkspaceButton
.getSelection());
912 op
.setVirtualFolders(false);