Internalize some more TMF APIs
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / tmf / ui / project / wizards / ImportTraceWizardPage.java
1 /*******************************************************************************
2 * Copyright (c) 2009, 2010, 2011 Ericsson
3 *
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
8 *
9 * Contributors:
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 *******************************************************************************/
14
15 package org.eclipse.linuxtools.tmf.ui.project.wizards;
16
17 import java.io.File;
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;
26 import java.util.Map;
27 import java.util.Map.Entry;
28
29 import org.eclipse.core.resources.IContainer;
30 import org.eclipse.core.resources.IFolder;
31 import org.eclipse.core.resources.IProject;
32 import org.eclipse.core.resources.IResource;
33 import org.eclipse.core.resources.ResourcesPlugin;
34 import org.eclipse.core.runtime.CoreException;
35 import org.eclipse.core.runtime.IConfigurationElement;
36 import org.eclipse.core.runtime.IPath;
37 import org.eclipse.core.runtime.IStatus;
38 import org.eclipse.core.runtime.Path;
39 import org.eclipse.core.runtime.Platform;
40 import org.eclipse.jface.dialogs.ErrorDialog;
41 import org.eclipse.jface.dialogs.MessageDialog;
42 import org.eclipse.jface.viewers.CheckStateChangedEvent;
43 import org.eclipse.jface.viewers.CheckboxTreeViewer;
44 import org.eclipse.jface.viewers.ICheckStateListener;
45 import org.eclipse.jface.viewers.IStructuredSelection;
46 import org.eclipse.jface.viewers.ITreeContentProvider;
47 import org.eclipse.linuxtools.internal.tmf.core.util.TmfTraceType;
48 import org.eclipse.linuxtools.internal.tmf.ui.TmfUiPlugin;
49 import org.eclipse.linuxtools.internal.tmf.ui.parsers.custom.CustomTxtTrace;
50 import org.eclipse.linuxtools.internal.tmf.ui.parsers.custom.CustomTxtTraceDefinition;
51 import org.eclipse.linuxtools.internal.tmf.ui.parsers.custom.CustomXmlTrace;
52 import org.eclipse.linuxtools.internal.tmf.ui.parsers.custom.CustomXmlTraceDefinition;
53 import org.eclipse.linuxtools.tmf.core.TmfProjectNature;
54 import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
55 import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectRegistry;
56 import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement;
57 import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceFolder;
58 import org.eclipse.swt.SWT;
59 import org.eclipse.swt.custom.BusyIndicator;
60 import org.eclipse.swt.events.FocusEvent;
61 import org.eclipse.swt.events.FocusListener;
62 import org.eclipse.swt.events.KeyEvent;
63 import org.eclipse.swt.events.KeyListener;
64 import org.eclipse.swt.events.SelectionAdapter;
65 import org.eclipse.swt.events.SelectionEvent;
66 import org.eclipse.swt.events.SelectionListener;
67 import org.eclipse.swt.layout.GridData;
68 import org.eclipse.swt.layout.GridLayout;
69 import org.eclipse.swt.widgets.Button;
70 import org.eclipse.swt.widgets.Combo;
71 import org.eclipse.swt.widgets.Composite;
72 import org.eclipse.swt.widgets.DirectoryDialog;
73 import org.eclipse.swt.widgets.Event;
74 import org.eclipse.swt.widgets.Group;
75 import org.eclipse.swt.widgets.Label;
76 import org.eclipse.swt.widgets.Listener;
77 import org.eclipse.ui.IWorkbench;
78 import org.eclipse.ui.dialogs.FileSystemElement;
79 import org.eclipse.ui.dialogs.WizardResourceImportPage;
80 import org.eclipse.ui.model.WorkbenchContentProvider;
81 import org.eclipse.ui.model.WorkbenchLabelProvider;
82 import org.eclipse.ui.wizards.datatransfer.FileSystemStructureProvider;
83 import org.eclipse.ui.wizards.datatransfer.IImportStructureProvider;
84 import org.eclipse.ui.wizards.datatransfer.ImportOperation;
85
86 /**
87 * <b><u>ImportTraceWizardPage</u></b>
88 * <p>
89 * A variant of the standard resource import wizard with the following changes:
90 * <ul>
91 * <li>A folder/file combined checkbox tree viewer to select traces
92 * <li>Cherry-picking of traces in the file structure without re-creating the file hierarchy
93 * <li>A trace types dropbox for optional characterization
94 * </ul>
95 * For our purpose, a trace can either be a single file or a whole directory sub-tree, whichever is reached first from
96 * the root directory.
97 * <p>
98 * TODO: Consider adding Filter/Select/Deselect buttons
99 */
100 public class ImportTraceWizardPage extends WizardResourceImportPage implements Listener {
101
102 // ------------------------------------------------------------------------
103 // Constants
104 // ------------------------------------------------------------------------
105
106 static private final String IMPORT_WIZARD_PAGE = "ImportTraceWizardPage"; //$NON-NLS-1$
107 private static final String CUSTOM_TXT_CATEGORY = "Custom Text"; //$NON-NLS-1$
108 private static final String CUSTOM_XML_CATEGORY = "Custom XML"; //$NON-NLS-1$
109 private static final String DEFAULT_TRACE_ICON_PATH = "icons/elcl16/trace.gif"; //$NON-NLS-1$
110
111 // ------------------------------------------------------------------------
112 // Attributes
113 // ------------------------------------------------------------------------
114
115 // Folder navigation start point (saved between invocations)
116 private static String fRootDirectory = null;
117
118 // Navigation folder content viewer and selector
119 private CheckboxTreeViewer fFolderViewer;
120
121 // Parent tracing project
122 private IProject fProject;
123
124 // Target import directory ('Traces' folder)
125 private IFolder fTargetFolder;
126
127 // ------------------------------------------------------------------------
128 // Constructors
129 // ------------------------------------------------------------------------
130
131 protected ImportTraceWizardPage(String name, IStructuredSelection selection) {
132 super(name, selection);
133 }
134
135 public ImportTraceWizardPage(IWorkbench workbench, IStructuredSelection selection) {
136 this(IMPORT_WIZARD_PAGE, selection);
137 setTitle(Messages.ImportTraceWizard_FileSystemTitle);
138 setDescription(Messages.ImportTraceWizard_ImportTrace);
139
140 // Locate the target trace folder
141 IFolder traceFolder = null;
142 Object element = selection.getFirstElement();
143
144 if (element instanceof TmfTraceFolder) {
145 TmfTraceFolder tmfTraceFolder = (TmfTraceFolder) element;
146 fProject = tmfTraceFolder.getProject().getResource();
147 traceFolder = tmfTraceFolder.getResource();
148 } else if (element instanceof IProject) {
149 IProject project = (IProject) element;
150 try {
151 if (project.hasNature(TmfProjectNature.ID)) {
152 traceFolder = (IFolder) project.findMember(TmfTraceFolder.TRACE_FOLDER_NAME);
153 }
154 } catch (CoreException e) {
155 }
156 }
157
158 // Set the target trace folder
159 if (traceFolder != null) {
160 fTargetFolder = traceFolder;
161 String path = traceFolder.getFullPath().toOSString();
162 setContainerFieldValue(path);
163 }
164 }
165
166 // ------------------------------------------------------------------------
167 // WizardResourceImportPage
168 // ------------------------------------------------------------------------
169
170 @Override
171 public void createControl(Composite parent) {
172 super.createControl(parent);
173 // Restore last directory if applicable
174 if (fRootDirectory != null) {
175 directoryNameField.setText(fRootDirectory);
176 updateFromSourceField();
177 }
178 }
179
180 @Override
181 protected void createSourceGroup(Composite parent) {
182 createDirectorySelectionGroup(parent);
183 createFileSelectionGroup(parent);
184 createTraceTypeGroup(parent);
185 validateSourceGroup();
186 }
187
188 @Override
189 protected void createFileSelectionGroup(Composite parent) {
190
191 // This Composite is only used for widget alignment purposes
192 Composite composite = new Composite(parent, SWT.NONE);
193 composite.setFont(parent.getFont());
194 GridLayout layout = new GridLayout();
195 composite.setLayout(layout);
196 composite.setLayoutData(new GridData(GridData.FILL_BOTH));
197
198 final int PREFERRED_LIST_HEIGHT = 150;
199
200 fFolderViewer = new CheckboxTreeViewer(composite, SWT.BORDER);
201 GridData data = new GridData(GridData.FILL_BOTH);
202 data.heightHint = PREFERRED_LIST_HEIGHT;
203 fFolderViewer.getTree().setLayoutData(data);
204 fFolderViewer.getTree().setFont(parent.getFont());
205
206 fFolderViewer.setContentProvider(getFileProvider());
207 fFolderViewer.setLabelProvider(new WorkbenchLabelProvider());
208 fFolderViewer.addCheckStateListener(new ICheckStateListener() {
209 @Override
210 public void checkStateChanged(CheckStateChangedEvent event) {
211 Object elem = event.getElement();
212 if (elem instanceof FileSystemElement) {
213 FileSystemElement element = (FileSystemElement) elem;
214 if (fFolderViewer.getGrayed(element)) {
215 fFolderViewer.setSubtreeChecked(element, false);
216 fFolderViewer.setGrayed(element, false);
217 } else if (event.getChecked()) {
218 fFolderViewer.setSubtreeChecked(event.getElement(), true);
219 } else {
220 fFolderViewer.setParentsGrayed(element, true);
221 if (!element.isDirectory()) {
222 fFolderViewer.setGrayed(element, false);
223 }
224 }
225 updateWidgetEnablements();
226 }
227 }
228 });
229 }
230
231 @Override
232 protected ITreeContentProvider getFolderProvider() {
233 return null;
234 }
235
236 @Override
237 protected ITreeContentProvider getFileProvider() {
238 return new WorkbenchContentProvider() {
239 @Override
240 public Object[] getChildren(Object o) {
241 if (o instanceof FileSystemElement) {
242 FileSystemElement element = (FileSystemElement) o;
243 populateChildren(element);
244 // For our purpose, we need folders + files
245 Object[] folders = element.getFolders().getChildren();
246 Object[] files = element.getFiles().getChildren();
247
248 List<Object> result = new LinkedList<Object>();
249 for (Object folder : folders)
250 result.add(folder);
251 for (Object file : files)
252 result.add(file);
253
254 return result.toArray();
255 }
256 return new Object[0];
257 }
258 };
259 }
260
261 private void populateChildren(FileSystemElement parent) {
262 // Do not re-populate if the job was done already...
263 FileSystemStructureProvider provider = FileSystemStructureProvider.INSTANCE;
264 if (parent.getFolders().size() == 0 && parent.getFiles().size() == 0) {
265 Object fileSystemObject = parent.getFileSystemObject();
266 List<?> children = provider.getChildren(fileSystemObject);
267 if (children != null) {
268 Iterator<?> iterator = children.iterator();
269 while (iterator.hasNext()) {
270 Object child = iterator.next();
271 String label = provider.getLabel(child);
272 FileSystemElement element = new FileSystemElement(label, parent, provider.isFolder(child));
273 element.setFileSystemObject(child);
274 }
275 }
276 }
277 }
278
279 @Override
280 protected List<FileSystemElement> getSelectedResources() {
281 List<FileSystemElement> resources = new ArrayList<FileSystemElement>();
282 Object[] checkedItems = fFolderViewer.getCheckedElements();
283 for (Object item : checkedItems) {
284 if (item instanceof FileSystemElement && !fFolderViewer.getGrayed(item)) {
285 resources.add((FileSystemElement) item);
286 }
287 }
288 return resources;
289 }
290
291 // ------------------------------------------------------------------------
292 // Directory Selection Group (forked WizardFileSystemResourceImportPage1)
293 // ------------------------------------------------------------------------
294
295 protected Combo directoryNameField;
296 protected Button directoryBrowseButton;
297 private boolean entryChanged = false;
298
299 protected void createDirectorySelectionGroup(Composite parent) {
300
301 Composite directoryContainerGroup = new Composite(parent, SWT.NONE);
302 GridLayout layout = new GridLayout();
303 layout.numColumns = 3;
304 directoryContainerGroup.setLayout(layout);
305 directoryContainerGroup.setFont(parent.getFont());
306 directoryContainerGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
307
308 // Label ("Trace directory:")
309 Label groupLabel = new Label(directoryContainerGroup, SWT.NONE);
310 groupLabel.setText(Messages.ImportTraceWizard_DirectoryLocation);
311 groupLabel.setFont(parent.getFont());
312
313 // Directory name entry field
314 directoryNameField = new Combo(directoryContainerGroup, SWT.BORDER);
315 GridData data = new GridData(SWT.FILL, SWT.FILL, true, false);
316 data.widthHint = SIZING_TEXT_FIELD_WIDTH;
317 directoryNameField.setLayoutData(data);
318 directoryNameField.setFont(parent.getFont());
319
320 directoryNameField.addSelectionListener(new SelectionAdapter() {
321 @Override
322 public void widgetSelected(SelectionEvent e) {
323 updateFromSourceField();
324 }
325 });
326
327 directoryNameField.addKeyListener(new KeyListener() {
328 @Override
329 public void keyPressed(KeyEvent e) {
330 // If there has been a key pressed then mark as dirty
331 entryChanged = true;
332 if (e.character == SWT.CR) { // Windows...
333 entryChanged = false;
334 updateFromSourceField();
335 }
336 }
337
338 @Override
339 public void keyReleased(KeyEvent e) {
340 }
341 });
342
343 directoryNameField.addFocusListener(new FocusListener() {
344 @Override
345 public void focusGained(FocusEvent e) {
346 // Do nothing when getting focus
347 }
348
349 @Override
350 public void focusLost(FocusEvent e) {
351 // Clear the flag to prevent constant update
352 if (entryChanged) {
353 entryChanged = false;
354 updateFromSourceField();
355 }
356 }
357 });
358
359 // Browse button
360 directoryBrowseButton = new Button(directoryContainerGroup, SWT.PUSH);
361 directoryBrowseButton.setText(Messages.ImportTraceWizard_BrowseButton);
362 directoryBrowseButton.addListener(SWT.Selection, this);
363 directoryBrowseButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
364 directoryBrowseButton.setFont(parent.getFont());
365 setButtonLayoutData(directoryBrowseButton);
366 }
367
368 // ------------------------------------------------------------------------
369 // Browse for the source directory
370 // ------------------------------------------------------------------------
371
372 @Override
373 public void handleEvent(Event event) {
374 if (event.widget == directoryBrowseButton) {
375 handleSourceDirectoryBrowseButtonPressed();
376 }
377 super.handleEvent(event);
378 }
379
380 protected void handleSourceDirectoryBrowseButtonPressed() {
381 String currentSource = directoryNameField.getText();
382 DirectoryDialog dialog = new DirectoryDialog(directoryNameField.getShell(), SWT.SAVE | SWT.SHEET);
383 dialog.setText(Messages.ImportTraceWizard_SelectTraceDirectoryTitle);
384 dialog.setMessage(Messages.ImportTraceWizard_SelectTraceDirectoryMessage);
385 dialog.setFilterPath(getSourceDirectoryName(currentSource));
386
387 String selectedDirectory = dialog.open();
388 if (selectedDirectory != null) {
389 // Just quit if the directory is not valid
390 if ((getSourceDirectory(selectedDirectory) == null) || selectedDirectory.equals(currentSource)) {
391 return;
392 }
393 // If it is valid then proceed to populate
394 setErrorMessage(null);
395 setSourceName(selectedDirectory);
396 }
397 }
398
399 private File getSourceDirectory() {
400 return getSourceDirectory(directoryNameField.getText());
401 }
402
403 private File getSourceDirectory(String path) {
404 File sourceDirectory = new File(getSourceDirectoryName(path));
405 if (!sourceDirectory.exists() || !sourceDirectory.isDirectory()) {
406 return null;
407 }
408
409 return sourceDirectory;
410 }
411
412 private String getSourceDirectoryName(String sourceName) {
413 IPath result = new Path(sourceName.trim());
414 if (result.getDevice() != null && result.segmentCount() == 0) {
415 result = result.addTrailingSeparator();
416 } else {
417 result = result.removeTrailingSeparator();
418 }
419 return result.toOSString();
420 }
421
422 private String getSourceDirectoryName() {
423 return getSourceDirectoryName(directoryNameField.getText());
424 }
425
426 private void updateFromSourceField() {
427 setSourceName(directoryNameField.getText());
428 updateWidgetEnablements();
429 }
430
431 private void setSourceName(String path) {
432 if (path.length() > 0) {
433 String[] currentItems = directoryNameField.getItems();
434 int selectionIndex = -1;
435 for (int i = 0; i < currentItems.length; i++) {
436 if (currentItems[i].equals(path)) {
437 selectionIndex = i;
438 }
439 }
440 if (selectionIndex < 0) {
441 int oldLength = currentItems.length;
442 String[] newItems = new String[oldLength + 1];
443 System.arraycopy(currentItems, 0, newItems, 0, oldLength);
444 newItems[oldLength] = path;
445 directoryNameField.setItems(newItems);
446 selectionIndex = oldLength;
447 }
448 directoryNameField.select(selectionIndex);
449 }
450 resetSelection();
451 }
452
453 // ------------------------------------------------------------------------
454 // File Selection Group (forked WizardFileSystemResourceImportPage1)
455 // ------------------------------------------------------------------------
456
457 private void resetSelection() {
458 FileSystemElement root = getFileSystemTree();
459 populateListViewer(root);
460 }
461
462 private void populateListViewer(final Object treeElement) {
463 fFolderViewer.setInput(treeElement);
464 }
465
466 private FileSystemElement getFileSystemTree() {
467 File sourceDirectory = getSourceDirectory();
468 if (sourceDirectory == null) {
469 return null;
470 }
471 return selectFiles(sourceDirectory, FileSystemStructureProvider.INSTANCE);
472 }
473
474 private FileSystemElement selectFiles(final Object rootFileSystemObject, final IImportStructureProvider structureProvider) {
475 final FileSystemElement[] results = new FileSystemElement[1];
476 BusyIndicator.showWhile(getShell().getDisplay(), new Runnable() {
477 @Override
478 public void run() {
479 // Create the root element from the supplied file system object
480 results[0] = createRootElement(rootFileSystemObject, structureProvider);
481 }
482 });
483 return results[0];
484 }
485
486 private FileSystemElement createRootElement(Object fileSystemObject, IImportStructureProvider provider) {
487
488 boolean isContainer = provider.isFolder(fileSystemObject);
489 String elementLabel = provider.getLabel(fileSystemObject);
490
491 FileSystemElement dummyParent = new FileSystemElement("", null, true); //$NON-NLS-1$
492 FileSystemElement element = new FileSystemElement(elementLabel, dummyParent, isContainer);
493 element.setFileSystemObject(fileSystemObject);
494
495 // Get the first level
496 populateChildren(element);
497
498 return dummyParent;
499 }
500
501 // ------------------------------------------------------------------------
502 // Trace Type Group
503 // ------------------------------------------------------------------------
504
505 private Combo fTraceTypes;
506
507 private final void createTraceTypeGroup(Composite parent) {
508 Composite composite = new Composite(parent, SWT.NONE);
509 GridLayout layout = new GridLayout();
510 layout.numColumns = 3;
511 layout.makeColumnsEqualWidth = false;
512 composite.setLayout(layout);
513 composite.setFont(parent.getFont());
514 GridData buttonData = new GridData(SWT.FILL, SWT.FILL, true, false);
515 composite.setLayoutData(buttonData);
516
517 // Trace type label ("Trace Type:")
518 Label typeLabel = new Label(composite, SWT.NONE);
519 typeLabel.setText(Messages.ImportTraceWizard_TraceType);
520 typeLabel.setFont(parent.getFont());
521
522 // Trace type combo
523 fTraceTypes = new Combo(composite, SWT.BORDER);
524 GridData data = new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1);
525 fTraceTypes.setLayoutData(data);
526 fTraceTypes.setFont(parent.getFont());
527
528 String[] availableTraceTypes = getAvailableTraceTypes();
529 fTraceTypes.setItems(availableTraceTypes);
530
531 fTraceTypes.addSelectionListener(new SelectionListener() {
532 @Override
533 public void widgetSelected(SelectionEvent e) {
534 validateSourceGroup();
535 }
536
537 @Override
538 public void widgetDefaultSelected(SelectionEvent e) {
539 }
540 });
541 }
542
543 // The mapping of available trace type IDs to their corresponding configuration element
544 private Map<String, IConfigurationElement> fTraceTypeAttributes = new HashMap<String, IConfigurationElement>();
545 private Map<String, IConfigurationElement> fTraceCategories = new HashMap<String, IConfigurationElement>();
546 private final Map<String, IConfigurationElement> fTraceAttributes = new HashMap<String, IConfigurationElement>();
547
548 private String[] getAvailableTraceTypes() {
549
550 // Populate the Categories and Trace Types
551 IConfigurationElement[] config = Platform.getExtensionRegistry().getConfigurationElementsFor(TmfTraceType.TMF_TRACE_TYPE_ID);
552 for (IConfigurationElement ce : config) {
553 String elementName = ce.getName();
554 if (elementName.equals(TmfTraceType.TYPE_ELEM)) {
555 String traceTypeId = ce.getAttribute(TmfTraceType.ID_ATTR);
556 fTraceTypeAttributes.put(traceTypeId, ce);
557 } else if (elementName.equals(TmfTraceType.CATEGORY_ELEM)) {
558 String categoryId = ce.getAttribute(TmfTraceType.ID_ATTR);
559 fTraceCategories.put(categoryId, ce);
560 }
561 }
562
563 // Generate the list of Category:TraceType to populate the ComboBox
564 List<String> traceTypes = new ArrayList<String>();
565 for (String typeId : fTraceTypeAttributes.keySet()) {
566 IConfigurationElement ce = fTraceTypeAttributes.get(typeId);
567 String traceTypeName = getCategory(ce) + " : " + ce.getAttribute(TmfTraceType.NAME_ATTR); //$NON-NLS-1$
568 fTraceAttributes.put(traceTypeName, ce);
569 traceTypes.add(traceTypeName);
570 }
571 Collections.sort(traceTypes);
572
573 // add the custom trace types
574 for (CustomTxtTraceDefinition def : CustomTxtTraceDefinition.loadAll()) {
575 String traceTypeName = CUSTOM_TXT_CATEGORY + " : " + def.definitionName; //$NON-NLS-1$
576 traceTypes.add(traceTypeName);
577 }
578 for (CustomXmlTraceDefinition def : CustomXmlTraceDefinition.loadAll()) {
579 String traceTypeName = CUSTOM_XML_CATEGORY + " : " + def.definitionName; //$NON-NLS-1$
580 traceTypes.add(traceTypeName);
581 }
582
583 // Format result
584 return traceTypes.toArray(new String[traceTypes.size()]);
585 }
586
587 private String getCategory(IConfigurationElement ce) {
588 String categoryId = ce.getAttribute(TmfTraceType.CATEGORY_ATTR);
589 if (categoryId != null) {
590 IConfigurationElement category = fTraceCategories.get(categoryId);
591 if (category != null && !category.getName().equals("")) { //$NON-NLS-1$
592 return category.getAttribute(TmfTraceType.NAME_ATTR);
593 }
594 }
595 return "[no category]"; //$NON-NLS-1$
596 }
597
598 // ------------------------------------------------------------------------
599 // Options
600 // ------------------------------------------------------------------------
601
602 private Button overwriteExistingResourcesCheckbox;
603 private Button createLinksInWorkspaceButton;
604
605 @Override
606 protected void createOptionsGroupButtons(Group optionsGroup) {
607
608 // Overwrite checkbox
609 overwriteExistingResourcesCheckbox = new Button(optionsGroup, SWT.CHECK);
610 overwriteExistingResourcesCheckbox.setFont(optionsGroup.getFont());
611 overwriteExistingResourcesCheckbox.setText(Messages.ImportTraceWizard_OverwriteExistingTrace);
612 overwriteExistingResourcesCheckbox.setSelection(false);
613
614 // Create links checkbox
615 createLinksInWorkspaceButton = new Button(optionsGroup, SWT.CHECK);
616 createLinksInWorkspaceButton.setFont(optionsGroup.getFont());
617 createLinksInWorkspaceButton.setText(Messages.ImportTraceWizard_CreateLinksInWorkspace);
618 createLinksInWorkspaceButton.setSelection(true);
619
620 createLinksInWorkspaceButton.addSelectionListener(new SelectionAdapter() {
621 @Override
622 public void widgetSelected(SelectionEvent e) {
623 updateWidgetEnablements();
624 }
625 });
626
627 updateWidgetEnablements();
628 }
629
630 // ------------------------------------------------------------------------
631 // Determine if the finish button can be enabled
632 // ------------------------------------------------------------------------
633
634 @Override
635 public boolean validateSourceGroup() {
636
637 File sourceDirectory = getSourceDirectory();
638 if (sourceDirectory == null) {
639 setMessage(Messages.ImportTraceWizard_SelectTraceSourceEmpty);
640 return false;
641 }
642
643 if (sourceConflictsWithDestination(new Path(sourceDirectory.getPath()))) {
644 setMessage(null);
645 setErrorMessage(getSourceConflictMessage());
646 return false;
647 }
648
649 List<FileSystemElement> resourcesToImport = getSelectedResources();
650 if (resourcesToImport.size() == 0) {
651 setMessage(null);
652 setErrorMessage(Messages.ImportTraceWizard_SelectTraceNoneSelected);
653 return false;
654 }
655
656 IContainer container = getSpecifiedContainer();
657 if (container != null && container.isVirtual()) {
658 if (Platform.getPreferencesService().getBoolean(TmfUiPlugin.PLUGIN_ID, ResourcesPlugin.PREF_DISABLE_LINKING, false, null)) {
659 setMessage(null);
660 setErrorMessage(Messages.ImportTraceWizard_CannotImportFilesUnderAVirtualFolder);
661 return false;
662 }
663 if (createLinksInWorkspaceButton == null || createLinksInWorkspaceButton.getSelection() == false) {
664 setMessage(null);
665 setErrorMessage(Messages.ImportTraceWizard_HaveToCreateLinksUnderAVirtualFolder);
666 return false;
667 }
668 }
669
670 // Perform trace validation
671 String traceTypeName = fTraceTypes.getText();
672 if (traceTypeName != null && !"".equals(traceTypeName) && //$NON-NLS-1$
673 !traceTypeName.startsWith(CUSTOM_TXT_CATEGORY) && !traceTypeName.startsWith(CUSTOM_XML_CATEGORY)) {
674
675 List<File> traces = isolateTraces();
676 for (File trace : traces) {
677 ITmfTrace<?> tmfTrace = null;
678 try {
679 IConfigurationElement ce = fTraceAttributes.get(traceTypeName);
680 tmfTrace = (ITmfTrace<?>) ce.createExecutableExtension(TmfTraceType.TRACE_TYPE_ATTR);
681 if (tmfTrace != null && !tmfTrace.validate(fProject, trace.getAbsolutePath())) {
682 setMessage(null);
683 setErrorMessage(Messages.ImportTraceWizard_TraceValidationFailed);
684 tmfTrace.dispose();
685 return false;
686 }
687 } catch (CoreException e) {
688 } finally {
689 if (tmfTrace != null)
690 tmfTrace.dispose();
691 }
692 }
693 }
694
695 setErrorMessage(null);
696 return true;
697 }
698
699 private List<File> isolateTraces() {
700
701 List<File> traces = new ArrayList<File>();
702
703 // Get the selection
704 List<FileSystemElement> selectedResources = getSelectedResources();
705 Iterator<FileSystemElement> resources = selectedResources.iterator();
706
707 // Get the sorted list of unique entries
708 Map<String, File> fileSystemObjects = new HashMap<String, File>();
709 while (resources.hasNext()) {
710 File resource = (File) resources.next().getFileSystemObject();
711 String key = resource.getAbsolutePath();
712 fileSystemObjects.put(key, resource);
713 }
714 List<String> files = new ArrayList<String>(fileSystemObjects.keySet());
715 Collections.sort(files);
716
717 // After sorting, traces correspond to the unique prefixes
718 String prefix = null;
719 for (int i = 0; i < files.size(); i++) {
720 File file = fileSystemObjects.get(files.get(i));
721 String name = file.getAbsolutePath();
722 if (prefix == null || !name.startsWith(prefix)) {
723 prefix = name; // new prefix
724 traces.add(file);
725 }
726 }
727
728 return traces;
729 }
730
731 // ------------------------------------------------------------------------
732 // Import the trace(s)
733 // ------------------------------------------------------------------------
734
735 public boolean finish() {
736 // Ensure source is valid
737 File sourceDir = new File(getSourceDirectoryName());
738 if (!sourceDir.isDirectory()) {
739 setErrorMessage(Messages.ImportTraceWizard_InvalidTraceDirectory);
740 return false;
741 }
742
743 String sourceDirPath;
744 try {
745 sourceDirPath = sourceDir.getCanonicalPath();
746 } catch (IOException e) {
747 MessageDialog.openInformation(getContainer().getShell(), Messages.ImportTraceWizard_Information,
748 Messages.ImportTraceWizard_InvalidTraceDirectory);
749 return false;
750 }
751
752 // Save directory for next import operation
753 fRootDirectory = getSourceDirectoryName();
754
755 List<FileSystemElement> selectedResources = getSelectedResources();
756 Iterator<FileSystemElement> resources = selectedResources.iterator();
757
758 // Use a map to end up with unique resources (getSelectedResources() can return duplicates)
759 Map<String, File> fileSystemObjects = new HashMap<String, File>();
760 while (resources.hasNext()) {
761 File file = (File) resources.next().getFileSystemObject();
762 String key = file.getAbsolutePath();
763 fileSystemObjects.put(key, file);
764 }
765
766 if (fileSystemObjects.size() > 0) {
767 boolean ok = importResources(sourceDirPath, fileSystemObjects);
768 String traceBundle = null;
769 String traceTypeId = null;
770 String traceIcon = null;
771 String traceType = fTraceTypes.getText();
772 boolean traceTypeOK = false;
773 if (traceType.startsWith(CUSTOM_TXT_CATEGORY)) {
774 for (CustomTxtTraceDefinition def : CustomTxtTraceDefinition.loadAll()) {
775 if (traceType.equals(CUSTOM_TXT_CATEGORY + " : " + def.definitionName)) { //$NON-NLS-1$
776 traceTypeOK = true;
777 traceBundle = TmfUiPlugin.getDefault().getBundle().getSymbolicName();
778 traceTypeId = CustomTxtTrace.class.getCanonicalName() + ":" + def.definitionName; //$NON-NLS-1$
779 traceIcon = DEFAULT_TRACE_ICON_PATH;
780 break;
781 }
782 }
783 } else if (traceType.startsWith(CUSTOM_XML_CATEGORY)) {
784 for (CustomXmlTraceDefinition def : CustomXmlTraceDefinition.loadAll()) {
785 if (traceType.equals(CUSTOM_XML_CATEGORY + " : " + def.definitionName)) { //$NON-NLS-1$
786 traceTypeOK = true;
787 traceBundle = TmfUiPlugin.getDefault().getBundle().getSymbolicName();
788 traceTypeId = CustomXmlTrace.class.getCanonicalName() + ":" + def.definitionName; //$NON-NLS-1$
789 traceIcon = DEFAULT_TRACE_ICON_PATH;
790 break;
791 }
792 }
793 } else {
794 IConfigurationElement ce = fTraceAttributes.get(traceType);
795 if (ce != null) {
796 traceTypeOK = true;
797 traceBundle = ce.getContributor().getName();
798 traceTypeId = ce.getAttribute(TmfTraceType.ID_ATTR);
799 traceIcon = ce.getAttribute(TmfTraceType.ICON_ATTR);
800 }
801 }
802 if (ok && traceTypeOK && !traceType.equals("")) { //$NON-NLS-1$
803 // Tag the selected traces with their type
804 List<String> files = new ArrayList<String>(fileSystemObjects.keySet());
805 Collections.sort(files);
806 // After sorting, traces correspond to the unique prefixes
807 String prefix = null;
808 for (int i = 0; i < files.size(); i++) {
809 File file = fileSystemObjects.get(files.get(i));
810 String name = file.getAbsolutePath();
811 if (prefix == null || !name.startsWith(prefix)) {
812 prefix = name; // new prefix
813 IResource resource = fTargetFolder.findMember(file.getName());
814 if (resource != null) {
815 try {
816 // Set the trace properties for this resource
817 resource.setPersistentProperty(TmfTraceElement.TRACEBUNDLE, traceBundle);
818 resource.setPersistentProperty(TmfTraceElement.TRACETYPE, traceTypeId);
819 resource.setPersistentProperty(TmfTraceElement.TRACEICON, traceIcon);
820 for (TmfTraceElement traceElement : TmfProjectRegistry.getProject(resource.getProject()).getTracesFolder().getTraces()) {
821 if (traceElement.getName().equals(resource.getName())) {
822 traceElement.refreshTraceType();
823 break;
824 }
825 }
826 } catch (CoreException e) {
827 e.printStackTrace();
828 }
829 }
830 }
831 }
832 }
833 return ok;
834 }
835
836 MessageDialog.openInformation(getContainer().getShell(), Messages.ImportTraceWizard_Information,
837 Messages.ImportTraceWizard_SelectTraceNoneSelected);
838 return false;
839 }
840
841 private boolean importResources(String rootDirectory, Map<String, File> fileSystemObjects) {
842
843 // Determine the sorted canonical list of items to import
844 List<File> fileList = new ArrayList<File>();
845 for (Entry<String, File> entry : fileSystemObjects.entrySet()) {
846 fileList.add(entry.getValue());
847 }
848 Collections.sort(fileList);
849
850
851 // Perform a distinct import operation for everything that has the same prefix
852 // (distinct prefixes correspond to traces - we don't want to re-create parent structures)
853 boolean ok = true;
854 boolean isLinked = createLinksInWorkspaceButton.getSelection();
855 for (int i = 0; i < fileList.size(); i++) {
856 File resource = fileList.get(i);
857 File parentFolder = new File(resource.getParent());
858
859 List<File> subList = new ArrayList<File>();
860 subList.add(resource);
861 if (resource.isDirectory()) {
862 String prefix = resource.getAbsolutePath();
863 boolean hasSamePrefix = true;
864 for (int j = i; j < fileList.size() && hasSamePrefix; j++) {
865 File res = fileList.get(j);
866 hasSamePrefix = res.getAbsolutePath().startsWith(prefix);
867 if (hasSamePrefix) {
868 // Import children individually if not linked
869 if (!isLinked) {
870 subList.add(res);
871 }
872 i = j;
873 }
874 }
875 }
876
877 // Perform the import operation for this subset
878 FileSystemStructureProvider fileSystemStructureProvider = FileSystemStructureProvider.INSTANCE;
879 ImportOperation operation = new ImportOperation(getContainerFullPath(), parentFolder, fileSystemStructureProvider, this,
880 subList);
881 operation.setContext(getShell());
882 ok = executeImportOperation(operation);
883 }
884
885 return ok;
886 }
887
888 private boolean executeImportOperation(ImportOperation op) {
889 initializeOperation(op);
890
891 try {
892 getContainer().run(true, true, op);
893 } catch (InterruptedException e) {
894 return false;
895 } catch (InvocationTargetException e) {
896 displayErrorDialog(e.getTargetException());
897 return false;
898 }
899
900 IStatus status = op.getStatus();
901 if (!status.isOK()) {
902 ErrorDialog.openError(getContainer().getShell(), Messages.ImportTraceWizard_ImportProblem, null, status);
903 return false;
904 }
905
906 return true;
907 }
908
909 private void initializeOperation(ImportOperation op) {
910 op.setCreateContainerStructure(false);
911 op.setOverwriteResources(overwriteExistingResourcesCheckbox.getSelection());
912 op.setCreateLinks(createLinksInWorkspaceButton.getSelection());
913 op.setVirtualFolders(false);
914 }
915
916 }
This page took 0.051284 seconds and 5 git commands to generate.