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