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 *******************************************************************************/
16 package org
.eclipse
.linuxtools
.tmf
.ui
.project
.wizards
;
19 import java
.io
.IOException
;
20 import java
.lang
.reflect
.InvocationTargetException
;
21 import java
.util
.ArrayList
;
22 import java
.util
.Collections
;
23 import java
.util
.Comparator
;
24 import java
.util
.HashMap
;
25 import java
.util
.Iterator
;
26 import java
.util
.LinkedList
;
27 import java
.util
.List
;
29 import java
.util
.Map
.Entry
;
31 import org
.eclipse
.core
.resources
.IContainer
;
32 import org
.eclipse
.core
.resources
.IFolder
;
33 import org
.eclipse
.core
.resources
.IProject
;
34 import org
.eclipse
.core
.resources
.IResource
;
35 import org
.eclipse
.core
.resources
.ResourcesPlugin
;
36 import org
.eclipse
.core
.runtime
.CoreException
;
37 import org
.eclipse
.core
.runtime
.IConfigurationElement
;
38 import org
.eclipse
.core
.runtime
.IPath
;
39 import org
.eclipse
.core
.runtime
.IStatus
;
40 import org
.eclipse
.core
.runtime
.Path
;
41 import org
.eclipse
.core
.runtime
.Platform
;
42 import org
.eclipse
.jface
.dialogs
.ErrorDialog
;
43 import org
.eclipse
.jface
.dialogs
.MessageDialog
;
44 import org
.eclipse
.jface
.viewers
.CheckStateChangedEvent
;
45 import org
.eclipse
.jface
.viewers
.CheckboxTreeViewer
;
46 import org
.eclipse
.jface
.viewers
.ICheckStateListener
;
47 import org
.eclipse
.jface
.viewers
.IStructuredSelection
;
48 import org
.eclipse
.jface
.viewers
.ITreeContentProvider
;
49 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.Activator
;
50 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.parsers
.custom
.CustomTxtTrace
;
51 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.parsers
.custom
.CustomTxtTraceDefinition
;
52 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.parsers
.custom
.CustomXmlTrace
;
53 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.parsers
.custom
.CustomXmlTraceDefinition
;
54 import org
.eclipse
.linuxtools
.tmf
.core
.TmfCommonConstants
;
55 import org
.eclipse
.linuxtools
.tmf
.core
.TmfProjectNature
;
56 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.ITmfTrace
;
57 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
.TmfProjectElement
;
58 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
.TmfProjectRegistry
;
59 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
.TmfTraceElement
;
60 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
.TmfTraceFolder
;
61 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
.TmfTraceType
;
62 import org
.eclipse
.swt
.SWT
;
63 import org
.eclipse
.swt
.custom
.BusyIndicator
;
64 import org
.eclipse
.swt
.events
.FocusEvent
;
65 import org
.eclipse
.swt
.events
.FocusListener
;
66 import org
.eclipse
.swt
.events
.KeyEvent
;
67 import org
.eclipse
.swt
.events
.KeyListener
;
68 import org
.eclipse
.swt
.events
.SelectionAdapter
;
69 import org
.eclipse
.swt
.events
.SelectionEvent
;
70 import org
.eclipse
.swt
.events
.SelectionListener
;
71 import org
.eclipse
.swt
.layout
.GridData
;
72 import org
.eclipse
.swt
.layout
.GridLayout
;
73 import org
.eclipse
.swt
.widgets
.Button
;
74 import org
.eclipse
.swt
.widgets
.Combo
;
75 import org
.eclipse
.swt
.widgets
.Composite
;
76 import org
.eclipse
.swt
.widgets
.DirectoryDialog
;
77 import org
.eclipse
.swt
.widgets
.Event
;
78 import org
.eclipse
.swt
.widgets
.Group
;
79 import org
.eclipse
.swt
.widgets
.Label
;
80 import org
.eclipse
.ui
.IWorkbench
;
81 import org
.eclipse
.ui
.dialogs
.FileSystemElement
;
82 import org
.eclipse
.ui
.dialogs
.WizardResourceImportPage
;
83 import org
.eclipse
.ui
.model
.WorkbenchContentProvider
;
84 import org
.eclipse
.ui
.model
.WorkbenchLabelProvider
;
85 import org
.eclipse
.ui
.wizards
.datatransfer
.FileSystemStructureProvider
;
86 import org
.eclipse
.ui
.wizards
.datatransfer
.IImportStructureProvider
;
87 import org
.eclipse
.ui
.wizards
.datatransfer
.ImportOperation
;
90 * A variant of the standard resource import wizard with the following changes:
92 * <li>A folder/file combined checkbox tree viewer to select traces
93 * <li>Cherry-picking of traces in the file structure without re-creating the
95 * <li>A trace types dropbox for optional characterization
97 * For our purpose, a trace can either be a single file or a whole directory
98 * sub-tree, whichever is reached first from the root directory.
102 * @author Francois Chouinard
104 public class ImportTraceWizardPage
extends WizardResourceImportPage
{
106 // ------------------------------------------------------------------------
108 // ------------------------------------------------------------------------
110 static private final String IMPORT_WIZARD_PAGE
= "ImportTraceWizardPage"; //$NON-NLS-1$
111 private static final String CUSTOM_TXT_CATEGORY
= "Custom Text"; //$NON-NLS-1$
112 private static final String CUSTOM_XML_CATEGORY
= "Custom XML"; //$NON-NLS-1$
113 private static final String DEFAULT_TRACE_ICON_PATH
= "icons/elcl16/trace.gif"; //$NON-NLS-1$
115 // ------------------------------------------------------------------------
117 // ------------------------------------------------------------------------
119 // Folder navigation start point (saved between invocations)
120 private static String fRootDirectory
= null;
122 // Navigation folder content viewer and selector
123 private CheckboxTreeViewer fFolderViewer
;
125 // Parent tracing project
126 private IProject fProject
;
128 // Target import directory ('Traces' folder)
129 private IFolder fTargetFolder
;
131 // ------------------------------------------------------------------------
133 // ------------------------------------------------------------------------
136 * Constructor. Creates the trace wizard page.
139 * The name of the page.
141 * The current selection
143 protected ImportTraceWizardPage(String name
, IStructuredSelection selection
) {
144 super(name
, selection
);
151 * The workbench reference.
153 * The current selection
155 public ImportTraceWizardPage(IWorkbench workbench
, IStructuredSelection selection
) {
156 this(IMPORT_WIZARD_PAGE
, selection
);
157 setTitle(Messages
.ImportTraceWizard_FileSystemTitle
);
158 setDescription(Messages
.ImportTraceWizard_ImportTrace
);
160 // Locate the target trace folder
161 IFolder traceFolder
= null;
162 Object element
= selection
.getFirstElement();
164 if (element
instanceof TmfTraceFolder
) {
165 TmfTraceFolder tmfTraceFolder
= (TmfTraceFolder
) element
;
166 fProject
= tmfTraceFolder
.getProject().getResource();
167 traceFolder
= tmfTraceFolder
.getResource();
168 } else if (element
instanceof IProject
) {
169 IProject project
= (IProject
) element
;
171 if (project
.hasNature(TmfProjectNature
.ID
)) {
172 traceFolder
= (IFolder
) project
.findMember(TmfTraceFolder
.TRACE_FOLDER_NAME
);
174 } catch (CoreException e
) {
178 // Set the target trace folder
179 if (traceFolder
!= null) {
180 fTargetFolder
= traceFolder
;
181 String path
= traceFolder
.getFullPath().toOSString();
182 setContainerFieldValue(path
);
186 // ------------------------------------------------------------------------
187 // WizardResourceImportPage
188 // ------------------------------------------------------------------------
193 * org.eclipse.ui.dialogs.WizardResourceImportPage#createControl(org.eclipse
194 * .swt.widgets.Composite)
197 public void createControl(Composite parent
) {
198 super.createControl(parent
);
199 // Restore last directory if applicable
200 if (fRootDirectory
!= null) {
201 directoryNameField
.setText(fRootDirectory
);
202 updateFromSourceField();
210 * org.eclipse.ui.dialogs.WizardResourceImportPage#createSourceGroup(org
211 * .eclipse.swt.widgets.Composite)
214 protected void createSourceGroup(Composite parent
) {
215 createDirectorySelectionGroup(parent
);
216 createFileSelectionGroup(parent
);
217 createTraceTypeGroup(parent
);
218 validateSourceGroup();
225 * org.eclipse.ui.dialogs.WizardResourceImportPage#createFileSelectionGroup
226 * (org.eclipse.swt.widgets.Composite)
229 protected void createFileSelectionGroup(Composite parent
) {
231 // This Composite is only used for widget alignment purposes
232 Composite composite
= new Composite(parent
, SWT
.NONE
);
233 composite
.setFont(parent
.getFont());
234 GridLayout layout
= new GridLayout();
235 composite
.setLayout(layout
);
236 composite
.setLayoutData(new GridData(GridData
.FILL_BOTH
));
238 final int PREFERRED_LIST_HEIGHT
= 150;
240 fFolderViewer
= new CheckboxTreeViewer(composite
, SWT
.BORDER
);
241 GridData data
= new GridData(GridData
.FILL_BOTH
);
242 data
.heightHint
= PREFERRED_LIST_HEIGHT
;
243 fFolderViewer
.getTree().setLayoutData(data
);
244 fFolderViewer
.getTree().setFont(parent
.getFont());
246 fFolderViewer
.setContentProvider(getFileProvider());
247 fFolderViewer
.setLabelProvider(new WorkbenchLabelProvider());
248 fFolderViewer
.addCheckStateListener(new ICheckStateListener() {
250 public void checkStateChanged(CheckStateChangedEvent event
) {
251 Object elem
= event
.getElement();
252 if (elem
instanceof FileSystemElement
) {
253 FileSystemElement element
= (FileSystemElement
) elem
;
254 if (fFolderViewer
.getGrayed(element
)) {
255 fFolderViewer
.setSubtreeChecked(element
, false);
256 fFolderViewer
.setGrayed(element
, false);
257 } else if (event
.getChecked()) {
258 fFolderViewer
.setSubtreeChecked(event
.getElement(), true);
260 fFolderViewer
.setParentsGrayed(element
, true);
261 if (!element
.isDirectory()) {
262 fFolderViewer
.setGrayed(element
, false);
265 updateWidgetEnablements();
274 * @see org.eclipse.ui.dialogs.WizardResourceImportPage#getFolderProvider()
277 protected ITreeContentProvider
getFolderProvider() {
284 * @see org.eclipse.ui.dialogs.WizardResourceImportPage#getFileProvider()
287 protected ITreeContentProvider
getFileProvider() {
288 return new WorkbenchContentProvider() {
290 public Object
[] getChildren(Object o
) {
291 if (o
instanceof FileSystemElement
) {
292 FileSystemElement element
= (FileSystemElement
) o
;
293 populateChildren(element
);
294 // For our purpose, we need folders + files
295 Object
[] folders
= element
.getFolders().getChildren();
296 Object
[] files
= element
.getFiles().getChildren();
298 List
<Object
> result
= new LinkedList
<Object
>();
299 for (Object folder
: folders
) {
302 for (Object file
: files
) {
306 return result
.toArray();
308 return new Object
[0];
313 private static void populateChildren(FileSystemElement parent
) {
314 // Do not re-populate if the job was done already...
315 FileSystemStructureProvider provider
= FileSystemStructureProvider
.INSTANCE
;
316 if (parent
.getFolders().size() == 0 && parent
.getFiles().size() == 0) {
317 Object fileSystemObject
= parent
.getFileSystemObject();
318 List
<?
> children
= provider
.getChildren(fileSystemObject
);
319 if (children
!= null) {
320 Iterator
<?
> iterator
= children
.iterator();
321 while (iterator
.hasNext()) {
322 Object child
= iterator
.next();
323 String label
= provider
.getLabel(child
);
324 FileSystemElement element
= new FileSystemElement(label
, parent
, provider
.isFolder(child
));
325 element
.setFileSystemObject(child
);
335 * org.eclipse.ui.dialogs.WizardResourceImportPage#getSelectedResources()
338 protected List
<FileSystemElement
> getSelectedResources() {
339 List
<FileSystemElement
> resources
= new ArrayList
<FileSystemElement
>();
340 Object
[] checkedItems
= fFolderViewer
.getCheckedElements();
341 for (Object item
: checkedItems
) {
342 if (item
instanceof FileSystemElement
&& !fFolderViewer
.getGrayed(item
)) {
343 resources
.add((FileSystemElement
) item
);
349 // ------------------------------------------------------------------------
350 // Directory Selection Group (forked WizardFileSystemResourceImportPage1)
351 // ------------------------------------------------------------------------
354 * The directory name field
356 protected Combo directoryNameField
;
358 * The directory browse button.
360 protected Button directoryBrowseButton
;
361 private boolean entryChanged
= false;
364 * creates the directory selection group.
367 * the parent composite
369 protected void createDirectorySelectionGroup(Composite parent
) {
371 Composite directoryContainerGroup
= new Composite(parent
, SWT
.NONE
);
372 GridLayout layout
= new GridLayout();
373 layout
.numColumns
= 3;
374 directoryContainerGroup
.setLayout(layout
);
375 directoryContainerGroup
.setFont(parent
.getFont());
376 directoryContainerGroup
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, false));
378 // Label ("Trace directory:")
379 Label groupLabel
= new Label(directoryContainerGroup
, SWT
.NONE
);
380 groupLabel
.setText(Messages
.ImportTraceWizard_DirectoryLocation
);
381 groupLabel
.setFont(parent
.getFont());
383 // Directory name entry field
384 directoryNameField
= new Combo(directoryContainerGroup
, SWT
.BORDER
);
385 GridData data
= new GridData(SWT
.FILL
, SWT
.FILL
, true, false);
386 data
.widthHint
= SIZING_TEXT_FIELD_WIDTH
;
387 directoryNameField
.setLayoutData(data
);
388 directoryNameField
.setFont(parent
.getFont());
390 directoryNameField
.addSelectionListener(new SelectionAdapter() {
392 public void widgetSelected(SelectionEvent e
) {
393 updateFromSourceField();
397 directoryNameField
.addKeyListener(new KeyListener() {
399 public void keyPressed(KeyEvent e
) {
400 // If there has been a key pressed then mark as dirty
402 if (e
.character
== SWT
.CR
) { // Windows...
403 entryChanged
= false;
404 updateFromSourceField();
409 public void keyReleased(KeyEvent e
) {
413 directoryNameField
.addFocusListener(new FocusListener() {
415 public void focusGained(FocusEvent e
) {
416 // Do nothing when getting focus
420 public void focusLost(FocusEvent e
) {
421 // Clear the flag to prevent constant update
423 entryChanged
= false;
424 updateFromSourceField();
430 directoryBrowseButton
= new Button(directoryContainerGroup
, SWT
.PUSH
);
431 directoryBrowseButton
.setText(Messages
.ImportTraceWizard_BrowseButton
);
432 directoryBrowseButton
.addListener(SWT
.Selection
, this);
433 directoryBrowseButton
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, false, false));
434 directoryBrowseButton
.setFont(parent
.getFont());
435 setButtonLayoutData(directoryBrowseButton
);
438 // ------------------------------------------------------------------------
439 // Browse for the source directory
440 // ------------------------------------------------------------------------
446 * org.eclipse.ui.dialogs.WizardResourceImportPage#handleEvent(org.eclipse
447 * .swt.widgets.Event)
450 public void handleEvent(Event event
) {
451 if (event
.widget
== directoryBrowseButton
) {
452 handleSourceDirectoryBrowseButtonPressed();
454 super.handleEvent(event
);
458 * Handle the button pressed event
460 protected void handleSourceDirectoryBrowseButtonPressed() {
461 String currentSource
= directoryNameField
.getText();
462 DirectoryDialog dialog
= new DirectoryDialog(directoryNameField
.getShell(), SWT
.SAVE
| SWT
.SHEET
);
463 dialog
.setText(Messages
.ImportTraceWizard_SelectTraceDirectoryTitle
);
464 dialog
.setMessage(Messages
.ImportTraceWizard_SelectTraceDirectoryMessage
);
465 dialog
.setFilterPath(getSourceDirectoryName(currentSource
));
467 String selectedDirectory
= dialog
.open();
468 if (selectedDirectory
!= null) {
469 // Just quit if the directory is not valid
470 if ((getSourceDirectory(selectedDirectory
) == null) || selectedDirectory
.equals(currentSource
)) {
473 // If it is valid then proceed to populate
474 setErrorMessage(null);
475 setSourceName(selectedDirectory
);
479 private File
getSourceDirectory() {
480 return getSourceDirectory(directoryNameField
.getText());
483 private static File
getSourceDirectory(String path
) {
484 File sourceDirectory
= new File(getSourceDirectoryName(path
));
485 if (!sourceDirectory
.exists() || !sourceDirectory
.isDirectory()) {
489 return sourceDirectory
;
492 private static String
getSourceDirectoryName(String sourceName
) {
493 IPath result
= new Path(sourceName
.trim());
494 if (result
.getDevice() != null && result
.segmentCount() == 0) {
495 result
= result
.addTrailingSeparator();
497 result
= result
.removeTrailingSeparator();
499 return result
.toOSString();
502 private String
getSourceDirectoryName() {
503 return getSourceDirectoryName(directoryNameField
.getText());
506 private void updateFromSourceField() {
507 setSourceName(directoryNameField
.getText());
508 updateWidgetEnablements();
511 private void setSourceName(String path
) {
512 if (path
.length() > 0) {
513 String
[] currentItems
= directoryNameField
.getItems();
514 int selectionIndex
= -1;
515 for (int i
= 0; i
< currentItems
.length
; i
++) {
516 if (currentItems
[i
].equals(path
)) {
520 if (selectionIndex
< 0) {
521 int oldLength
= currentItems
.length
;
522 String
[] newItems
= new String
[oldLength
+ 1];
523 System
.arraycopy(currentItems
, 0, newItems
, 0, oldLength
);
524 newItems
[oldLength
] = path
;
525 directoryNameField
.setItems(newItems
);
526 selectionIndex
= oldLength
;
528 directoryNameField
.select(selectionIndex
);
533 // ------------------------------------------------------------------------
534 // File Selection Group (forked WizardFileSystemResourceImportPage1)
535 // ------------------------------------------------------------------------
537 private void resetSelection() {
538 FileSystemElement root
= getFileSystemTree();
539 populateListViewer(root
);
542 private void populateListViewer(final Object treeElement
) {
543 fFolderViewer
.setInput(treeElement
);
546 private FileSystemElement
getFileSystemTree() {
547 File sourceDirectory
= getSourceDirectory();
548 if (sourceDirectory
== null) {
551 return selectFiles(sourceDirectory
, FileSystemStructureProvider
.INSTANCE
);
554 private FileSystemElement
selectFiles(final Object rootFileSystemObject
, final IImportStructureProvider structureProvider
) {
555 final FileSystemElement
[] results
= new FileSystemElement
[1];
556 BusyIndicator
.showWhile(getShell().getDisplay(), new Runnable() {
559 // Create the root element from the supplied file system object
560 results
[0] = createRootElement(rootFileSystemObject
, structureProvider
);
566 private static FileSystemElement
createRootElement(Object fileSystemObject
,
567 IImportStructureProvider provider
) {
569 boolean isContainer
= provider
.isFolder(fileSystemObject
);
570 String elementLabel
= provider
.getLabel(fileSystemObject
);
572 FileSystemElement dummyParent
= new FileSystemElement("", null, true); //$NON-NLS-1$
573 FileSystemElement element
= new FileSystemElement(elementLabel
, dummyParent
, isContainer
);
574 element
.setFileSystemObject(fileSystemObject
);
576 // Get the first level
577 populateChildren(element
);
582 // ------------------------------------------------------------------------
584 // ------------------------------------------------------------------------
586 private Combo fTraceTypes
;
588 private final void createTraceTypeGroup(Composite parent
) {
589 Composite composite
= new Composite(parent
, SWT
.NONE
);
590 GridLayout layout
= new GridLayout();
591 layout
.numColumns
= 3;
592 layout
.makeColumnsEqualWidth
= false;
593 composite
.setLayout(layout
);
594 composite
.setFont(parent
.getFont());
595 GridData buttonData
= new GridData(SWT
.FILL
, SWT
.FILL
, true, false);
596 composite
.setLayoutData(buttonData
);
598 // Trace type label ("Trace Type:")
599 Label typeLabel
= new Label(composite
, SWT
.NONE
);
600 typeLabel
.setText(Messages
.ImportTraceWizard_TraceType
);
601 typeLabel
.setFont(parent
.getFont());
604 fTraceTypes
= new Combo(composite
, SWT
.BORDER
);
605 GridData data
= new GridData(SWT
.FILL
, SWT
.FILL
, true, false, 2, 1);
606 fTraceTypes
.setLayoutData(data
);
607 fTraceTypes
.setFont(parent
.getFont());
609 String
[] availableTraceTypes
= getAvailableTraceTypes();
610 fTraceTypes
.setItems(availableTraceTypes
);
612 fTraceTypes
.addSelectionListener(new SelectionListener() {
614 public void widgetSelected(SelectionEvent e
) {
615 updateWidgetEnablements();
619 public void widgetDefaultSelected(SelectionEvent e
) {
624 // The mapping of available trace type IDs to their corresponding
625 // configuration element
626 private final Map
<String
, IConfigurationElement
> fTraceTypeAttributes
= new HashMap
<String
, IConfigurationElement
>();
627 private final Map
<String
, IConfigurationElement
> fTraceCategories
= new HashMap
<String
, IConfigurationElement
>();
628 private final Map
<String
, IConfigurationElement
> fTraceAttributes
= new HashMap
<String
, IConfigurationElement
>();
630 private String
[] getAvailableTraceTypes() {
632 // Populate the Categories and Trace Types
633 IConfigurationElement
[] config
= Platform
.getExtensionRegistry().getConfigurationElementsFor(TmfTraceType
.TMF_TRACE_TYPE_ID
);
634 for (IConfigurationElement ce
: config
) {
635 String elementName
= ce
.getName();
636 if (elementName
.equals(TmfTraceType
.TYPE_ELEM
)) {
637 String traceTypeId
= ce
.getAttribute(TmfTraceType
.ID_ATTR
);
638 fTraceTypeAttributes
.put(traceTypeId
, ce
);
639 } else if (elementName
.equals(TmfTraceType
.CATEGORY_ELEM
)) {
640 String categoryId
= ce
.getAttribute(TmfTraceType
.ID_ATTR
);
641 fTraceCategories
.put(categoryId
, ce
);
645 // Generate the list of Category:TraceType to populate the ComboBox
646 List
<String
> traceTypes
= new ArrayList
<String
>();
647 for (String typeId
: fTraceTypeAttributes
.keySet()) {
648 IConfigurationElement ce
= fTraceTypeAttributes
.get(typeId
);
649 String traceTypeName
= getCategory(ce
) + " : " + ce
.getAttribute(TmfTraceType
.NAME_ATTR
); //$NON-NLS-1$
650 fTraceAttributes
.put(traceTypeName
, ce
);
651 traceTypes
.add(traceTypeName
);
653 Collections
.sort(traceTypes
);
655 // add the custom trace types
656 for (CustomTxtTraceDefinition def
: CustomTxtTraceDefinition
.loadAll()) {
657 String traceTypeName
= CUSTOM_TXT_CATEGORY
+ " : " + def
.definitionName
; //$NON-NLS-1$
658 traceTypes
.add(traceTypeName
);
660 for (CustomXmlTraceDefinition def
: CustomXmlTraceDefinition
.loadAll()) {
661 String traceTypeName
= CUSTOM_XML_CATEGORY
+ " : " + def
.definitionName
; //$NON-NLS-1$
662 traceTypes
.add(traceTypeName
);
666 return traceTypes
.toArray(new String
[traceTypes
.size()]);
669 private String
getCategory(IConfigurationElement ce
) {
670 String categoryId
= ce
.getAttribute(TmfTraceType
.CATEGORY_ATTR
);
671 if (categoryId
!= null) {
672 IConfigurationElement category
= fTraceCategories
.get(categoryId
);
673 if (category
!= null && !category
.getName().equals("")) { //$NON-NLS-1$
674 return category
.getAttribute(TmfTraceType
.NAME_ATTR
);
677 return "[no category]"; //$NON-NLS-1$
680 // ------------------------------------------------------------------------
682 // ------------------------------------------------------------------------
684 private Button overwriteExistingResourcesCheckbox
;
685 private Button createLinksInWorkspaceButton
;
691 * org.eclipse.ui.dialogs.WizardDataTransferPage#createOptionsGroupButtons
692 * (org.eclipse.swt.widgets.Group)
695 protected void createOptionsGroupButtons(Group optionsGroup
) {
697 // Overwrite checkbox
698 overwriteExistingResourcesCheckbox
= new Button(optionsGroup
, SWT
.CHECK
);
699 overwriteExistingResourcesCheckbox
.setFont(optionsGroup
.getFont());
700 overwriteExistingResourcesCheckbox
.setText(Messages
.ImportTraceWizard_OverwriteExistingTrace
);
701 overwriteExistingResourcesCheckbox
.setSelection(false);
703 // Create links checkbox
704 createLinksInWorkspaceButton
= new Button(optionsGroup
, SWT
.CHECK
);
705 createLinksInWorkspaceButton
.setFont(optionsGroup
.getFont());
706 createLinksInWorkspaceButton
.setText(Messages
.ImportTraceWizard_CreateLinksInWorkspace
);
707 createLinksInWorkspaceButton
.setSelection(true);
709 createLinksInWorkspaceButton
.addSelectionListener(new SelectionAdapter() {
711 public void widgetSelected(SelectionEvent e
) {
712 updateWidgetEnablements();
716 updateWidgetEnablements();
719 // ------------------------------------------------------------------------
720 // Determine if the finish button can be enabled
721 // ------------------------------------------------------------------------
726 * @see org.eclipse.ui.dialogs.WizardDataTransferPage#validateSourceGroup()
729 public boolean validateSourceGroup() {
731 File sourceDirectory
= getSourceDirectory();
732 if (sourceDirectory
== null) {
733 setMessage(Messages
.ImportTraceWizard_SelectTraceSourceEmpty
);
737 if (sourceConflictsWithDestination(new Path(sourceDirectory
.getPath()))) {
739 setErrorMessage(getSourceConflictMessage());
743 List
<FileSystemElement
> resourcesToImport
= getSelectedResources();
744 if (resourcesToImport
.size() == 0) {
746 setErrorMessage(Messages
.ImportTraceWizard_SelectTraceNoneSelected
);
750 IContainer container
= getSpecifiedContainer();
751 if (container
!= null && container
.isVirtual()) {
752 if (Platform
.getPreferencesService().getBoolean(Activator
.PLUGIN_ID
, ResourcesPlugin
.PREF_DISABLE_LINKING
, false, null)) {
754 setErrorMessage(Messages
.ImportTraceWizard_CannotImportFilesUnderAVirtualFolder
);
757 if (createLinksInWorkspaceButton
== null || !createLinksInWorkspaceButton
.getSelection()) {
759 setErrorMessage(Messages
.ImportTraceWizard_HaveToCreateLinksUnderAVirtualFolder
);
764 // Perform trace validation
765 String traceTypeName
= fTraceTypes
.getText();
766 if (traceTypeName
!= null && !"".equals(traceTypeName
) && //$NON-NLS-1$
767 !traceTypeName
.startsWith(CUSTOM_TXT_CATEGORY
) && !traceTypeName
.startsWith(CUSTOM_XML_CATEGORY
)) {
769 List
<File
> traces
= isolateTraces();
770 for (File trace
: traces
) {
771 ITmfTrace tmfTrace
= null;
774 IConfigurationElement ce
= fTraceAttributes
.get(traceTypeName
);
775 tmfTrace
= (ITmfTrace
) ce
.createExecutableExtension(TmfTraceType
.TRACE_TYPE_ATTR
);
776 if (tmfTrace
!= null) {
777 IStatus status
= tmfTrace
.validate(fProject
, trace
.getAbsolutePath());
778 if (!status
.isOK()) {
780 setErrorMessage(Messages
.ImportTraceWizard_TraceValidationFailed
);
785 } catch (CoreException e
) {
787 if (tmfTrace
!= null) {
794 setErrorMessage(null);
798 private List
<File
> isolateTraces() {
800 List
<File
> traces
= new ArrayList
<File
>();
803 List
<FileSystemElement
> selectedResources
= getSelectedResources();
804 Iterator
<FileSystemElement
> resources
= selectedResources
.iterator();
806 // Get the sorted list of unique entries
807 Map
<String
, File
> fileSystemObjects
= new HashMap
<String
, File
>();
808 while (resources
.hasNext()) {
809 File resource
= (File
) resources
.next().getFileSystemObject();
810 String key
= resource
.getAbsolutePath();
811 fileSystemObjects
.put(key
, resource
);
813 List
<String
> files
= new ArrayList
<String
>(fileSystemObjects
.keySet());
814 Collections
.sort(files
);
816 // After sorting, traces correspond to the unique prefixes
817 String prefix
= null;
818 for (int i
= 0; i
< files
.size(); i
++) {
819 File file
= fileSystemObjects
.get(files
.get(i
));
820 String name
= file
.getAbsolutePath();
821 if (prefix
== null || !name
.startsWith(prefix
)) {
822 prefix
= name
; // new prefix
830 // ------------------------------------------------------------------------
831 // Import the trace(s)
832 // ------------------------------------------------------------------------
837 * @return <code>true</code> if successful else false
839 public boolean finish() {
840 // Ensure source is valid
841 File sourceDir
= new File(getSourceDirectoryName());
842 if (!sourceDir
.isDirectory()) {
843 setErrorMessage(Messages
.ImportTraceWizard_InvalidTraceDirectory
);
848 sourceDir
.getCanonicalPath();
849 } catch (IOException e
) {
850 MessageDialog
.openInformation(getContainer().getShell(), Messages
.ImportTraceWizard_Information
,
851 Messages
.ImportTraceWizard_InvalidTraceDirectory
);
855 // Save directory for next import operation
856 fRootDirectory
= getSourceDirectoryName();
858 List
<FileSystemElement
> selectedResources
= getSelectedResources();
859 Iterator
<FileSystemElement
> resources
= selectedResources
.iterator();
861 // Use a map to end up with unique resources (getSelectedResources() can
862 // return duplicates)
863 Map
<String
, File
> fileSystemObjects
= new HashMap
<String
, File
>();
864 while (resources
.hasNext()) {
865 File file
= (File
) resources
.next().getFileSystemObject();
866 String key
= file
.getAbsolutePath();
867 fileSystemObjects
.put(key
, file
);
870 if (fileSystemObjects
.size() > 0) {
871 boolean ok
= importResources(fileSystemObjects
);
872 String traceBundle
= null;
873 String traceTypeId
= null;
874 String traceIcon
= null;
875 String traceType
= fTraceTypes
.getText();
876 boolean traceTypeOK
= false;
877 if (traceType
.startsWith(CUSTOM_TXT_CATEGORY
)) {
878 for (CustomTxtTraceDefinition def
: CustomTxtTraceDefinition
.loadAll()) {
879 if (traceType
.equals(CUSTOM_TXT_CATEGORY
+ " : " + def
.definitionName
)) { //$NON-NLS-1$
881 traceBundle
= Activator
.getDefault().getBundle().getSymbolicName();
882 traceTypeId
= CustomTxtTrace
.class.getCanonicalName() + ":" + def
.definitionName
; //$NON-NLS-1$
883 traceIcon
= DEFAULT_TRACE_ICON_PATH
;
887 } else if (traceType
.startsWith(CUSTOM_XML_CATEGORY
)) {
888 for (CustomXmlTraceDefinition def
: CustomXmlTraceDefinition
.loadAll()) {
889 if (traceType
.equals(CUSTOM_XML_CATEGORY
+ " : " + def
.definitionName
)) { //$NON-NLS-1$
891 traceBundle
= Activator
.getDefault().getBundle().getSymbolicName();
892 traceTypeId
= CustomXmlTrace
.class.getCanonicalName() + ":" + def
.definitionName
; //$NON-NLS-1$
893 traceIcon
= DEFAULT_TRACE_ICON_PATH
;
898 IConfigurationElement ce
= fTraceAttributes
.get(traceType
);
901 traceBundle
= ce
.getContributor().getName();
902 traceTypeId
= ce
.getAttribute(TmfTraceType
.ID_ATTR
);
903 traceIcon
= ce
.getAttribute(TmfTraceType
.ICON_ATTR
);
906 if (ok
&& traceTypeOK
&& !traceType
.equals("")) { //$NON-NLS-1$
907 // Tag the selected traces with their type
908 List
<String
> files
= new ArrayList
<String
>(fileSystemObjects
.keySet());
909 Collections
.sort(files
, new Comparator
<String
>() {
911 public int compare(String o1
, String o2
) {
912 String v1
= o1
+ File
.separatorChar
;
913 String v2
= o2
+ File
.separatorChar
;
914 return v1
.compareTo(v2
);
917 // After sorting, traces correspond to the unique prefixes
918 String prefix
= null;
919 for (int i
= 0; i
< files
.size(); i
++) {
920 File file
= fileSystemObjects
.get(files
.get(i
));
921 String name
= file
.getAbsolutePath() + File
.separatorChar
;
922 if (fTargetFolder
!= null && (prefix
== null || !name
.startsWith(prefix
))) {
923 prefix
= name
; // new prefix
924 IResource resource
= fTargetFolder
.findMember(file
.getName());
925 if (resource
!= null) {
927 // Set the trace properties for this resource
928 resource
.setPersistentProperty(TmfCommonConstants
.TRACEBUNDLE
, traceBundle
);
929 resource
.setPersistentProperty(TmfCommonConstants
.TRACETYPE
, traceTypeId
);
930 resource
.setPersistentProperty(TmfCommonConstants
.TRACEICON
, traceIcon
);
931 TmfProjectElement tmfProject
= TmfProjectRegistry
.getProject(resource
.getProject());
932 if (tmfProject
!= null) {
933 for (TmfTraceElement traceElement
: tmfProject
.getTracesFolder().getTraces()) {
934 if (traceElement
.getName().equals(resource
.getName())) {
935 traceElement
.refreshTraceType();
940 } catch (CoreException e
) {
941 Activator
.getDefault().logError("Error importing trace resource " + resource
.getName(), e
); //$NON-NLS-1$
950 MessageDialog
.openInformation(getContainer().getShell(), Messages
.ImportTraceWizard_Information
,
951 Messages
.ImportTraceWizard_SelectTraceNoneSelected
);
955 private boolean importResources(Map
<String
, File
> fileSystemObjects
) {
957 // Determine the sorted canonical list of items to import
958 List
<File
> fileList
= new ArrayList
<File
>();
959 for (Entry
<String
, File
> entry
: fileSystemObjects
.entrySet()) {
960 fileList
.add(entry
.getValue());
962 Collections
.sort(fileList
, new Comparator
<File
>() {
964 public int compare(File o1
, File o2
) {
965 String v1
= o1
.getAbsolutePath() + File
.separatorChar
;
966 String v2
= o2
.getAbsolutePath() + File
.separatorChar
;
967 return v1
.compareTo(v2
);
971 // Perform a distinct import operation for everything that has the same
973 // (distinct prefixes correspond to traces - we don't want to re-create
974 // parent structures)
976 boolean isLinked
= createLinksInWorkspaceButton
.getSelection();
977 for (int i
= 0; i
< fileList
.size(); i
++) {
978 File resource
= fileList
.get(i
);
979 File parentFolder
= new File(resource
.getParent());
981 List
<File
> subList
= new ArrayList
<File
>();
982 subList
.add(resource
);
983 if (resource
.isDirectory()) {
984 String prefix
= resource
.getAbsolutePath() + File
.separatorChar
;
985 boolean hasSamePrefix
= true;
986 for (int j
= i
+ 1; j
< fileList
.size() && hasSamePrefix
; j
++) {
987 File res
= fileList
.get(j
);
988 hasSamePrefix
= res
.getAbsolutePath().startsWith(prefix
);
990 // Import children individually if not linked
999 // Perform the import operation for this subset
1000 FileSystemStructureProvider fileSystemStructureProvider
= FileSystemStructureProvider
.INSTANCE
;
1001 ImportOperation operation
= new ImportOperation(getContainerFullPath(), parentFolder
, fileSystemStructureProvider
, this,
1003 operation
.setContext(getShell());
1004 ok
= executeImportOperation(operation
);
1010 private boolean executeImportOperation(ImportOperation op
) {
1011 initializeOperation(op
);
1014 getContainer().run(true, true, op
);
1015 } catch (InterruptedException e
) {
1017 } catch (InvocationTargetException e
) {
1018 displayErrorDialog(e
.getTargetException());
1022 IStatus status
= op
.getStatus();
1023 if (!status
.isOK()) {
1024 ErrorDialog
.openError(getContainer().getShell(), Messages
.ImportTraceWizard_ImportProblem
, null, status
);
1031 private void initializeOperation(ImportOperation op
) {
1032 op
.setCreateContainerStructure(false);
1033 op
.setOverwriteResources(overwriteExistingResourcesCheckbox
.getSelection());
1034 op
.setCreateLinks(createLinksInWorkspaceButton
.getSelection());
1035 op
.setVirtualFolders(false);