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