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
.TmfProjectNature
;
47 import org
.eclipse
.linuxtools
.tmf
.trace
.ITmfTrace
;
48 import org
.eclipse
.linuxtools
.tmf
.ui
.TmfUiPlugin
;
49 import org
.eclipse
.linuxtools
.tmf
.ui
.parsers
.custom
.CustomTxtTrace
;
50 import org
.eclipse
.linuxtools
.tmf
.ui
.parsers
.custom
.CustomTxtTraceDefinition
;
51 import org
.eclipse
.linuxtools
.tmf
.ui
.parsers
.custom
.CustomXmlTrace
;
52 import org
.eclipse
.linuxtools
.tmf
.ui
.parsers
.custom
.CustomXmlTraceDefinition
;
53 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
.TmfTraceElement
;
54 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
.TmfTraceFolder
;
55 import org
.eclipse
.linuxtools
.tmf
.util
.TmfTraceType
;
56 import org
.eclipse
.swt
.SWT
;
57 import org
.eclipse
.swt
.custom
.BusyIndicator
;
58 import org
.eclipse
.swt
.events
.FocusEvent
;
59 import org
.eclipse
.swt
.events
.FocusListener
;
60 import org
.eclipse
.swt
.events
.KeyEvent
;
61 import org
.eclipse
.swt
.events
.KeyListener
;
62 import org
.eclipse
.swt
.events
.SelectionAdapter
;
63 import org
.eclipse
.swt
.events
.SelectionEvent
;
64 import org
.eclipse
.swt
.events
.SelectionListener
;
65 import org
.eclipse
.swt
.layout
.GridData
;
66 import org
.eclipse
.swt
.layout
.GridLayout
;
67 import org
.eclipse
.swt
.widgets
.Button
;
68 import org
.eclipse
.swt
.widgets
.Combo
;
69 import org
.eclipse
.swt
.widgets
.Composite
;
70 import org
.eclipse
.swt
.widgets
.DirectoryDialog
;
71 import org
.eclipse
.swt
.widgets
.Event
;
72 import org
.eclipse
.swt
.widgets
.Group
;
73 import org
.eclipse
.swt
.widgets
.Label
;
74 import org
.eclipse
.swt
.widgets
.Listener
;
75 import org
.eclipse
.ui
.IWorkbench
;
76 import org
.eclipse
.ui
.dialogs
.FileSystemElement
;
77 import org
.eclipse
.ui
.dialogs
.WizardResourceImportPage
;
78 import org
.eclipse
.ui
.model
.WorkbenchContentProvider
;
79 import org
.eclipse
.ui
.model
.WorkbenchLabelProvider
;
80 import org
.eclipse
.ui
.wizards
.datatransfer
.FileSystemStructureProvider
;
81 import org
.eclipse
.ui
.wizards
.datatransfer
.IImportStructureProvider
;
82 import org
.eclipse
.ui
.wizards
.datatransfer
.ImportOperation
;
85 * <b><u>ImportTraceWizardPage</u></b>
87 * A variant of the standard resource import wizard with the following changes:
89 * <li>A folder/file combined checkbox tree viewer to select traces
90 * <li>Cherry-picking of traces in the file structure without re-creating the file hierarchy
91 * <li>A trace types dropbox for optional characterization
93 * For our purpose, a trace can either be a single file or a whole directory sub-tree, whichever is reached first from
96 * TODO: Consider adding Filter/Select/Deselect buttons
98 public class ImportTraceWizardPage
extends WizardResourceImportPage
implements Listener
{
100 // ------------------------------------------------------------------------
102 // ------------------------------------------------------------------------
104 static private final String IMPORT_WIZARD_PAGE
= "ImportTraceWizardPage"; //$NON-NLS-1$
105 private static final String CUSTOM_TXT_CATEGORY
= "Custom Text"; //$NON-NLS-1$
106 private static final String CUSTOM_XML_CATEGORY
= "Custom XML"; //$NON-NLS-1$
107 private static final String DEFAULT_TRACE_ICON_PATH
= "icons/elcl16/trace.gif"; //$NON-NLS-1$
109 // ------------------------------------------------------------------------
111 // ------------------------------------------------------------------------
113 // Folder navigation start point (saved between invocations)
114 private static String fRootDirectory
= null;
116 // Navigation folder content viewer and selector
117 private CheckboxTreeViewer fFolderViewer
;
119 // Parent tracing project
120 private IProject fProject
;
122 // Target import directory ('Traces' folder)
123 private IFolder fTargetFolder
;
125 // ------------------------------------------------------------------------
127 // ------------------------------------------------------------------------
129 protected ImportTraceWizardPage(String name
, IStructuredSelection selection
) {
130 super(name
, selection
);
133 public ImportTraceWizardPage(IWorkbench workbench
, IStructuredSelection selection
) {
134 this(IMPORT_WIZARD_PAGE
, selection
);
135 setTitle(Messages
.ImportTraceWizard_FileSystemTitle
);
136 setDescription(Messages
.ImportTraceWizard_ImportTrace
);
138 // Locate the target trace folder
139 IFolder traceFolder
= null;
140 Object element
= selection
.getFirstElement();
142 if (element
instanceof TmfTraceFolder
) {
143 TmfTraceFolder tmfTraceFolder
= (TmfTraceFolder
) element
;
144 fProject
= tmfTraceFolder
.getProject().getResource();
145 traceFolder
= tmfTraceFolder
.getResource();
146 } else if (element
instanceof IProject
) {
147 IProject project
= (IProject
) element
;
149 if (project
.hasNature(TmfProjectNature
.ID
)) {
150 traceFolder
= (IFolder
) project
.findMember(TmfTraceFolder
.TRACE_FOLDER_NAME
);
152 } catch (CoreException e
) {
156 // Set the target trace folder
157 if (traceFolder
!= null) {
158 fTargetFolder
= traceFolder
;
159 String path
= traceFolder
.getFullPath().toOSString();
160 setContainerFieldValue(path
);
164 // ------------------------------------------------------------------------
165 // WizardResourceImportPage
166 // ------------------------------------------------------------------------
169 public void createControl(Composite parent
) {
170 super.createControl(parent
);
171 // Restore last directory if applicable
172 if (fRootDirectory
!= null) {
173 directoryNameField
.setText(fRootDirectory
);
174 updateFromSourceField();
179 protected void createSourceGroup(Composite parent
) {
180 createDirectorySelectionGroup(parent
);
181 createFileSelectionGroup(parent
);
182 createTraceTypeGroup(parent
);
183 validateSourceGroup();
187 protected void createFileSelectionGroup(Composite parent
) {
189 // This Composite is only used for widget alignment purposes
190 Composite composite
= new Composite(parent
, SWT
.NONE
);
191 composite
.setFont(parent
.getFont());
192 GridLayout layout
= new GridLayout();
193 composite
.setLayout(layout
);
194 composite
.setLayoutData(new GridData(GridData
.FILL_BOTH
));
196 final int PREFERRED_LIST_HEIGHT
= 150;
198 fFolderViewer
= new CheckboxTreeViewer(composite
, SWT
.BORDER
);
199 GridData data
= new GridData(GridData
.FILL_BOTH
);
200 data
.heightHint
= PREFERRED_LIST_HEIGHT
;
201 fFolderViewer
.getTree().setLayoutData(data
);
202 fFolderViewer
.getTree().setFont(parent
.getFont());
204 fFolderViewer
.setContentProvider(getFileProvider());
205 fFolderViewer
.setLabelProvider(new WorkbenchLabelProvider());
206 fFolderViewer
.addCheckStateListener(new ICheckStateListener() {
208 public void checkStateChanged(CheckStateChangedEvent event
) {
209 Object elem
= event
.getElement();
210 if (elem
instanceof FileSystemElement
) {
211 FileSystemElement element
= (FileSystemElement
) elem
;
212 if (fFolderViewer
.getGrayed(element
)) {
213 fFolderViewer
.setSubtreeChecked(element
, false);
214 fFolderViewer
.setGrayed(element
, false);
215 } else if (event
.getChecked()) {
216 fFolderViewer
.setSubtreeChecked(event
.getElement(), true);
218 fFolderViewer
.setParentsGrayed(element
, true);
219 if (!element
.isDirectory()) {
220 fFolderViewer
.setGrayed(element
, false);
223 updateWidgetEnablements();
230 protected ITreeContentProvider
getFolderProvider() {
235 protected ITreeContentProvider
getFileProvider() {
236 return new WorkbenchContentProvider() {
238 public Object
[] getChildren(Object o
) {
239 if (o
instanceof FileSystemElement
) {
240 FileSystemElement element
= (FileSystemElement
) o
;
241 populateChildren(element
);
242 // For our purpose, we need folders + files
243 Object
[] folders
= element
.getFolders().getChildren();
244 Object
[] files
= element
.getFiles().getChildren();
246 List
<Object
> result
= new LinkedList
<Object
>();
247 for (Object folder
: folders
)
249 for (Object file
: files
)
252 return result
.toArray();
254 return new Object
[0];
259 private void populateChildren(FileSystemElement parent
) {
260 // Do not re-populate if the job was done already...
261 FileSystemStructureProvider provider
= FileSystemStructureProvider
.INSTANCE
;
262 if (parent
.getFolders().size() == 0 && parent
.getFiles().size() == 0) {
263 Object fileSystemObject
= parent
.getFileSystemObject();
264 List
<?
> children
= provider
.getChildren(fileSystemObject
);
265 if (children
!= null) {
266 Iterator
<?
> iterator
= children
.iterator();
267 while (iterator
.hasNext()) {
268 Object child
= iterator
.next();
269 String label
= provider
.getLabel(child
);
270 FileSystemElement element
= new FileSystemElement(label
, parent
, provider
.isFolder(child
));
271 element
.setFileSystemObject(child
);
278 protected List
<FileSystemElement
> getSelectedResources() {
279 List
<FileSystemElement
> resources
= new ArrayList
<FileSystemElement
>();
280 Object
[] checkedItems
= fFolderViewer
.getCheckedElements();
281 for (Object item
: checkedItems
) {
282 if (item
instanceof FileSystemElement
&& !fFolderViewer
.getGrayed(item
)) {
283 resources
.add((FileSystemElement
) item
);
289 // ------------------------------------------------------------------------
290 // Directory Selection Group (forked WizardFileSystemResourceImportPage1)
291 // ------------------------------------------------------------------------
293 protected Combo directoryNameField
;
294 protected Button directoryBrowseButton
;
295 private boolean entryChanged
= false;
297 protected void createDirectorySelectionGroup(Composite parent
) {
299 Composite directoryContainerGroup
= new Composite(parent
, SWT
.NONE
);
300 GridLayout layout
= new GridLayout();
301 layout
.numColumns
= 3;
302 directoryContainerGroup
.setLayout(layout
);
303 directoryContainerGroup
.setFont(parent
.getFont());
304 directoryContainerGroup
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, false));
306 // Label ("Trace directory:")
307 Label groupLabel
= new Label(directoryContainerGroup
, SWT
.NONE
);
308 groupLabel
.setText(Messages
.ImportTraceWizard_DirectoryLocation
);
309 groupLabel
.setFont(parent
.getFont());
311 // Directory name entry field
312 directoryNameField
= new Combo(directoryContainerGroup
, SWT
.BORDER
);
313 GridData data
= new GridData(SWT
.FILL
, SWT
.FILL
, true, false);
314 data
.widthHint
= SIZING_TEXT_FIELD_WIDTH
;
315 directoryNameField
.setLayoutData(data
);
316 directoryNameField
.setFont(parent
.getFont());
318 directoryNameField
.addSelectionListener(new SelectionAdapter() {
320 public void widgetSelected(SelectionEvent e
) {
321 updateFromSourceField();
325 directoryNameField
.addKeyListener(new KeyListener() {
327 public void keyPressed(KeyEvent e
) {
328 // If there has been a key pressed then mark as dirty
330 if (e
.character
== SWT
.CR
) { // Windows...
331 entryChanged
= false;
332 updateFromSourceField();
337 public void keyReleased(KeyEvent e
) {
341 directoryNameField
.addFocusListener(new FocusListener() {
343 public void focusGained(FocusEvent e
) {
344 // Do nothing when getting focus
348 public void focusLost(FocusEvent e
) {
349 // Clear the flag to prevent constant update
351 entryChanged
= false;
352 updateFromSourceField();
358 directoryBrowseButton
= new Button(directoryContainerGroup
, SWT
.PUSH
);
359 directoryBrowseButton
.setText(Messages
.ImportTraceWizard_BrowseButton
);
360 directoryBrowseButton
.addListener(SWT
.Selection
, this);
361 directoryBrowseButton
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, false, false));
362 directoryBrowseButton
.setFont(parent
.getFont());
363 setButtonLayoutData(directoryBrowseButton
);
366 // ------------------------------------------------------------------------
367 // Browse for the source directory
368 // ------------------------------------------------------------------------
371 public void handleEvent(Event event
) {
372 if (event
.widget
== directoryBrowseButton
) {
373 handleSourceDirectoryBrowseButtonPressed();
375 super.handleEvent(event
);
378 protected void handleSourceDirectoryBrowseButtonPressed() {
379 String currentSource
= directoryNameField
.getText();
380 DirectoryDialog dialog
= new DirectoryDialog(directoryNameField
.getShell(), SWT
.SAVE
| SWT
.SHEET
);
381 dialog
.setText(Messages
.ImportTraceWizard_SelectTraceDirectoryTitle
);
382 dialog
.setMessage(Messages
.ImportTraceWizard_SelectTraceDirectoryMessage
);
383 dialog
.setFilterPath(getSourceDirectoryName(currentSource
));
385 String selectedDirectory
= dialog
.open();
386 if (selectedDirectory
!= null) {
387 // Just quit if the directory is not valid
388 if ((getSourceDirectory(selectedDirectory
) == null) || selectedDirectory
.equals(currentSource
)) {
391 // If it is valid then proceed to populate
392 setErrorMessage(null);
393 setSourceName(selectedDirectory
);
397 private File
getSourceDirectory() {
398 return getSourceDirectory(directoryNameField
.getText());
401 private File
getSourceDirectory(String path
) {
402 File sourceDirectory
= new File(getSourceDirectoryName(path
));
403 if (!sourceDirectory
.exists() || !sourceDirectory
.isDirectory()) {
407 return sourceDirectory
;
410 private String
getSourceDirectoryName(String sourceName
) {
411 IPath result
= new Path(sourceName
.trim());
412 if (result
.getDevice() != null && result
.segmentCount() == 0) {
413 result
= result
.addTrailingSeparator();
415 result
= result
.removeTrailingSeparator();
417 return result
.toOSString();
420 private String
getSourceDirectoryName() {
421 return getSourceDirectoryName(directoryNameField
.getText());
424 private void updateFromSourceField() {
425 setSourceName(directoryNameField
.getText());
426 updateWidgetEnablements();
429 private void setSourceName(String path
) {
430 if (path
.length() > 0) {
431 String
[] currentItems
= directoryNameField
.getItems();
432 int selectionIndex
= -1;
433 for (int i
= 0; i
< currentItems
.length
; i
++) {
434 if (currentItems
[i
].equals(path
)) {
438 if (selectionIndex
< 0) {
439 int oldLength
= currentItems
.length
;
440 String
[] newItems
= new String
[oldLength
+ 1];
441 System
.arraycopy(currentItems
, 0, newItems
, 0, oldLength
);
442 newItems
[oldLength
] = path
;
443 directoryNameField
.setItems(newItems
);
444 selectionIndex
= oldLength
;
446 directoryNameField
.select(selectionIndex
);
451 // ------------------------------------------------------------------------
452 // File Selection Group (forked WizardFileSystemResourceImportPage1)
453 // ------------------------------------------------------------------------
455 private void resetSelection() {
456 FileSystemElement root
= getFileSystemTree();
457 populateListViewer(root
);
460 private void populateListViewer(final Object treeElement
) {
461 fFolderViewer
.setInput(treeElement
);
464 private FileSystemElement
getFileSystemTree() {
465 File sourceDirectory
= getSourceDirectory();
466 if (sourceDirectory
== null) {
469 return selectFiles(sourceDirectory
, FileSystemStructureProvider
.INSTANCE
);
472 private FileSystemElement
selectFiles(final Object rootFileSystemObject
, final IImportStructureProvider structureProvider
) {
473 final FileSystemElement
[] results
= new FileSystemElement
[1];
474 BusyIndicator
.showWhile(getShell().getDisplay(), new Runnable() {
477 // Create the root element from the supplied file system object
478 results
[0] = createRootElement(rootFileSystemObject
, structureProvider
);
484 private FileSystemElement
createRootElement(Object fileSystemObject
, IImportStructureProvider provider
) {
486 boolean isContainer
= provider
.isFolder(fileSystemObject
);
487 String elementLabel
= provider
.getLabel(fileSystemObject
);
489 FileSystemElement dummyParent
= new FileSystemElement("", null, true); //$NON-NLS-1$
490 FileSystemElement element
= new FileSystemElement(elementLabel
, dummyParent
, isContainer
);
491 element
.setFileSystemObject(fileSystemObject
);
493 // Get the first level
494 populateChildren(element
);
499 // ------------------------------------------------------------------------
501 // ------------------------------------------------------------------------
503 private Combo fTraceTypes
;
505 private final void createTraceTypeGroup(Composite parent
) {
506 Composite composite
= new Composite(parent
, SWT
.NONE
);
507 GridLayout layout
= new GridLayout();
508 layout
.numColumns
= 3;
509 layout
.makeColumnsEqualWidth
= false;
510 composite
.setLayout(layout
);
511 composite
.setFont(parent
.getFont());
512 GridData buttonData
= new GridData(SWT
.FILL
, SWT
.FILL
, true, false);
513 composite
.setLayoutData(buttonData
);
515 // Trace type label ("Trace Type:")
516 Label typeLabel
= new Label(composite
, SWT
.NONE
);
517 typeLabel
.setText(Messages
.ImportTraceWizard_TraceType
);
518 typeLabel
.setFont(parent
.getFont());
521 fTraceTypes
= new Combo(composite
, SWT
.BORDER
);
522 GridData data
= new GridData(SWT
.FILL
, SWT
.FILL
, true, false, 2, 1);
523 fTraceTypes
.setLayoutData(data
);
524 fTraceTypes
.setFont(parent
.getFont());
526 String
[] availableTraceTypes
= getAvailableTraceTypes();
527 fTraceTypes
.setItems(availableTraceTypes
);
529 fTraceTypes
.addSelectionListener(new SelectionListener() {
531 public void widgetSelected(SelectionEvent e
) {
532 validateSourceGroup();
536 public void widgetDefaultSelected(SelectionEvent e
) {
541 // The mapping of available trace type IDs to their corresponding configuration element
542 private Map
<String
, IConfigurationElement
> fTraceTypeAttributes
= new HashMap
<String
, IConfigurationElement
>();
543 private Map
<String
, IConfigurationElement
> fTraceCategories
= new HashMap
<String
, IConfigurationElement
>();
544 private final Map
<String
, IConfigurationElement
> fTraceAttributes
= new HashMap
<String
, IConfigurationElement
>();
546 private String
[] getAvailableTraceTypes() {
548 // Populate the Categories and Trace Types
549 IConfigurationElement
[] config
= Platform
.getExtensionRegistry().getConfigurationElementsFor(TmfTraceType
.TMF_TRACE_TYPE_ID
);
550 for (IConfigurationElement ce
: config
) {
551 String elementName
= ce
.getName();
552 if (elementName
.equals(TmfTraceType
.TYPE_ELEM
)) {
553 String traceTypeId
= ce
.getAttribute(TmfTraceType
.ID_ATTR
);
554 fTraceTypeAttributes
.put(traceTypeId
, ce
);
555 } else if (elementName
.equals(TmfTraceType
.CATEGORY_ELEM
)) {
556 String categoryId
= ce
.getAttribute(TmfTraceType
.ID_ATTR
);
557 fTraceCategories
.put(categoryId
, ce
);
561 // Generate the list of Category:TraceType to populate the ComboBox
562 List
<String
> traceTypes
= new ArrayList
<String
>();
563 for (String typeId
: fTraceTypeAttributes
.keySet()) {
564 IConfigurationElement ce
= fTraceTypeAttributes
.get(typeId
);
565 String traceTypeName
= getCategory(ce
) + " : " + ce
.getAttribute(TmfTraceType
.NAME_ATTR
); //$NON-NLS-1$
566 fTraceAttributes
.put(traceTypeName
, ce
);
567 traceTypes
.add(traceTypeName
);
569 Collections
.sort(traceTypes
);
571 // add the custom trace types
572 for (CustomTxtTraceDefinition def
: CustomTxtTraceDefinition
.loadAll()) {
573 String traceTypeName
= CUSTOM_TXT_CATEGORY
+ " : " + def
.definitionName
; //$NON-NLS-1$
574 traceTypes
.add(traceTypeName
);
576 for (CustomXmlTraceDefinition def
: CustomXmlTraceDefinition
.loadAll()) {
577 String traceTypeName
= CUSTOM_XML_CATEGORY
+ " : " + def
.definitionName
; //$NON-NLS-1$
578 traceTypes
.add(traceTypeName
);
582 return traceTypes
.toArray(new String
[0]);
585 private String
getCategory(IConfigurationElement ce
) {
586 String categoryId
= ce
.getAttribute(TmfTraceType
.CATEGORY_ATTR
);
587 if (categoryId
!= null) {
588 IConfigurationElement category
= fTraceCategories
.get(categoryId
);
589 if (category
!= null && !category
.equals("")) { //$NON-NLS-1$
590 return category
.getAttribute(TmfTraceType
.NAME_ATTR
);
593 return "[no category]"; //$NON-NLS-1$
596 // ------------------------------------------------------------------------
598 // ------------------------------------------------------------------------
600 private Button overwriteExistingResourcesCheckbox
;
601 private Button createLinksInWorkspaceButton
;
604 protected void createOptionsGroupButtons(Group optionsGroup
) {
606 // Overwrite checkbox
607 overwriteExistingResourcesCheckbox
= new Button(optionsGroup
, SWT
.CHECK
);
608 overwriteExistingResourcesCheckbox
.setFont(optionsGroup
.getFont());
609 overwriteExistingResourcesCheckbox
.setText(Messages
.ImportTraceWizard_OverwriteExistingTrace
);
610 overwriteExistingResourcesCheckbox
.setSelection(false);
612 // Create links checkbox
613 createLinksInWorkspaceButton
= new Button(optionsGroup
, SWT
.CHECK
);
614 createLinksInWorkspaceButton
.setFont(optionsGroup
.getFont());
615 createLinksInWorkspaceButton
.setText(Messages
.ImportTraceWizard_CreateLinksInWorkspace
);
616 createLinksInWorkspaceButton
.setSelection(true);
618 createLinksInWorkspaceButton
.addSelectionListener(new SelectionAdapter() {
620 public void widgetSelected(SelectionEvent e
) {
621 updateWidgetEnablements();
625 updateWidgetEnablements();
628 // ------------------------------------------------------------------------
629 // Determine if the finish button can be enabled
630 // ------------------------------------------------------------------------
633 public boolean validateSourceGroup() {
635 File sourceDirectory
= getSourceDirectory();
636 if (sourceDirectory
== null) {
637 setMessage(Messages
.ImportTraceWizard_SelectTraceSourceEmpty
);
641 if (sourceConflictsWithDestination(new Path(sourceDirectory
.getPath()))) {
643 setErrorMessage(getSourceConflictMessage());
647 List
<FileSystemElement
> resourcesToImport
= getSelectedResources();
648 if (resourcesToImport
.size() == 0) {
650 setErrorMessage(Messages
.ImportTraceWizard_SelectTraceNoneSelected
);
654 IContainer container
= getSpecifiedContainer();
655 if (container
!= null && container
.isVirtual()) {
656 if (Platform
.getPreferencesService().getBoolean(TmfUiPlugin
.PLUGIN_ID
, ResourcesPlugin
.PREF_DISABLE_LINKING
, false, null)) {
658 setErrorMessage(Messages
.ImportTraceWizard_CannotImportFilesUnderAVirtualFolder
);
661 if (createLinksInWorkspaceButton
== null || createLinksInWorkspaceButton
.getSelection() == false) {
663 setErrorMessage(Messages
.ImportTraceWizard_HaveToCreateLinksUnderAVirtualFolder
);
668 // Perform trace validation
669 String traceTypeName
= fTraceTypes
.getText();
670 if (traceTypeName
!= null && !"".equals(traceTypeName
) && //$NON-NLS-1$
671 !traceTypeName
.startsWith(CUSTOM_TXT_CATEGORY
) && !traceTypeName
.startsWith(CUSTOM_XML_CATEGORY
)) {
673 List
<File
> traces
= isolateTraces();
674 for (File trace
: traces
) {
675 ITmfTrace
<?
> tmfTrace
= null;
677 IConfigurationElement ce
= fTraceAttributes
.get(traceTypeName
);
678 tmfTrace
= (ITmfTrace
<?
>) ce
.createExecutableExtension(TmfTraceType
.TRACE_TYPE_ATTR
);
679 if (!tmfTrace
.validate(fProject
, trace
.getAbsolutePath())) {
681 setErrorMessage(Messages
.ImportTraceWizard_TraceValidationFailed
);
684 if (tmfTrace
!= null)
686 } catch (CoreException e
) {
688 if (tmfTrace
!= null)
694 setErrorMessage(null);
698 private List
<File
> isolateTraces() {
700 List
<File
> traces
= new ArrayList
<File
>();
703 List
<FileSystemElement
> selectedResources
= getSelectedResources();
704 Iterator
<FileSystemElement
> resources
= selectedResources
.iterator();
706 // Get the sorted list of unique entries
707 Map
<String
, File
> fileSystemObjects
= new HashMap
<String
, File
>();
708 while (resources
.hasNext()) {
709 File resource
= (File
) resources
.next().getFileSystemObject();
710 String key
= resource
.getAbsolutePath();
711 fileSystemObjects
.put(key
, resource
);
713 List
<String
> files
= new ArrayList
<String
>(fileSystemObjects
.keySet());
714 Collections
.sort(files
);
716 // After sorting, traces correspond to the unique prefixes
717 String prefix
= null;
718 for (int i
= 0; i
< files
.size(); i
++) {
719 File file
= fileSystemObjects
.get(files
.get(i
));
720 String name
= file
.getAbsolutePath();
721 if (prefix
== null || !name
.startsWith(prefix
)) {
722 prefix
= name
; // new prefix
730 // ------------------------------------------------------------------------
731 // Import the trace(s)
732 // ------------------------------------------------------------------------
734 public boolean finish() {
735 // Ensure source is valid
736 File sourceDir
= new File(getSourceDirectoryName());
737 if (!sourceDir
.isDirectory()) {
738 setErrorMessage(Messages
.ImportTraceWizard_InvalidTraceDirectory
);
742 String sourceDirPath
;
744 sourceDirPath
= sourceDir
.getCanonicalPath();
745 } catch (IOException e
) {
746 MessageDialog
.openInformation(getContainer().getShell(), Messages
.ImportTraceWizard_Information
,
747 Messages
.ImportTraceWizard_InvalidTraceDirectory
);
751 // Save directory for next import operation
752 fRootDirectory
= getSourceDirectoryName();
754 List
<FileSystemElement
> selectedResources
= getSelectedResources();
755 Iterator
<FileSystemElement
> resources
= selectedResources
.iterator();
757 // Use a map to end up with unique resources (getSelectedResources() can return duplicates)
758 Map
<String
, File
> fileSystemObjects
= new HashMap
<String
, File
>();
759 while (resources
.hasNext()) {
760 File file
= (File
) resources
.next().getFileSystemObject();
761 String key
= file
.getAbsolutePath();
762 fileSystemObjects
.put(key
, file
);
765 if (fileSystemObjects
.size() > 0) {
766 boolean ok
= importResources(sourceDirPath
, fileSystemObjects
);
767 String traceBundle
= null;
768 String traceTypeId
= null;
769 String traceIcon
= null;
770 String traceType
= fTraceTypes
.getText();
771 boolean traceTypeOK
= false;
772 if (traceType
.startsWith(CUSTOM_TXT_CATEGORY
)) {
773 for (CustomTxtTraceDefinition def
: CustomTxtTraceDefinition
.loadAll()) {
774 if (traceType
.equals(CUSTOM_TXT_CATEGORY
+ " : " + def
.definitionName
)) { //$NON-NLS-1$
776 traceBundle
= TmfUiPlugin
.getDefault().getBundle().getSymbolicName();
777 traceTypeId
= CustomTxtTrace
.class.getCanonicalName() + ":" + def
.definitionName
; //$NON-NLS-1$
778 traceIcon
= DEFAULT_TRACE_ICON_PATH
;
782 } else if (traceType
.startsWith(CUSTOM_XML_CATEGORY
)) {
783 for (CustomXmlTraceDefinition def
: CustomXmlTraceDefinition
.loadAll()) {
784 if (traceType
.equals(CUSTOM_XML_CATEGORY
+ " : " + def
.definitionName
)) { //$NON-NLS-1$
786 traceBundle
= TmfUiPlugin
.getDefault().getBundle().getSymbolicName();
787 traceTypeId
= CustomXmlTrace
.class.getCanonicalName() + ":" + def
.definitionName
; //$NON-NLS-1$
788 traceIcon
= DEFAULT_TRACE_ICON_PATH
;
793 IConfigurationElement ce
= fTraceAttributes
.get(traceType
);
796 traceBundle
= ce
.getContributor().getName();
797 traceTypeId
= ce
.getAttribute(TmfTraceType
.ID_ATTR
);
798 traceIcon
= ce
.getAttribute(TmfTraceType
.ICON_ATTR
);
801 if (ok
&& traceTypeOK
&& !traceType
.equals("")) { //$NON-NLS-1$
802 // Tag the selected traces with their type
803 List
<String
> files
= new ArrayList
<String
>(fileSystemObjects
.keySet());
804 Collections
.sort(files
);
805 // After sorting, traces correspond to the unique prefixes
806 String prefix
= null;
807 for (int i
= 0; i
< files
.size(); i
++) {
808 File file
= fileSystemObjects
.get(files
.get(i
));
809 String name
= file
.getAbsolutePath();
810 if (prefix
== null || !name
.startsWith(prefix
)) {
811 prefix
= name
; // new prefix
812 IResource resource
= fTargetFolder
.findMember(file
.getName());
813 if (resource
!= null) {
815 // Set the trace properties for this resource
816 resource
.setPersistentProperty(TmfTraceElement
.TRACEBUNDLE
, traceBundle
);
817 resource
.setPersistentProperty(TmfTraceElement
.TRACETYPE
, traceTypeId
);
818 resource
.setPersistentProperty(TmfTraceElement
.TRACEICON
, traceIcon
);
819 } catch (CoreException e
) {
829 MessageDialog
.openInformation(getContainer().getShell(), Messages
.ImportTraceWizard_Information
,
830 Messages
.ImportTraceWizard_SelectTraceNoneSelected
);
834 private boolean importResources(String rootDirectory
, Map
<String
, File
> fileSystemObjects
) {
836 // Determine the sorted canonical list of items to import
837 List
<File
> fileList
= new ArrayList
<File
>();
838 for (String key
: fileSystemObjects
.keySet()) {
839 fileList
.add(fileSystemObjects
.get(key
));
841 Collections
.sort(fileList
);
843 // Perform a distinct import operation for everything that has the same prefix
844 // (distinct prefixes correspond to traces - we don't want to re-create parent structures)
846 boolean isLinked
= createLinksInWorkspaceButton
.getSelection();
847 for (int i
= 0; i
< fileList
.size(); i
++) {
848 File resource
= fileList
.get(i
);
849 File parentFolder
= new File(resource
.getParent());
851 List
<File
> subList
= new ArrayList
<File
>();
852 subList
.add(resource
);
853 if (resource
.isDirectory()) {
854 String prefix
= resource
.getAbsolutePath();
855 boolean hasSamePrefix
= true;
856 for (int j
= i
; j
< fileList
.size() && hasSamePrefix
; j
++) {
857 File res
= fileList
.get(j
);
858 hasSamePrefix
= res
.getAbsolutePath().startsWith(prefix
);
860 // Import children individually if not linked
869 // Perform the import operation for this subset
870 FileSystemStructureProvider fileSystemStructureProvider
= FileSystemStructureProvider
.INSTANCE
;
871 ImportOperation operation
= new ImportOperation(getContainerFullPath(), parentFolder
, fileSystemStructureProvider
, this,
873 operation
.setContext(getShell());
874 ok
= executeImportOperation(operation
);
880 private boolean executeImportOperation(ImportOperation op
) {
881 initializeOperation(op
);
884 getContainer().run(true, true, op
);
885 } catch (InterruptedException e
) {
887 } catch (InvocationTargetException e
) {
888 displayErrorDialog(e
.getTargetException());
892 IStatus status
= op
.getStatus();
893 if (!status
.isOK()) {
894 ErrorDialog
.openError(getContainer().getShell(), Messages
.ImportTraceWizard_ImportProblem
, null, status
);
901 private void initializeOperation(ImportOperation op
) {
902 op
.setCreateContainerStructure(false);
903 op
.setOverwriteResources(overwriteExistingResourcesCheckbox
.getSelection());
904 op
.setCreateLinks(createLinksInWorkspaceButton
.getSelection());
905 op
.setVirtualFolders(false);