Commit | Line | Data |
---|---|---|
002f9f07 | 1 | /******************************************************************************* |
2b0005f0 | 2 | * Copyright (c) 2009, 2015 Ericsson and others. |
002f9f07 BH |
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 | * Anna Dushistova(Montavista) - [383047] NPE while importing a CFT trace | |
14 | * Matthew Khouzam - Moved out some common functions | |
15 | * Patrick Tasse - Add sorting of file system elements | |
252c602c | 16 | * Bernd Hufmann - Re-design of trace selection and trace validation |
0e1d517e | 17 | * Marc-Andre Laperle - Preserve folder structure on import |
002f9f07 BH |
18 | *******************************************************************************/ |
19 | ||
2bdf0193 | 20 | package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace; |
002f9f07 BH |
21 | |
22 | import java.io.File; | |
c8cf44dc | 23 | import java.io.IOException; |
16f91bd5 | 24 | import java.io.InputStream; |
002f9f07 | 25 | import java.lang.reflect.InvocationTargetException; |
c8cf44dc | 26 | import java.net.URI; |
002f9f07 | 27 | import java.util.ArrayList; |
29ceb238 | 28 | import java.util.Collection; |
002f9f07 BH |
29 | import java.util.HashMap; |
30 | import java.util.Iterator; | |
002f9f07 BH |
31 | import java.util.List; |
32 | import java.util.Map; | |
c8cf44dc MAL |
33 | import java.util.zip.ZipEntry; |
34 | import java.util.zip.ZipException; | |
35 | import java.util.zip.ZipFile; | |
002f9f07 BH |
36 | |
37 | import org.eclipse.core.resources.IContainer; | |
38 | import org.eclipse.core.resources.IFolder; | |
39 | import org.eclipse.core.resources.IProject; | |
40 | import org.eclipse.core.resources.IResource; | |
41 | import org.eclipse.core.resources.ResourcesPlugin; | |
42 | import org.eclipse.core.runtime.CoreException; | |
43 | import org.eclipse.core.runtime.IPath; | |
252c602c | 44 | import org.eclipse.core.runtime.IProgressMonitor; |
002f9f07 | 45 | import org.eclipse.core.runtime.IStatus; |
252c602c | 46 | import org.eclipse.core.runtime.NullProgressMonitor; |
002f9f07 BH |
47 | import org.eclipse.core.runtime.Path; |
48 | import org.eclipse.core.runtime.Platform; | |
252c602c BH |
49 | import org.eclipse.core.runtime.Status; |
50 | import org.eclipse.core.runtime.SubMonitor; | |
51 | import org.eclipse.core.runtime.SubProgressMonitor; | |
89730b51 | 52 | import org.eclipse.core.runtime.URIUtil; |
252c602c | 53 | import org.eclipse.jface.dialogs.IDialogSettings; |
c8cf44dc | 54 | import org.eclipse.jface.layout.PixelConverter; |
252c602c BH |
55 | import org.eclipse.jface.operation.IRunnableWithProgress; |
56 | import org.eclipse.jface.operation.ModalContext; | |
282218e9 MAL |
57 | import org.eclipse.jface.viewers.CheckStateChangedEvent; |
58 | import org.eclipse.jface.viewers.ICheckStateListener; | |
002f9f07 BH |
59 | import org.eclipse.jface.viewers.IStructuredSelection; |
60 | import org.eclipse.jface.viewers.ITreeContentProvider; | |
002f9f07 BH |
61 | import org.eclipse.swt.SWT; |
62 | import org.eclipse.swt.custom.BusyIndicator; | |
c8cf44dc | 63 | import org.eclipse.swt.events.FocusAdapter; |
002f9f07 | 64 | import org.eclipse.swt.events.FocusEvent; |
2f7b3dd7 BH |
65 | import org.eclipse.swt.events.ModifyEvent; |
66 | import org.eclipse.swt.events.ModifyListener; | |
002f9f07 BH |
67 | import org.eclipse.swt.events.SelectionAdapter; |
68 | import org.eclipse.swt.events.SelectionEvent; | |
c8cf44dc MAL |
69 | import org.eclipse.swt.events.TraverseEvent; |
70 | import org.eclipse.swt.events.TraverseListener; | |
002f9f07 BH |
71 | import org.eclipse.swt.layout.GridData; |
72 | import org.eclipse.swt.layout.GridLayout; | |
73 | import org.eclipse.swt.widgets.Button; | |
74 | import org.eclipse.swt.widgets.Combo; | |
75 | import org.eclipse.swt.widgets.Composite; | |
76 | import org.eclipse.swt.widgets.DirectoryDialog; | |
77 | import org.eclipse.swt.widgets.Event; | |
c8cf44dc | 78 | import org.eclipse.swt.widgets.FileDialog; |
002f9f07 BH |
79 | import org.eclipse.swt.widgets.Group; |
80 | import org.eclipse.swt.widgets.Label; | |
2bdf0193 AM |
81 | import org.eclipse.tracecompass.internal.tmf.ui.Activator; |
82 | import org.eclipse.tracecompass.tmf.core.TmfCommonConstants; | |
83 | import org.eclipse.tracecompass.tmf.core.TmfProjectNature; | |
84 | import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceImportException; | |
85 | import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType; | |
86 | import org.eclipse.tracecompass.tmf.core.project.model.TraceTypeHelper; | |
87 | import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectElement; | |
88 | import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectRegistry; | |
2bdf0193 AM |
89 | import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder; |
90 | import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceTypeUIUtils; | |
91 | import org.eclipse.tracecompass.tmf.ui.project.model.TmfTracesFolder; | |
002f9f07 | 92 | import org.eclipse.ui.dialogs.FileSystemElement; |
252c602c | 93 | import org.eclipse.ui.dialogs.IOverwriteQuery; |
002f9f07 | 94 | import org.eclipse.ui.dialogs.WizardResourceImportPage; |
282218e9 | 95 | import org.eclipse.ui.internal.ide.DialogUtil; |
29ceb238 | 96 | import org.eclipse.ui.internal.ide.dialogs.IElementFilter; |
c8cf44dc | 97 | import org.eclipse.ui.internal.wizards.datatransfer.ArchiveFileManipulations; |
c8cf44dc MAL |
98 | import org.eclipse.ui.internal.wizards.datatransfer.ILeveledImportStructureProvider; |
99 | import org.eclipse.ui.internal.wizards.datatransfer.TarEntry; | |
100 | import org.eclipse.ui.internal.wizards.datatransfer.TarException; | |
101 | import org.eclipse.ui.internal.wizards.datatransfer.TarFile; | |
102 | import org.eclipse.ui.internal.wizards.datatransfer.TarLeveledStructureProvider; | |
103 | import org.eclipse.ui.internal.wizards.datatransfer.ZipLeveledStructureProvider; | |
252c602c | 104 | import org.eclipse.ui.model.AdaptableList; |
002f9f07 | 105 | import org.eclipse.ui.model.WorkbenchContentProvider; |
282218e9 MAL |
106 | import org.eclipse.ui.model.WorkbenchLabelProvider; |
107 | import org.eclipse.ui.model.WorkbenchViewerComparator; | |
002f9f07 BH |
108 | import org.eclipse.ui.wizards.datatransfer.FileSystemStructureProvider; |
109 | import org.eclipse.ui.wizards.datatransfer.IImportStructureProvider; | |
110 | import org.eclipse.ui.wizards.datatransfer.ImportOperation; | |
111 | ||
112 | /** | |
ba560b10 MK |
113 | * A variant of the standard resource import wizard for importing traces to |
114 | * given tracing project. If no project or tracing project was selected the | |
115 | * wizard imports it to the default tracing project which is created if | |
116 | * necessary. | |
252c602c BH |
117 | * |
118 | * In our case traces could be files or a directory structure. This wizard | |
ba560b10 MK |
119 | * supports both cases. It imports traces for a selected trace type or, if no |
120 | * trace type is selected, it tries to detect the trace type automatically. | |
121 | * However, the automatic detection is a best-effort and cannot guarantee that | |
122 | * the detection is successful. The reason for this is that there might be | |
123 | * multiple trace types that can be assigned to a single trace. | |
252c602c | 124 | * |
002f9f07 | 125 | * |
002f9f07 | 126 | * @author Francois Chouinard |
002f9f07 | 127 | */ |
29ceb238 | 128 | @SuppressWarnings("restriction") |
002f9f07 BH |
129 | public class ImportTraceWizardPage extends WizardResourceImportPage { |
130 | ||
002f9f07 BH |
131 | // ------------------------------------------------------------------------ |
132 | // Constants | |
133 | // ------------------------------------------------------------------------ | |
d0e34947 MAL |
134 | private static final String IMPORT_WIZARD_PAGE_NAME = "ImportTraceWizardPage"; //$NON-NLS-1$ |
135 | private static final String IMPORT_WIZARD_ROOT_DIRECTORY_ID = ".import_root_directory_id"; //$NON-NLS-1$; | |
136 | private static final String IMPORT_WIZARD_ARCHIVE_FILE_NAME_ID = ".import_archive_file_name_id"; //$NON-NLS-1$ | |
137 | private static final String IMPORT_WIZARD_IMPORT_UNRECOGNIZED_ID = ".import_unrecognized_traces_id"; //$NON-NLS-1$ | |
138 | private static final String IMPORT_WIZARD_PRESERVE_FOLDERS_ID = ".import_preserve_folders_id"; //$NON-NLS-1$ | |
139 | private static final String IMPORT_WIZARD_IMPORT_FROM_DIRECTORY_ID = ".import_from_directory"; //$NON-NLS-1$ | |
002f9f07 | 140 | |
c8cf44dc MAL |
141 | // constant from WizardArchiveFileResourceImportPage1 |
142 | private static final String[] FILE_IMPORT_MASK = { "*.jar;*.zip;*.tar;*.tar.gz;*.tgz", "*.*" }; //$NON-NLS-1$ //$NON-NLS-2$ | |
143 | private static final String TRACE_IMPORT_TEMP_FOLDER = ".traceImport"; //$NON-NLS-1$ | |
144 | ||
d0e34947 MAL |
145 | /** |
146 | * A special trace type value to communicate that automatic trace type | |
147 | * detection will occur instead of setting a specific trace type when | |
148 | * importing the traces. | |
149 | */ | |
9b3f4afe | 150 | public static final String TRACE_TYPE_AUTO_DETECT = Messages.ImportTraceWizard_AutoDetection; |
d0e34947 MAL |
151 | |
152 | /** | |
153 | * Preserve the folder structure of the import traces. | |
154 | */ | |
9b3f4afe | 155 | public static final int OPTION_PRESERVE_FOLDER_STRUCTURE = 1 << 1; |
d0e34947 MAL |
156 | /** |
157 | * Create links to the trace files instead of copies. | |
158 | */ | |
9b3f4afe | 159 | public static final int OPTION_CREATE_LINKS_IN_WORKSPACE = 1 << 2; |
d0e34947 MAL |
160 | /** |
161 | * Import files that were not recognized as the selected trace type. | |
162 | */ | |
9b3f4afe | 163 | public static final int OPTION_IMPORT_UNRECOGNIZED_TRACES = 1 << 3; |
d0e34947 MAL |
164 | /** |
165 | * Overwrite existing resources without prompting. | |
166 | */ | |
9b3f4afe | 167 | public static final int OPTION_OVERWRITE_EXISTING_RESOURCES = 1 << 4; |
d0e34947 | 168 | |
002f9f07 BH |
169 | // ------------------------------------------------------------------------ |
170 | // Attributes | |
171 | // ------------------------------------------------------------------------ | |
172 | ||
002f9f07 BH |
173 | // Target import directory ('Traces' folder) |
174 | private IFolder fTargetFolder; | |
16f91bd5 BH |
175 | // Target Trace folder element |
176 | private TmfTraceFolder fTraceFolderElement; | |
252c602c BH |
177 | // Flag to handle destination folder change event |
178 | private Boolean fIsDestinationChanged = false; | |
179 | // Combo box containing trace types | |
180 | private Combo fTraceTypes; | |
181 | // Button to ignore unrecognized traces or not | |
182 | private Button fImportUnrecognizedButton; | |
183 | // Button to overwrite existing resources or not | |
184 | private Button fOverwriteExistingResourcesCheckbox; | |
185 | // Button to link or copy traces to workspace | |
186 | private Button fCreateLinksInWorkspaceButton; | |
0e1d517e MAL |
187 | // Button to preserve folder structure |
188 | private Button fPreserveFolderStructureButton; | |
252c602c | 189 | private boolean entryChanged = false; |
c8cf44dc MAL |
190 | // The import from directory radio button |
191 | private Button fImportFromDirectoryRadio; | |
192 | // The import from archive radio button | |
193 | private Button fImportFromArchiveRadio; | |
194 | // Flag to remember the "create links" checkbox when it gets disabled by | |
195 | // the import from archive radio button | |
196 | private Boolean fPreviousCreateLinksValue = true; | |
d0e34947 | 197 | |
c8cf44dc | 198 | /** The archive name field */ |
d0e34947 | 199 | protected Combo fArchiveNameField; |
c8cf44dc MAL |
200 | /** The archive browse button. */ |
201 | protected Button fArchiveBrowseButton; | |
252c602c BH |
202 | /** The directory name field */ |
203 | protected Combo directoryNameField; | |
204 | /** The directory browse button. */ | |
205 | protected Button directoryBrowseButton; | |
002f9f07 | 206 | |
282218e9 MAL |
207 | /** |
208 | * ResourceTreeAndListGroup was internal in Kepler and we referenced it. It | |
209 | * is now removed in Luna. To keep our builds compatible with Kepler, we | |
210 | * need to have our own version of this class. Once we stop supporting | |
211 | * Kepler, we can delete this class and use the public one from the | |
212 | * platform. | |
213 | */ | |
214 | private ResourceTreeAndListGroup fSelectionGroup; | |
215 | ||
c8cf44dc MAL |
216 | // Keep trace of the selection root so that we can dispose its related |
217 | // resources | |
218 | private TraceFileSystemElement fSelectionGroupRoot; | |
219 | ||
002f9f07 BH |
220 | // ------------------------------------------------------------------------ |
221 | // Constructors | |
222 | // ------------------------------------------------------------------------ | |
223 | ||
224 | /** | |
225 | * Constructor. Creates the trace wizard page. | |
226 | * | |
227 | * @param name | |
228 | * The name of the page. | |
229 | * @param selection | |
230 | * The current selection | |
231 | */ | |
232 | protected ImportTraceWizardPage(String name, IStructuredSelection selection) { | |
233 | super(name, selection); | |
002f9f07 BH |
234 | setTitle(Messages.ImportTraceWizard_FileSystemTitle); |
235 | setDescription(Messages.ImportTraceWizard_ImportTrace); | |
236 | ||
237 | // Locate the target trace folder | |
238 | IFolder traceFolder = null; | |
239 | Object element = selection.getFirstElement(); | |
240 | ||
241 | if (element instanceof TmfTraceFolder) { | |
16f91bd5 | 242 | fTraceFolderElement = (TmfTraceFolder) element; |
16f91bd5 | 243 | traceFolder = fTraceFolderElement.getResource(); |
002f9f07 BH |
244 | } else if (element instanceof IProject) { |
245 | IProject project = (IProject) element; | |
246 | try { | |
247 | if (project.hasNature(TmfProjectNature.ID)) { | |
6ca50a1d BH |
248 | TmfProjectElement projectElement = TmfProjectRegistry.getProject(project, true); |
249 | fTraceFolderElement = projectElement.getTracesFolder(); | |
339d539c | 250 | traceFolder = project.getFolder(TmfTracesFolder.TRACES_FOLDER_NAME); |
002f9f07 BH |
251 | } |
252 | } catch (CoreException e) { | |
253 | } | |
254 | } | |
255 | ||
ba560b10 MK |
256 | // If no tracing project was selected or trace folder doesn't exist use |
257 | // default tracing project | |
252c602c BH |
258 | if (traceFolder == null) { |
259 | IProject project = TmfProjectRegistry.createProject( | |
260 | TmfCommonConstants.DEFAULT_TRACE_PROJECT_NAME, null, new NullProgressMonitor()); | |
6ca50a1d BH |
261 | TmfProjectElement projectElement = TmfProjectRegistry.getProject(project, true); |
262 | fTraceFolderElement = projectElement.getTracesFolder(); | |
339d539c | 263 | traceFolder = project.getFolder(TmfTracesFolder.TRACES_FOLDER_NAME); |
252c602c BH |
264 | } |
265 | ||
002f9f07 BH |
266 | // Set the target trace folder |
267 | if (traceFolder != null) { | |
268 | fTargetFolder = traceFolder; | |
1d6c9022 | 269 | String path = traceFolder.getFullPath().toString(); |
002f9f07 BH |
270 | setContainerFieldValue(path); |
271 | } | |
272 | } | |
273 | ||
d0e34947 MAL |
274 | /** |
275 | * Constructor | |
276 | * | |
277 | * @param selection | |
278 | * The current selection | |
279 | */ | |
280 | public ImportTraceWizardPage(IStructuredSelection selection) { | |
281 | this(IMPORT_WIZARD_PAGE_NAME, selection); | |
282 | } | |
283 | ||
284 | /** | |
285 | * Create the import source selection widget. (Copied from | |
286 | * WizardResourceImportPage but instead always uses the internal | |
287 | * ResourceTreeAndListGroup to keep compatibility with Kepler) | |
288 | */ | |
289 | @Override | |
290 | protected void createFileSelectionGroup(Composite parent) { | |
291 | ||
292 | // Just create with a dummy root. | |
293 | fSelectionGroup = new ResourceTreeAndListGroup(parent, | |
294 | new FileSystemElement("Dummy", null, true),//$NON-NLS-1$ | |
295 | getFolderProvider(), new WorkbenchLabelProvider(), | |
296 | getFileProvider(), new WorkbenchLabelProvider(), SWT.NONE, | |
297 | DialogUtil.inRegularFontMode(parent)); | |
298 | ||
299 | ICheckStateListener listener = new ICheckStateListener() { | |
300 | @Override | |
301 | public void checkStateChanged(CheckStateChangedEvent event) { | |
302 | updateWidgetEnablements(); | |
303 | } | |
304 | }; | |
305 | ||
306 | WorkbenchViewerComparator comparator = new WorkbenchViewerComparator(); | |
307 | fSelectionGroup.setTreeComparator(comparator); | |
308 | fSelectionGroup.setListComparator(comparator); | |
309 | fSelectionGroup.addCheckStateListener(listener); | |
310 | ||
311 | } | |
312 | ||
002f9f07 BH |
313 | // ------------------------------------------------------------------------ |
314 | // WizardResourceImportPage | |
315 | // ------------------------------------------------------------------------ | |
316 | ||
002f9f07 BH |
317 | @Override |
318 | protected void createSourceGroup(Composite parent) { | |
c8cf44dc | 319 | createSourceSelectionGroup(parent); |
002f9f07 BH |
320 | createFileSelectionGroup(parent); |
321 | createTraceTypeGroup(parent); | |
322 | validateSourceGroup(); | |
323 | } | |
324 | ||
325 | @Override | |
252c602c BH |
326 | protected ITreeContentProvider getFileProvider() { |
327 | return new WorkbenchContentProvider() { | |
002f9f07 | 328 | @Override |
252c602c BH |
329 | public Object[] getChildren(Object object) { |
330 | if (object instanceof TraceFileSystemElement) { | |
331 | TraceFileSystemElement element = (TraceFileSystemElement) object; | |
332 | return element.getFiles().getChildren(element); | |
002f9f07 | 333 | } |
252c602c | 334 | return new Object[0]; |
002f9f07 | 335 | } |
252c602c | 336 | }; |
002f9f07 BH |
337 | } |
338 | ||
339 | @Override | |
340 | protected ITreeContentProvider getFolderProvider() { | |
002f9f07 BH |
341 | return new WorkbenchContentProvider() { |
342 | @Override | |
343 | public Object[] getChildren(Object o) { | |
252c602c BH |
344 | if (o instanceof TraceFileSystemElement) { |
345 | TraceFileSystemElement element = (TraceFileSystemElement) o; | |
346 | return element.getFolders().getChildren(); | |
002f9f07 BH |
347 | } |
348 | return new Object[0]; | |
349 | } | |
002f9f07 | 350 | |
252c602c BH |
351 | @Override |
352 | public boolean hasChildren(Object o) { | |
353 | if (o instanceof TraceFileSystemElement) { | |
354 | TraceFileSystemElement element = (TraceFileSystemElement) o; | |
355 | if (element.isPopulated()) { | |
356 | return getChildren(element).length > 0; | |
357 | } | |
ba560b10 | 358 | // If we have not populated then wait until asked |
252c602c | 359 | return true; |
002f9f07 | 360 | } |
252c602c | 361 | return false; |
002f9f07 | 362 | } |
252c602c | 363 | }; |
002f9f07 BH |
364 | } |
365 | ||
366 | // ------------------------------------------------------------------------ | |
367 | // Directory Selection Group (forked WizardFileSystemResourceImportPage1) | |
368 | // ------------------------------------------------------------------------ | |
369 | ||
002f9f07 | 370 | /** |
c8cf44dc | 371 | * creates the source selection group. |
002f9f07 BH |
372 | * |
373 | * @param parent | |
374 | * the parent composite | |
375 | */ | |
d0e34947 | 376 | protected void createSourceSelectionGroup(Composite parent) { |
002f9f07 | 377 | |
d0e34947 | 378 | Composite sourceGroup = new Composite(parent, SWT.NONE); |
002f9f07 BH |
379 | GridLayout layout = new GridLayout(); |
380 | layout.numColumns = 3; | |
c8cf44dc MAL |
381 | layout.makeColumnsEqualWidth = false; |
382 | layout.marginWidth = 0; | |
383 | sourceGroup.setLayout(layout); | |
384 | sourceGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); | |
385 | ||
386 | // import from directory radio button | |
387 | fImportFromDirectoryRadio = new Button(sourceGroup, SWT.RADIO); | |
388 | fImportFromDirectoryRadio | |
389 | .setText(Messages.ImportTraceWizard_DirectoryLocation); | |
390 | ||
391 | // import location entry combo | |
d0e34947 MAL |
392 | directoryNameField = createPathSelectionCombo(sourceGroup); |
393 | createDirectoryBrowseButton(sourceGroup); | |
c8cf44dc MAL |
394 | |
395 | // import from archive radio button | |
396 | fImportFromArchiveRadio = new Button(sourceGroup, SWT.RADIO); | |
397 | fImportFromArchiveRadio | |
398 | .setText(Messages.ImportTraceWizard_ArchiveLocation); | |
399 | ||
400 | // import location entry combo | |
d0e34947 MAL |
401 | fArchiveNameField = createPathSelectionCombo(sourceGroup); |
402 | createArchiveBrowseButton(sourceGroup); | |
c8cf44dc MAL |
403 | |
404 | fImportFromDirectoryRadio.setSelection(true); | |
405 | fArchiveNameField.setEnabled(false); | |
406 | fArchiveBrowseButton.setEnabled(false); | |
407 | ||
d0e34947 | 408 | fImportFromDirectoryRadio.addSelectionListener(new SelectionAdapter() { |
002f9f07 BH |
409 | @Override |
410 | public void widgetSelected(SelectionEvent e) { | |
d0e34947 | 411 | directoryRadioSelected(); |
002f9f07 | 412 | } |
c8cf44dc | 413 | }); |
002f9f07 | 414 | |
d0e34947 | 415 | fImportFromArchiveRadio.addSelectionListener(new SelectionAdapter() { |
002f9f07 | 416 | @Override |
c8cf44dc | 417 | public void widgetSelected(SelectionEvent e) { |
d0e34947 | 418 | archiveRadioSelected(); |
002f9f07 BH |
419 | } |
420 | }); | |
d0e34947 MAL |
421 | } |
422 | ||
423 | /** | |
424 | * Select or deselect all files in the file selection group | |
425 | * | |
426 | * @param checked | |
427 | * whether or not the files should be checked | |
428 | */ | |
429 | protected void setFileSelectionGroupChecked(boolean checked) { | |
430 | if (fSelectionGroup != null) { | |
431 | fSelectionGroup.setAllSelections(checked); | |
432 | } | |
433 | } | |
434 | ||
435 | /** | |
436 | * Create a combo that will be used to select a path to specify the source | |
437 | * of the import. The parent is assumed to have a GridLayout. | |
438 | * | |
439 | * @param parent | |
440 | * the parent composite | |
441 | * @return the created path selection combo | |
442 | */ | |
443 | protected Combo createPathSelectionCombo(Composite parent) { | |
444 | Combo pathSelectionCombo = new Combo(parent, SWT.BORDER); | |
445 | ||
446 | GridData layoutData = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL); | |
447 | layoutData.widthHint = new PixelConverter(pathSelectionCombo).convertWidthInCharsToPixels(25); | |
448 | pathSelectionCombo.setLayoutData(layoutData); | |
002f9f07 | 449 | |
c8cf44dc | 450 | TraverseListener traverseListener = new TraverseListener() { |
002f9f07 | 451 | @Override |
c8cf44dc MAL |
452 | public void keyTraversed(TraverseEvent e) { |
453 | if (e.detail == SWT.TRAVERSE_RETURN) { | |
454 | e.doit = false; | |
455 | entryChanged = false; | |
456 | updateFromSourceField(); | |
457 | } | |
002f9f07 | 458 | } |
c8cf44dc MAL |
459 | }; |
460 | ||
461 | FocusAdapter focusAdapter = new FocusAdapter() { | |
002f9f07 BH |
462 | @Override |
463 | public void focusLost(FocusEvent e) { | |
464 | // Clear the flag to prevent constant update | |
465 | if (entryChanged) { | |
466 | entryChanged = false; | |
467 | updateFromSourceField(); | |
468 | } | |
469 | } | |
c8cf44dc MAL |
470 | }; |
471 | ||
472 | SelectionAdapter selectionAdapter = new SelectionAdapter() { | |
473 | @Override | |
474 | public void widgetSelected(SelectionEvent e) { | |
475 | entryChanged = false; | |
476 | updateFromSourceField(); | |
477 | } | |
478 | }; | |
002f9f07 | 479 | |
c8cf44dc | 480 | ModifyListener modifyListner = new ModifyListener() { |
2f7b3dd7 BH |
481 | @Override |
482 | public void modifyText(ModifyEvent e) { | |
483 | entryChanged = true; | |
484 | } | |
c8cf44dc MAL |
485 | }; |
486 | ||
d0e34947 MAL |
487 | pathSelectionCombo.addModifyListener(modifyListner); |
488 | pathSelectionCombo.addTraverseListener(traverseListener); | |
489 | pathSelectionCombo.addFocusListener(focusAdapter); | |
490 | pathSelectionCombo.addSelectionListener(selectionAdapter); | |
c8cf44dc | 491 | |
d0e34947 MAL |
492 | return pathSelectionCombo; |
493 | } | |
494 | ||
495 | /** | |
496 | * Create the directory browse button. | |
497 | * | |
498 | * @param parent | |
499 | * the parent composite | |
500 | */ | |
501 | protected void createDirectoryBrowseButton(Composite parent) { | |
502 | directoryBrowseButton = createPathSelectionBrowseButton(parent); | |
503 | directoryBrowseButton.addSelectionListener(new SelectionAdapter() { | |
c8cf44dc MAL |
504 | @Override |
505 | public void widgetSelected(SelectionEvent e) { | |
d0e34947 | 506 | handleSourceDirectoryBrowseButtonPressed(); |
c8cf44dc | 507 | } |
2f7b3dd7 | 508 | }); |
d0e34947 | 509 | } |
2f7b3dd7 | 510 | |
d0e34947 MAL |
511 | /** |
512 | * Create the archive browse button. | |
513 | * | |
514 | * @param parent | |
515 | * the parent composite | |
516 | */ | |
517 | protected void createArchiveBrowseButton(Composite parent) { | |
518 | fArchiveBrowseButton = createPathSelectionBrowseButton(parent); | |
519 | fArchiveBrowseButton.addSelectionListener(new SelectionAdapter() { | |
c8cf44dc MAL |
520 | @Override |
521 | public void widgetSelected(SelectionEvent e) { | |
d0e34947 | 522 | handleArchiveBrowseButtonPressed(FILE_IMPORT_MASK); |
c8cf44dc MAL |
523 | } |
524 | }); | |
525 | } | |
526 | ||
d0e34947 MAL |
527 | /** |
528 | * Create a browse button that will be used to browse for a path to specify | |
529 | * the source of the import. The parent is assumed to have a GridLayout. | |
530 | * | |
531 | * @param parent | |
532 | * the parent composite | |
533 | * @return the created path selection combo | |
534 | */ | |
535 | protected Button createPathSelectionBrowseButton(Composite parent) { | |
536 | Button pathSelectionBrowseButton = new Button(parent, SWT.PUSH); | |
537 | pathSelectionBrowseButton.setText(Messages.ImportTraceWizard_BrowseButton); | |
538 | setButtonLayoutData(pathSelectionBrowseButton); | |
539 | ||
540 | return pathSelectionBrowseButton; | |
541 | } | |
542 | ||
c8cf44dc | 543 | private void archiveRadioSelected() { |
d0e34947 | 544 | if (!isImportFromDirectory()) { |
c8cf44dc MAL |
545 | directoryNameField.setEnabled(false); |
546 | directoryBrowseButton.setEnabled(false); | |
547 | fArchiveNameField.setEnabled(true); | |
548 | fArchiveBrowseButton.setEnabled(true); | |
549 | updateFromSourceField(); | |
550 | fArchiveNameField.setFocus(); | |
d0e34947 MAL |
551 | if (fCreateLinksInWorkspaceButton != null) { |
552 | fPreviousCreateLinksValue = fCreateLinksInWorkspaceButton.getSelection(); | |
553 | fCreateLinksInWorkspaceButton.setSelection(false); | |
554 | fCreateLinksInWorkspaceButton.setEnabled(false); | |
555 | } | |
c8cf44dc MAL |
556 | } |
557 | } | |
558 | ||
559 | private void directoryRadioSelected() { | |
d0e34947 | 560 | if (isImportFromDirectory()) { |
c8cf44dc MAL |
561 | directoryNameField.setEnabled(true); |
562 | directoryBrowseButton.setEnabled(true); | |
563 | fArchiveNameField.setEnabled(false); | |
564 | fArchiveBrowseButton.setEnabled(false); | |
565 | updateFromSourceField(); | |
566 | directoryNameField.setFocus(); | |
d0e34947 MAL |
567 | if (fCreateLinksInWorkspaceButton != null) { |
568 | fCreateLinksInWorkspaceButton.setSelection(fPreviousCreateLinksValue); | |
569 | fCreateLinksInWorkspaceButton.setEnabled(true); | |
570 | } | |
c8cf44dc | 571 | } |
002f9f07 BH |
572 | } |
573 | ||
574 | // ------------------------------------------------------------------------ | |
575 | // Browse for the source directory | |
576 | // ------------------------------------------------------------------------ | |
577 | ||
578 | @Override | |
579 | public void handleEvent(Event event) { | |
580 | if (event.widget == directoryBrowseButton) { | |
581 | handleSourceDirectoryBrowseButtonPressed(); | |
582 | } | |
252c602c BH |
583 | |
584 | // Avoid overwriting destination path without repeatedly trigger | |
585 | // call of handleEvent(); | |
586 | synchronized (fIsDestinationChanged) { | |
587 | if (fIsDestinationChanged == false) { | |
588 | event.display.asyncExec(new Runnable() { | |
589 | @Override | |
590 | public void run() { | |
591 | synchronized (fIsDestinationChanged) { | |
592 | fIsDestinationChanged = true; | |
1d6c9022 | 593 | String path = fTargetFolder.getFullPath().toString(); |
252c602c BH |
594 | setContainerFieldValue(path); |
595 | } | |
596 | } | |
597 | }); | |
598 | } else { | |
599 | fIsDestinationChanged = false; | |
600 | } | |
601 | } | |
002f9f07 BH |
602 | super.handleEvent(event); |
603 | } | |
604 | ||
252c602c BH |
605 | @Override |
606 | protected void handleContainerBrowseButtonPressed() { | |
607 | // Do nothing so that destination directory cannot be changed. | |
608 | } | |
609 | ||
002f9f07 BH |
610 | /** |
611 | * Handle the button pressed event | |
612 | */ | |
613 | protected void handleSourceDirectoryBrowseButtonPressed() { | |
614 | String currentSource = directoryNameField.getText(); | |
615 | DirectoryDialog dialog = new DirectoryDialog(directoryNameField.getShell(), SWT.SAVE | SWT.SHEET); | |
616 | dialog.setText(Messages.ImportTraceWizard_SelectTraceDirectoryTitle); | |
617 | dialog.setMessage(Messages.ImportTraceWizard_SelectTraceDirectoryMessage); | |
618 | dialog.setFilterPath(getSourceDirectoryName(currentSource)); | |
619 | ||
620 | String selectedDirectory = dialog.open(); | |
621 | if (selectedDirectory != null) { | |
622 | // Just quit if the directory is not valid | |
623 | if ((getSourceDirectory(selectedDirectory) == null) || selectedDirectory.equals(currentSource)) { | |
624 | return; | |
625 | } | |
626 | // If it is valid then proceed to populate | |
627 | setErrorMessage(null); | |
d0e34947 | 628 | setSourcePath(selectedDirectory); |
002f9f07 BH |
629 | } |
630 | } | |
631 | ||
c8cf44dc MAL |
632 | /** |
633 | * Handle the button pressed event | |
d0e34947 MAL |
634 | * |
635 | * @param extensions | |
636 | * file extensions used to filter files shown to the user | |
c8cf44dc | 637 | */ |
d0e34947 | 638 | protected void handleArchiveBrowseButtonPressed(String[] extensions) { |
c8cf44dc | 639 | FileDialog dialog = new FileDialog(fArchiveNameField.getShell(), SWT.SHEET); |
d0e34947 | 640 | dialog.setFilterExtensions(extensions); |
c8cf44dc MAL |
641 | dialog.setText(Messages.ImportTraceWizard_SelectTraceArchiveTitle); |
642 | String fileName = fArchiveNameField.getText().trim(); | |
643 | if (!fileName.isEmpty()) { | |
644 | File path = new File(fileName).getParentFile(); | |
645 | if (path != null && path.exists()) { | |
646 | dialog.setFilterPath(path.toString()); | |
647 | } | |
648 | } | |
649 | ||
650 | String selectedArchive = dialog.open(); | |
651 | if (selectedArchive != null) { | |
652 | setErrorMessage(null); | |
d0e34947 | 653 | setSourcePath(selectedArchive); |
c8cf44dc MAL |
654 | updateWidgetEnablements(); |
655 | } | |
656 | } | |
657 | ||
002f9f07 | 658 | private File getSourceDirectory() { |
d0e34947 MAL |
659 | if (directoryNameField == null) { |
660 | return null; | |
661 | } | |
002f9f07 BH |
662 | return getSourceDirectory(directoryNameField.getText()); |
663 | } | |
664 | ||
c8cf44dc | 665 | private File getSourceArchiveFile() { |
d0e34947 MAL |
666 | if (fArchiveNameField == null) { |
667 | return null; | |
668 | } | |
669 | ||
c8cf44dc MAL |
670 | return getSourceArchiveFile(fArchiveNameField.getText()); |
671 | } | |
672 | ||
673 | private String getSourceContainerPath() { | |
d0e34947 | 674 | if (isImportFromDirectory()) { |
c8cf44dc MAL |
675 | File sourceDirectory = getSourceDirectory(); |
676 | if (sourceDirectory != null) { | |
677 | return sourceDirectory.getAbsolutePath(); | |
678 | } | |
679 | } | |
680 | File sourceArchiveFile = getSourceArchiveFile(); | |
681 | if (sourceArchiveFile != null) { | |
682 | return sourceArchiveFile.getParent(); | |
683 | } | |
684 | return null; | |
685 | } | |
686 | ||
002f9f07 BH |
687 | private static File getSourceDirectory(String path) { |
688 | File sourceDirectory = new File(getSourceDirectoryName(path)); | |
689 | if (!sourceDirectory.exists() || !sourceDirectory.isDirectory()) { | |
690 | return null; | |
691 | } | |
692 | ||
693 | return sourceDirectory; | |
694 | } | |
695 | ||
c8cf44dc MAL |
696 | private static File getSourceArchiveFile(String path) { |
697 | File sourceArchiveFile = new File(path); | |
698 | if (!sourceArchiveFile.exists() || sourceArchiveFile.isDirectory()) { | |
699 | return null; | |
700 | } | |
701 | ||
702 | return sourceArchiveFile; | |
703 | } | |
704 | ||
002f9f07 BH |
705 | private static String getSourceDirectoryName(String sourceName) { |
706 | IPath result = new Path(sourceName.trim()); | |
707 | if (result.getDevice() != null && result.segmentCount() == 0) { | |
708 | result = result.addTrailingSeparator(); | |
709 | } else { | |
710 | result = result.removeTrailingSeparator(); | |
711 | } | |
712 | return result.toOSString(); | |
713 | } | |
714 | ||
002f9f07 | 715 | private void updateFromSourceField() { |
d0e34947 | 716 | setSourcePath(getSourceField().getText()); |
002f9f07 BH |
717 | updateWidgetEnablements(); |
718 | } | |
719 | ||
c8cf44dc | 720 | private Combo getSourceField() { |
d0e34947 MAL |
721 | if (directoryNameField == null) { |
722 | return fArchiveNameField; | |
723 | } | |
724 | ||
c8cf44dc MAL |
725 | return directoryNameField.isEnabled() ? directoryNameField : fArchiveNameField; |
726 | } | |
727 | ||
d0e34947 MAL |
728 | /** |
729 | * Set the source path that was selected by the user by various input | |
730 | * methods (Browse button, typing, etc). | |
731 | * | |
732 | * Clients can also call this to set the path programmatically (hard-coded | |
733 | * initial path) and this can also be overridden to be notified when the | |
734 | * source path changes. | |
735 | * | |
736 | * @param path | |
737 | * the source path | |
738 | */ | |
739 | protected void setSourcePath(String path) { | |
c8cf44dc | 740 | Combo sourceField = getSourceField(); |
d0e34947 MAL |
741 | if (sourceField == null) { |
742 | return; | |
743 | } | |
744 | ||
002f9f07 | 745 | if (path.length() > 0) { |
c8cf44dc | 746 | String[] currentItems = sourceField.getItems(); |
002f9f07 BH |
747 | int selectionIndex = -1; |
748 | for (int i = 0; i < currentItems.length; i++) { | |
749 | if (currentItems[i].equals(path)) { | |
750 | selectionIndex = i; | |
751 | } | |
752 | } | |
753 | if (selectionIndex < 0) { | |
754 | int oldLength = currentItems.length; | |
755 | String[] newItems = new String[oldLength + 1]; | |
756 | System.arraycopy(currentItems, 0, newItems, 0, oldLength); | |
757 | newItems[oldLength] = path; | |
c8cf44dc | 758 | sourceField.setItems(newItems); |
002f9f07 BH |
759 | selectionIndex = oldLength; |
760 | } | |
c8cf44dc | 761 | sourceField.select(selectionIndex); |
002f9f07 BH |
762 | } |
763 | resetSelection(); | |
764 | } | |
765 | ||
766 | // ------------------------------------------------------------------------ | |
767 | // File Selection Group (forked WizardFileSystemResourceImportPage1) | |
768 | // ------------------------------------------------------------------------ | |
002f9f07 | 769 | private void resetSelection() { |
c8cf44dc MAL |
770 | if (fSelectionGroupRoot != null) { |
771 | disposeSelectionGroupRoot(); | |
772 | } | |
773 | fSelectionGroupRoot = getFileSystemTree(); | |
774 | fSelectionGroup.setRoot(fSelectionGroupRoot); | |
775 | } | |
776 | ||
777 | private void disposeSelectionGroupRoot() { | |
778 | if (fSelectionGroupRoot != null && fSelectionGroupRoot.getProvider() != null) { | |
779 | FileSystemObjectImportStructureProvider provider = fSelectionGroupRoot.getProvider(); | |
780 | provider.dispose(); | |
781 | fSelectionGroupRoot = null; | |
782 | } | |
002f9f07 BH |
783 | } |
784 | ||
252c602c | 785 | private TraceFileSystemElement getFileSystemTree() { |
c8cf44dc MAL |
786 | IFileSystemObject rootElement = null; |
787 | FileSystemObjectImportStructureProvider importStructureProvider = null; | |
788 | ||
789 | // Import from directory | |
d0e34947 | 790 | if (isImportFromDirectory()) { |
c8cf44dc MAL |
791 | importStructureProvider = new FileSystemObjectImportStructureProvider(FileSystemStructureProvider.INSTANCE, null); |
792 | File sourceDirectory = getSourceDirectory(); | |
793 | if (sourceDirectory == null) { | |
794 | return null; | |
795 | } | |
796 | rootElement = importStructureProvider.getIFileSystemObject(sourceDirectory); | |
797 | } else { | |
798 | // Import from archive | |
799 | FileSystemObjectLeveledImportStructureProvider leveledImportStructureProvider = null; | |
800 | String archivePath = getSourceArchiveFile() != null ? getSourceArchiveFile().getAbsolutePath() : ""; //$NON-NLS-1$ | |
801 | if (ArchiveFileManipulations.isTarFile(archivePath)) { | |
802 | if (ensureTarSourceIsValid(archivePath)) { | |
ba560b10 MK |
803 | // We close the file when we dispose the import provider, |
804 | // see disposeSelectionGroupRoot | |
c8cf44dc MAL |
805 | TarFile tarFile = getSpecifiedTarSourceFile(archivePath); |
806 | leveledImportStructureProvider = new FileSystemObjectLeveledImportStructureProvider(new TarLeveledStructureProvider(tarFile), archivePath); | |
807 | } | |
808 | } else if (ensureZipSourceIsValid(archivePath)) { | |
ba560b10 MK |
809 | // We close the file when we dispose the import provider, see |
810 | // disposeSelectionGroupRoot | |
c8cf44dc MAL |
811 | @SuppressWarnings("resource") |
812 | ZipFile zipFile = getSpecifiedZipSourceFile(archivePath); | |
813 | leveledImportStructureProvider = new FileSystemObjectLeveledImportStructureProvider(new ZipLeveledStructureProvider(zipFile), archivePath); | |
814 | } | |
815 | if (leveledImportStructureProvider == null) { | |
816 | return null; | |
817 | } | |
818 | rootElement = leveledImportStructureProvider.getRoot(); | |
819 | importStructureProvider = leveledImportStructureProvider; | |
820 | } | |
821 | ||
822 | if (rootElement == null) { | |
823 | return null; | |
824 | } | |
825 | ||
826 | return selectFiles(rootElement, importStructureProvider); | |
827 | } | |
828 | ||
829 | /** | |
830 | * An import provider that makes use of the IFileSystemObject abstraction | |
831 | * instead of using plain file system objects (File, TarEntry, ZipEntry) | |
832 | */ | |
833 | private static class FileSystemObjectImportStructureProvider implements IImportStructureProvider { | |
834 | ||
835 | private IImportStructureProvider fImportProvider; | |
836 | private String fArchivePath; | |
ba560b10 | 837 | |
c8cf44dc MAL |
838 | private FileSystemObjectImportStructureProvider(IImportStructureProvider importStructureProvider, String archivePath) { |
839 | fImportProvider = importStructureProvider; | |
840 | fArchivePath = archivePath; | |
841 | } | |
842 | ||
843 | @Override | |
844 | public List<IFileSystemObject> getChildren(Object element) { | |
845 | @SuppressWarnings("rawtypes") | |
ba560b10 | 846 | List children = fImportProvider.getChildren(((IFileSystemObject) element).getRawFileSystemObject()); |
c8cf44dc MAL |
847 | List<IFileSystemObject> adapted = new ArrayList<>(children.size()); |
848 | for (Object o : children) { | |
849 | adapted.add(getIFileSystemObject(o)); | |
850 | } | |
851 | return adapted; | |
852 | } | |
853 | ||
edaf6a5e MAL |
854 | public IFileSystemObject getIFileSystemObject(Object o) { |
855 | if (o == null) { | |
856 | return null; | |
857 | } | |
858 | ||
c8cf44dc | 859 | if (o instanceof File) { |
edaf6a5e | 860 | return new FileFileSystemObject((File) o); |
c8cf44dc MAL |
861 | } else if (o instanceof TarEntry) { |
862 | return new TarFileSystemObject((TarEntry) o, fArchivePath); | |
863 | } else if (o instanceof ZipEntry) { | |
864 | return new ZipFileSystemObject((ZipEntry) o, fArchivePath); | |
865 | } | |
866 | ||
867 | throw new IllegalArgumentException("Object type not handled"); //$NON-NLS-1$ | |
868 | } | |
869 | ||
870 | @Override | |
871 | public InputStream getContents(Object element) { | |
ba560b10 | 872 | return fImportProvider.getContents(((IFileSystemObject) element).getRawFileSystemObject()); |
c8cf44dc MAL |
873 | } |
874 | ||
875 | @Override | |
876 | public String getFullPath(Object element) { | |
ba560b10 | 877 | return fImportProvider.getFullPath(((IFileSystemObject) element).getRawFileSystemObject()); |
c8cf44dc MAL |
878 | } |
879 | ||
880 | @Override | |
881 | public String getLabel(Object element) { | |
ba560b10 | 882 | return fImportProvider.getLabel(((IFileSystemObject) element).getRawFileSystemObject()); |
c8cf44dc MAL |
883 | } |
884 | ||
885 | @Override | |
886 | public boolean isFolder(Object element) { | |
ba560b10 | 887 | return fImportProvider.isFolder(((IFileSystemObject) element).getRawFileSystemObject()); |
c8cf44dc MAL |
888 | } |
889 | ||
890 | /** | |
891 | * Disposes of the resources associated with the provider. | |
892 | */ | |
893 | public void dispose() { | |
894 | } | |
895 | } | |
896 | ||
897 | /** | |
898 | * An import provider that both supports using IFileSystemObject and adds | |
899 | * "archive functionality" by delegating to a leveled import provider | |
900 | * (TarLeveledStructureProvider, ZipLeveledStructureProvider) | |
901 | */ | |
902 | private static class FileSystemObjectLeveledImportStructureProvider extends FileSystemObjectImportStructureProvider implements ILeveledImportStructureProvider { | |
903 | ||
904 | private ILeveledImportStructureProvider fLeveledImportProvider; | |
905 | ||
906 | private FileSystemObjectLeveledImportStructureProvider(ILeveledImportStructureProvider importStructureProvider, String archivePath) { | |
907 | super(importStructureProvider, archivePath); | |
908 | fLeveledImportProvider = importStructureProvider; | |
909 | } | |
910 | ||
911 | @Override | |
912 | public IFileSystemObject getRoot() { | |
913 | return getIFileSystemObject(fLeveledImportProvider.getRoot()); | |
914 | } | |
915 | ||
916 | @Override | |
917 | public void setStrip(int level) { | |
918 | fLeveledImportProvider.setStrip(level); | |
919 | } | |
920 | ||
921 | @Override | |
922 | public int getStrip() { | |
923 | return fLeveledImportProvider.getStrip(); | |
924 | } | |
925 | ||
926 | @Override | |
927 | public boolean closeArchive() { | |
928 | return fLeveledImportProvider.closeArchive(); | |
929 | } | |
930 | } | |
931 | ||
932 | @SuppressWarnings("resource") | |
933 | private boolean ensureZipSourceIsValid(String archivePath) { | |
934 | ZipFile specifiedFile = getSpecifiedZipSourceFile(archivePath); | |
935 | if (specifiedFile == null) { | |
936 | return false; | |
937 | } | |
938 | return ArchiveFileManipulations.closeZipFile(specifiedFile, getShell()); | |
939 | } | |
940 | ||
941 | private boolean ensureTarSourceIsValid(String archivePath) { | |
942 | TarFile specifiedFile = getSpecifiedTarSourceFile(archivePath); | |
943 | if (specifiedFile == null) { | |
944 | return false; | |
945 | } | |
946 | return ArchiveFileManipulations.closeTarFile(specifiedFile, getShell()); | |
947 | } | |
948 | ||
949 | private static ZipFile getSpecifiedZipSourceFile(String fileName) { | |
950 | if (fileName.length() == 0) { | |
951 | return null; | |
952 | } | |
953 | ||
954 | try { | |
955 | return new ZipFile(fileName); | |
956 | } catch (ZipException e) { | |
957 | // ignore | |
958 | } catch (IOException e) { | |
959 | // ignore | |
960 | } | |
961 | ||
962 | return null; | |
963 | } | |
964 | ||
965 | private static TarFile getSpecifiedTarSourceFile(String fileName) { | |
966 | if (fileName.length() == 0) { | |
002f9f07 BH |
967 | return null; |
968 | } | |
c8cf44dc MAL |
969 | |
970 | try { | |
971 | return new TarFile(fileName); | |
972 | } catch (TarException e) { | |
973 | // ignore | |
974 | } catch (IOException e) { | |
975 | // ignore | |
976 | } | |
977 | ||
978 | return null; | |
002f9f07 BH |
979 | } |
980 | ||
c8cf44dc MAL |
981 | private TraceFileSystemElement selectFiles(final IFileSystemObject rootFileSystemObject, |
982 | final FileSystemObjectImportStructureProvider structureProvider) { | |
252c602c | 983 | final TraceFileSystemElement[] results = new TraceFileSystemElement[1]; |
002f9f07 BH |
984 | BusyIndicator.showWhile(getShell().getDisplay(), new Runnable() { |
985 | @Override | |
986 | public void run() { | |
987 | // Create the root element from the supplied file system object | |
988 | results[0] = createRootElement(rootFileSystemObject, structureProvider); | |
989 | } | |
990 | }); | |
991 | return results[0]; | |
992 | } | |
993 | ||
c8cf44dc MAL |
994 | private static TraceFileSystemElement createRootElement(IFileSystemObject element, |
995 | FileSystemObjectImportStructureProvider provider) { | |
996 | boolean isContainer = provider.isFolder(element); | |
997 | String elementLabel = provider.getLabel(element); | |
002f9f07 | 998 | |
252c602c BH |
999 | // Use an empty label so that display of the element's full name |
1000 | // doesn't include a confusing label | |
c8cf44dc MAL |
1001 | TraceFileSystemElement dummyParent = new TraceFileSystemElement("", null, true, provider);//$NON-NLS-1$ |
1002 | Object dummyParentFileSystemObject = element; | |
1003 | Object rawFileSystemObject = element.getRawFileSystemObject(); | |
1004 | if (rawFileSystemObject instanceof File) { | |
1005 | dummyParentFileSystemObject = provider.getIFileSystemObject(((File) rawFileSystemObject).getParentFile()); | |
1006 | } | |
1007 | dummyParent.setFileSystemObject(dummyParentFileSystemObject); | |
252c602c BH |
1008 | dummyParent.setPopulated(); |
1009 | TraceFileSystemElement result = new TraceFileSystemElement( | |
c8cf44dc MAL |
1010 | elementLabel, dummyParent, isContainer, provider); |
1011 | result.setFileSystemObject(element); | |
002f9f07 | 1012 | |
ba560b10 | 1013 | // Get the files for the element so as to build the first level |
252c602c | 1014 | result.getFiles(); |
002f9f07 BH |
1015 | |
1016 | return dummyParent; | |
1017 | } | |
1018 | ||
1019 | // ------------------------------------------------------------------------ | |
1020 | // Trace Type Group | |
1021 | // ------------------------------------------------------------------------ | |
002f9f07 BH |
1022 | private final void createTraceTypeGroup(Composite parent) { |
1023 | Composite composite = new Composite(parent, SWT.NONE); | |
1024 | GridLayout layout = new GridLayout(); | |
1025 | layout.numColumns = 3; | |
1026 | layout.makeColumnsEqualWidth = false; | |
1027 | composite.setLayout(layout); | |
1028 | composite.setFont(parent.getFont()); | |
1029 | GridData buttonData = new GridData(SWT.FILL, SWT.FILL, true, false); | |
1030 | composite.setLayoutData(buttonData); | |
1031 | ||
1032 | // Trace type label ("Trace Type:") | |
1033 | Label typeLabel = new Label(composite, SWT.NONE); | |
1034 | typeLabel.setText(Messages.ImportTraceWizard_TraceType); | |
1035 | typeLabel.setFont(parent.getFont()); | |
1036 | ||
1037 | // Trace type combo | |
252c602c | 1038 | fTraceTypes = new Combo(composite, SWT.BORDER | SWT.READ_ONLY); |
002f9f07 BH |
1039 | GridData data = new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1); |
1040 | fTraceTypes.setLayoutData(data); | |
1041 | fTraceTypes.setFont(parent.getFont()); | |
1042 | ||
a4a116c3 | 1043 | String[] availableTraceTypes = TmfTraceType.getAvailableTraceTypes(); |
252c602c | 1044 | String[] traceTypeList = new String[availableTraceTypes.length + 1]; |
d0e34947 | 1045 | traceTypeList[0] = TRACE_TYPE_AUTO_DETECT; |
252c602c BH |
1046 | for (int i = 0; i < availableTraceTypes.length; i++) { |
1047 | traceTypeList[i + 1] = availableTraceTypes[i]; | |
1048 | } | |
1049 | fTraceTypes.setItems(traceTypeList); | |
e2a50e26 | 1050 | fTraceTypes.addSelectionListener(new SelectionAdapter() { |
002f9f07 BH |
1051 | @Override |
1052 | public void widgetSelected(SelectionEvent e) { | |
1053 | updateWidgetEnablements(); | |
d0e34947 | 1054 | boolean enabled = fTraceTypes.getText().equals(TRACE_TYPE_AUTO_DETECT); |
e2a50e26 | 1055 | fImportUnrecognizedButton.setEnabled(enabled); |
002f9f07 BH |
1056 | } |
1057 | }); | |
252c602c BH |
1058 | fTraceTypes.select(0); |
1059 | ||
16f91bd5 | 1060 | // Unrecognized checkbox |
252c602c BH |
1061 | fImportUnrecognizedButton = new Button(composite, SWT.CHECK); |
1062 | fImportUnrecognizedButton.setSelection(true); | |
1063 | fImportUnrecognizedButton.setText(Messages.ImportTraceWizard_ImportUnrecognized); | |
002f9f07 BH |
1064 | } |
1065 | ||
1066 | // ------------------------------------------------------------------------ | |
1067 | // Options | |
1068 | // ------------------------------------------------------------------------ | |
1069 | ||
002f9f07 BH |
1070 | @Override |
1071 | protected void createOptionsGroupButtons(Group optionsGroup) { | |
1072 | ||
1073 | // Overwrite checkbox | |
252c602c BH |
1074 | fOverwriteExistingResourcesCheckbox = new Button(optionsGroup, SWT.CHECK); |
1075 | fOverwriteExistingResourcesCheckbox.setFont(optionsGroup.getFont()); | |
1076 | fOverwriteExistingResourcesCheckbox.setText(Messages.ImportTraceWizard_OverwriteExistingTrace); | |
1077 | fOverwriteExistingResourcesCheckbox.setSelection(false); | |
002f9f07 BH |
1078 | |
1079 | // Create links checkbox | |
252c602c BH |
1080 | fCreateLinksInWorkspaceButton = new Button(optionsGroup, SWT.CHECK); |
1081 | fCreateLinksInWorkspaceButton.setFont(optionsGroup.getFont()); | |
1082 | fCreateLinksInWorkspaceButton.setText(Messages.ImportTraceWizard_CreateLinksInWorkspace); | |
1083 | fCreateLinksInWorkspaceButton.setSelection(true); | |
002f9f07 | 1084 | |
252c602c | 1085 | fCreateLinksInWorkspaceButton.addSelectionListener(new SelectionAdapter() { |
002f9f07 BH |
1086 | @Override |
1087 | public void widgetSelected(SelectionEvent e) { | |
1088 | updateWidgetEnablements(); | |
1089 | } | |
1090 | }); | |
1091 | ||
0e1d517e MAL |
1092 | fPreserveFolderStructureButton = new Button(optionsGroup, SWT.CHECK); |
1093 | fPreserveFolderStructureButton.setFont(optionsGroup.getFont()); | |
1094 | fPreserveFolderStructureButton.setText(Messages.ImportTraceWizard_PreserveFolderStructure); | |
1095 | fPreserveFolderStructureButton.setSelection(true); | |
1096 | ||
002f9f07 BH |
1097 | updateWidgetEnablements(); |
1098 | } | |
1099 | ||
1100 | // ------------------------------------------------------------------------ | |
1101 | // Determine if the finish button can be enabled | |
1102 | // ------------------------------------------------------------------------ | |
002f9f07 BH |
1103 | @Override |
1104 | public boolean validateSourceGroup() { | |
1105 | ||
d0e34947 | 1106 | File source = isImportFromDirectory() ? getSourceDirectory() : getSourceArchiveFile(); |
c8cf44dc | 1107 | if (source == null) { |
002f9f07 | 1108 | setMessage(Messages.ImportTraceWizard_SelectTraceSourceEmpty); |
c8cf44dc | 1109 | setErrorMessage(null); |
002f9f07 BH |
1110 | return false; |
1111 | } | |
1112 | ||
c8cf44dc | 1113 | if (sourceConflictsWithDestination(new Path(source.getPath()))) { |
002f9f07 BH |
1114 | setMessage(null); |
1115 | setErrorMessage(getSourceConflictMessage()); | |
1116 | return false; | |
1117 | } | |
1118 | ||
d0e34947 | 1119 | if (!isImportFromDirectory()) { |
c8cf44dc MAL |
1120 | if (!ensureTarSourceIsValid(source.getAbsolutePath()) && !ensureZipSourceIsValid(source.getAbsolutePath())) { |
1121 | setMessage(null); | |
1122 | setErrorMessage(Messages.ImportTraceWizard_BadArchiveFormat); | |
1123 | return false; | |
1124 | } | |
1125 | } | |
1126 | ||
282218e9 | 1127 | if (fSelectionGroup.getCheckedElementCount() == 0) { |
002f9f07 BH |
1128 | setMessage(null); |
1129 | setErrorMessage(Messages.ImportTraceWizard_SelectTraceNoneSelected); | |
1130 | return false; | |
1131 | } | |
1132 | ||
1133 | IContainer container = getSpecifiedContainer(); | |
1134 | if (container != null && container.isVirtual()) { | |
1135 | if (Platform.getPreferencesService().getBoolean(Activator.PLUGIN_ID, ResourcesPlugin.PREF_DISABLE_LINKING, false, null)) { | |
1136 | setMessage(null); | |
1137 | setErrorMessage(Messages.ImportTraceWizard_CannotImportFilesUnderAVirtualFolder); | |
1138 | return false; | |
1139 | } | |
252c602c | 1140 | if (fCreateLinksInWorkspaceButton == null || !fCreateLinksInWorkspaceButton.getSelection()) { |
002f9f07 BH |
1141 | setMessage(null); |
1142 | setErrorMessage(Messages.ImportTraceWizard_HaveToCreateLinksUnderAVirtualFolder); | |
1143 | return false; | |
1144 | } | |
1145 | } | |
1146 | ||
002f9f07 BH |
1147 | setErrorMessage(null); |
1148 | return true; | |
1149 | } | |
1150 | ||
d0e34947 MAL |
1151 | private boolean isImportFromDirectory() { |
1152 | return fImportFromDirectoryRadio != null && fImportFromDirectoryRadio.getSelection(); | |
1153 | } | |
1154 | ||
6781d5b9 BH |
1155 | @Override |
1156 | protected void restoreWidgetValues() { | |
1157 | super.restoreWidgetValues(); | |
1158 | ||
1159 | IDialogSettings settings = getDialogSettings(); | |
1160 | boolean value; | |
d0e34947 MAL |
1161 | if (fImportUnrecognizedButton != null) { |
1162 | if (settings.get(getPageStoreKey(IMPORT_WIZARD_IMPORT_UNRECOGNIZED_ID)) == null) { | |
1163 | value = true; | |
1164 | } else { | |
1165 | value = settings.getBoolean(getPageStoreKey(IMPORT_WIZARD_IMPORT_UNRECOGNIZED_ID)); | |
1166 | } | |
1167 | fImportUnrecognizedButton.setSelection(value); | |
6781d5b9 | 1168 | } |
6781d5b9 | 1169 | |
d0e34947 MAL |
1170 | if (fPreserveFolderStructureButton != null) { |
1171 | if (settings.get(getPageStoreKey(IMPORT_WIZARD_PRESERVE_FOLDERS_ID)) == null) { | |
1172 | value = true; | |
1173 | } else { | |
1174 | value = settings.getBoolean(getPageStoreKey(IMPORT_WIZARD_PRESERVE_FOLDERS_ID)); | |
1175 | } | |
1176 | fPreserveFolderStructureButton.setSelection(value); | |
6781d5b9 | 1177 | } |
6781d5b9 | 1178 | |
d0e34947 | 1179 | if (settings.get(getPageStoreKey(IMPORT_WIZARD_IMPORT_FROM_DIRECTORY_ID)) == null) { |
c8cf44dc MAL |
1180 | value = true; |
1181 | } else { | |
d0e34947 | 1182 | value = settings.getBoolean(getPageStoreKey(IMPORT_WIZARD_IMPORT_FROM_DIRECTORY_ID)); |
c8cf44dc | 1183 | } |
c8cf44dc | 1184 | |
d0e34947 MAL |
1185 | if (directoryNameField != null) { |
1186 | restoreComboValues(directoryNameField, settings, getPageStoreKey(IMPORT_WIZARD_ROOT_DIRECTORY_ID)); | |
1187 | } | |
1188 | if (fArchiveNameField != null) { | |
1189 | restoreComboValues(fArchiveNameField, settings, getPageStoreKey(IMPORT_WIZARD_ARCHIVE_FILE_NAME_ID)); | |
1190 | } | |
1191 | ||
1192 | if (fImportFromDirectoryRadio != null) { | |
1193 | fImportFromDirectoryRadio.setSelection(value); | |
1194 | if (value) { | |
1195 | directoryRadioSelected(); | |
1196 | } | |
1197 | } | |
1198 | if (fImportFromArchiveRadio != null) { | |
1199 | fImportFromArchiveRadio.setSelection(!value); | |
1200 | if (!value) { | |
1201 | archiveRadioSelected(); | |
1202 | } | |
6781d5b9 BH |
1203 | } |
1204 | } | |
1205 | ||
1206 | @Override | |
1207 | protected void saveWidgetValues() { | |
1208 | // Persist dialog settings | |
1209 | IDialogSettings settings = getDialogSettings(); | |
d0e34947 MAL |
1210 | if (fImportUnrecognizedButton != null) { |
1211 | settings.put(getPageStoreKey(IMPORT_WIZARD_IMPORT_UNRECOGNIZED_ID), fImportUnrecognizedButton.getSelection()); | |
1212 | } | |
1213 | if (fPreserveFolderStructureButton != null) { | |
1214 | settings.put(getPageStoreKey(IMPORT_WIZARD_PRESERVE_FOLDERS_ID), fPreserveFolderStructureButton.getSelection()); | |
1215 | } | |
1216 | settings.put(getPageStoreKey(IMPORT_WIZARD_IMPORT_FROM_DIRECTORY_ID), isImportFromDirectory()); | |
1217 | ||
1218 | if (directoryNameField != null) { | |
1219 | saveComboValues(directoryNameField, settings, getPageStoreKey(IMPORT_WIZARD_ROOT_DIRECTORY_ID)); | |
1220 | } | |
1221 | if (fArchiveNameField != null) { | |
1222 | saveComboValues(fArchiveNameField, settings, getPageStoreKey(IMPORT_WIZARD_ARCHIVE_FILE_NAME_ID)); | |
1223 | } | |
1224 | } | |
c8cf44dc | 1225 | |
d0e34947 MAL |
1226 | private String getPageStoreKey(String key) { |
1227 | return getName() + key; | |
c8cf44dc MAL |
1228 | } |
1229 | ||
1230 | private static void restoreComboValues(Combo combo, IDialogSettings settings, String key) { | |
1231 | String[] directoryNames = settings.getArray(key); | |
1232 | if ((directoryNames != null) && (directoryNames.length != 0)) { | |
1233 | for (int i = 0; i < directoryNames.length; i++) { | |
1234 | combo.add(directoryNames[i]); | |
1235 | } | |
1236 | } | |
1237 | } | |
6781d5b9 | 1238 | |
c8cf44dc MAL |
1239 | private void saveComboValues(Combo combo, IDialogSettings settings, String key) { |
1240 | // update names history | |
1241 | String[] directoryNames = settings.getArray(key); | |
6781d5b9 BH |
1242 | if (directoryNames == null) { |
1243 | directoryNames = new String[0]; | |
1244 | } | |
1245 | ||
c8cf44dc | 1246 | String items[] = combo.getItems(); |
6781d5b9 BH |
1247 | for (int i = 0; i < items.length; i++) { |
1248 | directoryNames = addToHistory(directoryNames, items[i]); | |
1249 | } | |
c8cf44dc | 1250 | settings.put(key, directoryNames); |
6781d5b9 BH |
1251 | } |
1252 | ||
002f9f07 BH |
1253 | // ------------------------------------------------------------------------ |
1254 | // Import the trace(s) | |
1255 | // ------------------------------------------------------------------------ | |
1256 | ||
1257 | /** | |
1258 | * Finish the import. | |
1259 | * | |
252c602c | 1260 | * @return <code>true</code> if successful else <code>false</code> |
002f9f07 BH |
1261 | */ |
1262 | public boolean finish() { | |
2b0005f0 | 1263 | String traceTypeLabel = getImportTraceTypeId(); |
252c602c | 1264 | String traceId = null; |
2b0005f0 PT |
1265 | if (!TRACE_TYPE_AUTO_DETECT.equals(traceTypeLabel)) { |
1266 | traceId = TmfTraceType.getTraceTypeId(traceTypeLabel); | |
002f9f07 BH |
1267 | } |
1268 | ||
6781d5b9 BH |
1269 | // Save dialog settings |
1270 | saveWidgetValues(); | |
002f9f07 | 1271 | |
c8cf44dc MAL |
1272 | IPath baseSourceContainerPath = new Path(getSourceContainerPath()); |
1273 | boolean importFromArchive = getSourceArchiveFile() != null; | |
d0e34947 MAL |
1274 | int importOptionFlags = getImportOptionFlags(); |
1275 | ||
c8cf44dc | 1276 | final TraceValidateAndImportOperation operation = new TraceValidateAndImportOperation(traceId, baseSourceContainerPath, getContainerFullPath(), importFromArchive, |
d0e34947 | 1277 | importOptionFlags); |
002f9f07 | 1278 | |
252c602c BH |
1279 | IStatus status = Status.OK_STATUS; |
1280 | try { | |
1281 | getContainer().run(true, true, new IRunnableWithProgress() { | |
1282 | @Override | |
1283 | public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { | |
1284 | operation.run(monitor); | |
1285 | monitor.done(); | |
002f9f07 | 1286 | } |
252c602c | 1287 | }); |
002f9f07 | 1288 | |
252c602c BH |
1289 | status = operation.getStatus(); |
1290 | } catch (InvocationTargetException e) { | |
1291 | status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.ImportTraceWizard_ImportProblem, e); | |
1292 | } catch (InterruptedException e) { | |
1293 | status = Status.CANCEL_STATUS; | |
ba560b10 MK |
1294 | } |
1295 | if (!status.isOK()) { | |
1296 | if (status.getSeverity() == IStatus.CANCEL) { | |
1297 | setMessage(Messages.ImportTraceWizard_ImportOperationCancelled); | |
1298 | setErrorMessage(null); | |
1299 | } else { | |
1300 | if (status.getException() != null) { | |
1301 | displayErrorDialog(status.getMessage() + ": " + status.getException()); //$NON-NLS-1$ | |
002f9f07 | 1302 | } |
ba560b10 MK |
1303 | setMessage(null); |
1304 | setErrorMessage(Messages.ImportTraceWizard_ImportProblem); | |
252c602c | 1305 | } |
ba560b10 | 1306 | return false; |
252c602c | 1307 | } |
252c602c BH |
1308 | setErrorMessage(null); |
1309 | return true; | |
1310 | } | |
002f9f07 | 1311 | |
d0e34947 MAL |
1312 | /** |
1313 | * Get the trace type id to import as. This can also return | |
1314 | * {@link #TRACE_TYPE_AUTO_DETECT} to communicate that automatic trace type | |
1315 | * detection will occur instead of setting a specific trace type when | |
1316 | * importing the traces. | |
1317 | * | |
1318 | * @return the trace type id or {@link #TRACE_TYPE_AUTO_DETECT} | |
1319 | */ | |
1320 | protected String getImportTraceTypeId() { | |
1321 | return fTraceTypes.getText(); | |
1322 | } | |
1323 | ||
1324 | /** | |
1325 | * Get import options in the form of flags (bits). | |
1326 | * | |
1327 | * @return the import flags. | |
1328 | * @see #OPTION_CREATE_LINKS_IN_WORKSPACE | |
1329 | * @see #OPTION_IMPORT_UNRECOGNIZED_TRACES | |
1330 | * @see #OPTION_OVERWRITE_EXISTING_RESOURCES | |
1331 | * @see #OPTION_PRESERVE_FOLDER_STRUCTURE | |
1332 | */ | |
1333 | protected int getImportOptionFlags() { | |
1334 | int flags = 0; | |
1335 | if (fCreateLinksInWorkspaceButton != null && fCreateLinksInWorkspaceButton.getSelection()) { | |
1336 | flags |= OPTION_CREATE_LINKS_IN_WORKSPACE; | |
1337 | } | |
1338 | if (fImportUnrecognizedButton != null && fImportUnrecognizedButton.getSelection()) { | |
1339 | flags |= OPTION_IMPORT_UNRECOGNIZED_TRACES; | |
1340 | } | |
1341 | if (fOverwriteExistingResourcesCheckbox != null && fOverwriteExistingResourcesCheckbox.getSelection()) { | |
1342 | flags |= OPTION_OVERWRITE_EXISTING_RESOURCES; | |
1343 | } | |
1344 | if (fPreserveFolderStructureButton != null && fPreserveFolderStructureButton.getSelection()) { | |
1345 | flags |= OPTION_PRESERVE_FOLDER_STRUCTURE; | |
1346 | } | |
1347 | return flags; | |
1348 | } | |
1349 | ||
c8cf44dc MAL |
1350 | @Override |
1351 | public void dispose() { | |
1352 | super.dispose(); | |
1353 | disposeSelectionGroupRoot(); | |
1354 | } | |
252c602c BH |
1355 | |
1356 | // ------------------------------------------------------------------------ | |
1357 | // Classes | |
1358 | // ------------------------------------------------------------------------ | |
1359 | ||
16f91bd5 | 1360 | private class TraceValidateAndImportOperation { |
252c602c | 1361 | private IStatus fStatus; |
252c602c | 1362 | private String fTraceType; |
0e1d517e MAL |
1363 | private IPath fDestinationContainerPath; |
1364 | private IPath fBaseSourceContainerPath; | |
c8cf44dc | 1365 | private boolean fImportFromArchive; |
d0e34947 | 1366 | private int fImportOptionFlags; |
72041d61 | 1367 | private ImportConflictHandler fConflictHandler; |
252c602c | 1368 | |
d0e34947 | 1369 | private TraceValidateAndImportOperation(String traceId, IPath baseSourceContainerPath, IPath destinationContainerPath, boolean importFromArchive, int importOptionFlags) { |
252c602c | 1370 | fTraceType = traceId; |
0e1d517e MAL |
1371 | fBaseSourceContainerPath = baseSourceContainerPath; |
1372 | fDestinationContainerPath = destinationContainerPath; | |
d0e34947 | 1373 | fImportOptionFlags = importOptionFlags; |
c8cf44dc | 1374 | fImportFromArchive = importFromArchive; |
d0e34947 MAL |
1375 | |
1376 | boolean overwriteExistingResources = (importOptionFlags & OPTION_OVERWRITE_EXISTING_RESOURCES) != 0; | |
1377 | if (overwriteExistingResources) { | |
72041d61 BH |
1378 | fConflictHandler = new ImportConflictHandler(getContainer().getShell(), fTraceFolderElement, ImportConfirmation.OVERWRITE_ALL); |
1379 | } else { | |
1380 | fConflictHandler = new ImportConflictHandler(getContainer().getShell(), fTraceFolderElement, ImportConfirmation.SKIP); | |
16f91bd5 | 1381 | } |
252c602c BH |
1382 | } |
1383 | ||
1384 | public void run(IProgressMonitor progressMonitor) { | |
1385 | String currentPath = null; | |
252c602c | 1386 | try { |
29ceb238 BH |
1387 | |
1388 | final ArrayList<TraceFileSystemElement> fileSystemElements = new ArrayList<>(); | |
1389 | IElementFilter passThroughFilter = new IElementFilter() { | |
1390 | ||
1391 | @Override | |
1392 | public void filterElements(Collection elements, IProgressMonitor monitor) { | |
1393 | fileSystemElements.addAll(elements); | |
1394 | } | |
ba560b10 | 1395 | |
29ceb238 BH |
1396 | @Override |
1397 | public void filterElements(Object[] elements, IProgressMonitor monitor) { | |
1398 | for (int i = 0; i < elements.length; i++) { | |
ba560b10 | 1399 | fileSystemElements.add((TraceFileSystemElement) elements[i]); |
29ceb238 BH |
1400 | } |
1401 | } | |
1402 | }; | |
1403 | ||
ba560b10 MK |
1404 | // List fileSystemElements will be filled using the |
1405 | // passThroughFilter | |
29ceb238 | 1406 | SubMonitor subMonitor = SubMonitor.convert(progressMonitor, 1); |
282218e9 | 1407 | fSelectionGroup.getAllCheckedListItems(passThroughFilter, subMonitor); |
29ceb238 BH |
1408 | |
1409 | // Check if operation was cancelled. | |
1410 | ModalContext.checkCanceled(subMonitor); | |
1411 | ||
16f91bd5 | 1412 | Iterator<TraceFileSystemElement> fileSystemElementsIter = fileSystemElements.iterator(); |
c8cf44dc | 1413 | IFolder destTempFolder = null; |
29ceb238 | 1414 | subMonitor = SubMonitor.convert(progressMonitor, fileSystemElements.size()); |
c8cf44dc MAL |
1415 | if (fImportFromArchive) { |
1416 | // When importing from archive, we first extract the | |
1417 | // *selected* files to a temporary folder then create a new | |
1418 | // Iterator<TraceFileSystemElement> that points to the | |
1419 | // extracted files. This way, the import operator can | |
1420 | // continue as it normally would. | |
1421 | ||
1422 | subMonitor = SubMonitor.convert(progressMonitor, fileSystemElements.size() * 2); | |
1423 | destTempFolder = fTargetFolder.getProject().getFolder(TRACE_IMPORT_TEMP_FOLDER); | |
1424 | if (destTempFolder.exists()) { | |
1425 | SubProgressMonitor monitor = new SubProgressMonitor(subMonitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK); | |
1426 | destTempFolder.delete(true, monitor); | |
1427 | } | |
1428 | SubProgressMonitor monitor = new SubProgressMonitor(subMonitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK); | |
1429 | destTempFolder.create(IResource.HIDDEN, true, monitor); | |
1430 | ||
1431 | fileSystemElementsIter = extractSelectedFiles(fileSystemElementsIter, destTempFolder, subMonitor); | |
1432 | // We need to update the source container path because the | |
1433 | // "preserve folder structure" option would create the | |
1434 | // wrong folders otherwise. | |
1435 | fBaseSourceContainerPath = destTempFolder.getLocation(); | |
1436 | } | |
252c602c | 1437 | |
9bc16b84 BH |
1438 | // Map to remember already imported directory traces |
1439 | final Map<String, TraceFileSystemElement> directoryTraces = new HashMap<>(); | |
16f91bd5 | 1440 | while (fileSystemElementsIter.hasNext()) { |
252c602c BH |
1441 | ModalContext.checkCanceled(progressMonitor); |
1442 | currentPath = null; | |
16f91bd5 | 1443 | TraceFileSystemElement element = fileSystemElementsIter.next(); |
c8cf44dc MAL |
1444 | IFileSystemObject fileSystemObject = element.getFileSystemObject(); |
1445 | String resourcePath = element.getFileSystemObject().getAbsolutePath(fBaseSourceContainerPath.toOSString()); | |
0e1d517e MAL |
1446 | element.setDestinationContainerPath(computeDestinationContainerPath(new Path(resourcePath))); |
1447 | ||
252c602c BH |
1448 | currentPath = resourcePath; |
1449 | SubMonitor sub = subMonitor.newChild(1); | |
16f91bd5 | 1450 | if (element.isDirectory()) { |
9bc16b84 | 1451 | if (!directoryTraces.containsKey(resourcePath)) { |
16f91bd5 | 1452 | if (isDirectoryTrace(element)) { |
9bc16b84 | 1453 | directoryTraces.put(resourcePath, element); |
c659283d | 1454 | validateAndImportTrace(element, sub); |
252c602c BH |
1455 | } |
1456 | } | |
1457 | } else { | |
ba560b10 | 1458 | TraceFileSystemElement parentElement = (TraceFileSystemElement) element.getParent(); |
c8cf44dc | 1459 | String parentPath = parentElement.getFileSystemObject().getAbsolutePath(fBaseSourceContainerPath.toOSString()); |
0e1d517e | 1460 | parentElement.setDestinationContainerPath(computeDestinationContainerPath(new Path(parentPath))); |
252c602c | 1461 | currentPath = parentPath; |
9bc16b84 | 1462 | if (!directoryTraces.containsKey(parentPath)) { |
16f91bd5 | 1463 | if (isDirectoryTrace(parentElement)) { |
9bc16b84 | 1464 | directoryTraces.put(parentPath, parentElement); |
c659283d | 1465 | validateAndImportTrace(parentElement, sub); |
252c602c | 1466 | } else { |
9bc16b84 BH |
1467 | boolean validateFile = true; |
1468 | TraceFileSystemElement grandParentElement = (TraceFileSystemElement) parentElement.getParent(); | |
1469 | // Special case for LTTng trace that may contain index directory and files | |
1470 | if (grandParentElement != null) { | |
1471 | String grandParentPath = grandParentElement.getFileSystemObject().getAbsolutePath(fBaseSourceContainerPath.toOSString()); | |
1472 | grandParentElement.setDestinationContainerPath(computeDestinationContainerPath(new Path(parentPath))); | |
1473 | currentPath = grandParentPath; | |
1474 | if (directoryTraces.containsKey(grandParentPath)) { | |
1475 | validateFile = false; | |
1476 | } else if (isDirectoryTrace(grandParentElement)) { | |
1477 | directoryTraces.put(grandParentPath, grandParentElement); | |
1478 | validateAndImportTrace(grandParentElement, sub); | |
1479 | validateFile = false; | |
1480 | } | |
1481 | } | |
1482 | if (validateFile && (fileSystemObject.exists())) { | |
c659283d | 1483 | validateAndImportTrace(element, sub); |
002f9f07 | 1484 | } |
002f9f07 BH |
1485 | } |
1486 | } | |
1487 | } | |
1488 | } | |
c8cf44dc MAL |
1489 | |
1490 | if (destTempFolder != null && destTempFolder.exists()) { | |
1491 | destTempFolder.delete(true, progressMonitor); | |
1492 | } | |
1493 | ||
252c602c BH |
1494 | setStatus(Status.OK_STATUS); |
1495 | } catch (InterruptedException e) { | |
1496 | setStatus(Status.CANCEL_STATUS); | |
1497 | } catch (Exception e) { | |
0e1d517e MAL |
1498 | String errorMessage = Messages.ImportTraceWizard_ImportProblem + ": " + //$NON-NLS-1$ |
1499 | (currentPath != null ? currentPath : ""); //$NON-NLS-1$ | |
1500 | Activator.getDefault().logError(errorMessage, e); | |
ba560b10 | 1501 | setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, errorMessage, e)); |
0e1d517e MAL |
1502 | } |
1503 | } | |
1504 | ||
c8cf44dc MAL |
1505 | private Iterator<TraceFileSystemElement> extractSelectedFiles(Iterator<TraceFileSystemElement> fileSystemElementsIter, IFolder tempFolder, IProgressMonitor progressMonitor) throws InterruptedException, |
1506 | InvocationTargetException { | |
1507 | List<TraceFileSystemElement> subList = new ArrayList<>(); | |
5609386c | 1508 | Map<IPath, String> sourceLocationMap = new HashMap<>(); |
c8cf44dc MAL |
1509 | // Collect all the elements |
1510 | while (fileSystemElementsIter.hasNext()) { | |
1511 | ModalContext.checkCanceled(progressMonitor); | |
1512 | TraceFileSystemElement element = fileSystemElementsIter.next(); | |
5609386c PT |
1513 | sourceLocationMap.put(new Path(element.getFileSystemObject().getName()).removeTrailingSeparator(), element.getSourceLocation()); |
1514 | TraceFileSystemElement parentElement = (TraceFileSystemElement) element.getParent(); | |
1515 | sourceLocationMap.put(new Path(parentElement.getFileSystemObject().getName()).removeTrailingSeparator(), parentElement.getSourceLocation()); | |
c8cf44dc MAL |
1516 | if (element.isDirectory()) { |
1517 | Object[] array = element.getFiles().getChildren(); | |
1518 | for (int i = 0; i < array.length; i++) { | |
ba560b10 | 1519 | subList.add((TraceFileSystemElement) array[i]); |
c8cf44dc MAL |
1520 | } |
1521 | } | |
1522 | subList.add(element); | |
1523 | } | |
1524 | ||
1525 | // Find a sensible root element | |
1526 | TraceFileSystemElement root = subList.get(0); | |
1527 | while (root.getParent() != null) { | |
1528 | root = (TraceFileSystemElement) root.getParent(); | |
1529 | } | |
1530 | ||
1531 | ImportProvider fileSystemStructureProvider = new ImportProvider(); | |
1532 | ||
1533 | IOverwriteQuery myQueryImpl = new IOverwriteQuery() { | |
1534 | @Override | |
1535 | public String queryOverwrite(String file) { | |
1536 | return IOverwriteQuery.NO_ALL; | |
1537 | } | |
1538 | }; | |
1539 | ||
1540 | progressMonitor.setTaskName(Messages.ImportTraceWizard_ExtractImportOperationTaskName); | |
1541 | IPath containerPath = tempFolder.getFullPath(); | |
1542 | ImportOperation operation = new ImportOperation(containerPath, root, fileSystemStructureProvider, myQueryImpl, subList); | |
1543 | operation.setContext(getShell()); | |
1544 | ||
1545 | operation.setCreateContainerStructure(true); | |
1546 | operation.setOverwriteResources(false); | |
1547 | operation.setVirtualFolders(false); | |
1548 | ||
1549 | operation.run(new SubProgressMonitor(progressMonitor, subList.size(), SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK)); | |
1550 | ||
ba560b10 MK |
1551 | // Create the new import provider and root element based on the |
1552 | // extracted temp folder | |
c8cf44dc MAL |
1553 | FileSystemObjectImportStructureProvider importStructureProvider = new FileSystemObjectImportStructureProvider(FileSystemStructureProvider.INSTANCE, null); |
1554 | IFileSystemObject rootElement = importStructureProvider.getIFileSystemObject(new File(tempFolder.getLocation().toOSString())); | |
1555 | TraceFileSystemElement createRootElement = createRootElement(rootElement, importStructureProvider); | |
1556 | List<TraceFileSystemElement> list = new ArrayList<>(); | |
1557 | getAllChildren(list, createRootElement); | |
1558 | Iterator<TraceFileSystemElement> extractedElementsIter = list.iterator(); | |
5609386c PT |
1559 | IPath tempPath = new Path(tempFolder.getLocation().toOSString()); |
1560 | for (TraceFileSystemElement element : list) { | |
1561 | IPath path = new Path(((File) element.getFileSystemObject().getRawFileSystemObject()).getAbsolutePath()).makeRelativeTo(tempPath); | |
1562 | element.setSourceLocation(sourceLocationMap.get(path)); | |
1563 | TraceFileSystemElement parentElement = (TraceFileSystemElement) element.getParent(); | |
1564 | IPath parentPath = new Path(((File) parentElement.getFileSystemObject().getRawFileSystemObject()).getAbsolutePath()).makeRelativeTo(tempPath); | |
1565 | parentElement.setSourceLocation(sourceLocationMap.get(parentPath)); | |
1566 | } | |
c8cf44dc MAL |
1567 | return extractedElementsIter; |
1568 | } | |
1569 | ||
1570 | /** | |
1571 | * Get all the TraceFileSystemElements recursively. | |
1572 | * | |
1573 | * @param result | |
1574 | * the list accumulating the result | |
1575 | * @param rootElement | |
1576 | * the root element of the file system to be imported | |
1577 | */ | |
1578 | private void getAllChildren(List<TraceFileSystemElement> result, TraceFileSystemElement rootElement) { | |
1579 | AdaptableList files = rootElement.getFiles(); | |
1580 | for (Object file : files.getChildren()) { | |
1581 | result.add((TraceFileSystemElement) file); | |
1582 | } | |
1583 | ||
1584 | AdaptableList folders = rootElement.getFolders(); | |
1585 | for (Object folder : folders.getChildren()) { | |
ba560b10 | 1586 | getAllChildren(result, (TraceFileSystemElement) folder); |
c8cf44dc MAL |
1587 | } |
1588 | } | |
1589 | ||
0e1d517e MAL |
1590 | private IPath computeDestinationContainerPath(Path resourcePath) { |
1591 | IPath destinationContainerPath = fDestinationContainerPath; | |
1592 | ||
ba560b10 MK |
1593 | // We need to figure out the new destination path relative to the |
1594 | // selected "base" source directory. | |
0e1d517e | 1595 | // Here for example, the selected source directory is /home/user |
d0e34947 | 1596 | if ((fImportOptionFlags & OPTION_PRESERVE_FOLDER_STRUCTURE) != 0) { |
0e1d517e MAL |
1597 | // /home/user/bar/foo/trace -> /home/user/bar/foo |
1598 | IPath sourceContainerPath = resourcePath.removeLastSegments(1); | |
1599 | if (fBaseSourceContainerPath.equals(resourcePath)) { | |
ba560b10 MK |
1600 | // Use resourcePath directory if fBaseSourceContainerPath |
1601 | // points to a directory trace | |
0e1d517e MAL |
1602 | sourceContainerPath = resourcePath; |
1603 | } | |
1604 | // /home/user/bar/foo, /home/user -> bar/foo | |
1605 | IPath relativeContainerPath = sourceContainerPath.makeRelativeTo(fBaseSourceContainerPath); | |
1606 | // project/Traces + bar/foo -> project/Traces/bar/foo | |
1607 | destinationContainerPath = fDestinationContainerPath.append(relativeContainerPath); | |
002f9f07 | 1608 | } |
0e1d517e | 1609 | return destinationContainerPath; |
002f9f07 BH |
1610 | } |
1611 | ||
c659283d | 1612 | private void validateAndImportTrace(TraceFileSystemElement fileSystemElement, IProgressMonitor monitor) |
252c602c | 1613 | throws TmfTraceImportException, CoreException, InvocationTargetException, InterruptedException { |
c8cf44dc MAL |
1614 | String parentContainerPath = fBaseSourceContainerPath.toOSString(); |
1615 | String path = fileSystemElement.getFileSystemObject().getAbsolutePath(parentContainerPath); | |
350cae41 | 1616 | TraceTypeHelper traceTypeHelper = null; |
c659283d | 1617 | |
252c602c | 1618 | if (fTraceType == null) { |
c659283d | 1619 | // Auto Detection |
350cae41 PT |
1620 | try { |
1621 | traceTypeHelper = TmfTraceTypeUIUtils.selectTraceType(path, null, null); | |
1622 | } catch (TmfTraceImportException e) { | |
1623 | // the trace did not match any trace type | |
1624 | } | |
1625 | if (traceTypeHelper == null) { | |
d0e34947 | 1626 | if ((fImportOptionFlags & OPTION_IMPORT_UNRECOGNIZED_TRACES) != 0) { |
98bb2f6a | 1627 | importResource(fileSystemElement, monitor); |
350cae41 PT |
1628 | } |
1629 | return; | |
1630 | } | |
252c602c | 1631 | } else { |
a4a116c3 | 1632 | boolean isDirectoryTraceType = TmfTraceType.isDirectoryTraceType(fTraceType); |
c659283d | 1633 | if (fileSystemElement.isDirectory() != isDirectoryTraceType) { |
252c602c BH |
1634 | return; |
1635 | } | |
a4a116c3 | 1636 | traceTypeHelper = TmfTraceType.getTraceType(fTraceType); |
16f91bd5 | 1637 | |
350cae41 | 1638 | if (traceTypeHelper == null) { |
c659283d BH |
1639 | // Trace type not found |
1640 | throw new TmfTraceImportException(Messages.ImportTraceWizard_TraceTypeNotFound); | |
252c602c | 1641 | } |
c659283d | 1642 | |
a8ddd783 | 1643 | if (!traceTypeHelper.validate(path).isOK()) { |
c659283d | 1644 | // Trace type exist but doesn't validate for given trace. |
350cae41 PT |
1645 | return; |
1646 | } | |
252c602c | 1647 | } |
002f9f07 | 1648 | |
c659283d | 1649 | // Finally import trace |
0e1d517e MAL |
1650 | IResource importedResource = importResource(fileSystemElement, monitor); |
1651 | if (importedResource != null) { | |
1652 | TmfTraceTypeUIUtils.setTraceType(importedResource, traceTypeHelper); | |
002f9f07 | 1653 | } |
002f9f07 | 1654 | |
252c602c | 1655 | } |
002f9f07 | 1656 | |
16f91bd5 BH |
1657 | /** |
1658 | * Imports a trace resource to project. In case of name collision the | |
1659 | * user will be asked to confirm overwriting the existing trace, | |
1660 | * overwriting or skipping the trace to be imported. | |
1661 | * | |
1662 | * @param fileSystemElement | |
1663 | * trace file system object to import | |
1664 | * @param monitor | |
1665 | * a progress monitor | |
0e1d517e | 1666 | * @return the imported resource or null if no resource was imported |
16f91bd5 BH |
1667 | * |
1668 | * @throws InvocationTargetException | |
1669 | * if problems during import operation | |
1670 | * @throws InterruptedException | |
1671 | * if cancelled | |
1672 | * @throws CoreException | |
1673 | * if problems with workspace | |
1674 | */ | |
0e1d517e | 1675 | private IResource importResource(TraceFileSystemElement fileSystemElement, IProgressMonitor monitor) |
16f91bd5 | 1676 | throws InvocationTargetException, InterruptedException, CoreException { |
0e1d517e | 1677 | |
72041d61 BH |
1678 | IPath tracePath = getInitialDestinationPath(fileSystemElement); |
1679 | String newName = fConflictHandler.checkAndHandleNameClash(tracePath, monitor); | |
1680 | if (newName == null) { | |
0e1d517e | 1681 | return null; |
16f91bd5 | 1682 | } |
72041d61 | 1683 | fileSystemElement.setLabel(newName); |
16f91bd5 BH |
1684 | |
1685 | List<TraceFileSystemElement> subList = new ArrayList<>(); | |
1686 | ||
16f91bd5 BH |
1687 | FileSystemElement parentFolder = fileSystemElement.getParent(); |
1688 | ||
0e1d517e | 1689 | IPath containerPath = fileSystemElement.getDestinationContainerPath(); |
72041d61 | 1690 | tracePath = containerPath.addTrailingSeparator().append(fileSystemElement.getLabel()); |
d0e34947 MAL |
1691 | boolean createLinksInWorkspace = (fImportOptionFlags & OPTION_CREATE_LINKS_IN_WORKSPACE) != 0; |
1692 | if (fileSystemElement.isDirectory() && !createLinksInWorkspace) { | |
0e1d517e | 1693 | containerPath = tracePath; |
16f91bd5 BH |
1694 | |
1695 | Object[] array = fileSystemElement.getFiles().getChildren(); | |
1696 | for (int i = 0; i < array.length; i++) { | |
ba560b10 | 1697 | subList.add((TraceFileSystemElement) array[i]); |
16f91bd5 BH |
1698 | } |
1699 | parentFolder = fileSystemElement; | |
1700 | ||
1701 | } else { | |
1702 | subList.add(fileSystemElement); | |
1703 | } | |
1704 | ||
16f91bd5 | 1705 | ImportProvider fileSystemStructureProvider = new ImportProvider(); |
252c602c | 1706 | |
252c602c BH |
1707 | IOverwriteQuery myQueryImpl = new IOverwriteQuery() { |
1708 | @Override | |
1709 | public String queryOverwrite(String file) { | |
16f91bd5 | 1710 | return IOverwriteQuery.NO_ALL; |
252c602c BH |
1711 | } |
1712 | }; | |
1713 | ||
c8cf44dc | 1714 | monitor.setTaskName(Messages.ImportTraceWizard_ImportOperationTaskName + " " + fileSystemElement.getFileSystemObject().getAbsolutePath(fBaseSourceContainerPath.toOSString())); //$NON-NLS-1$ |
16f91bd5 | 1715 | ImportOperation operation = new ImportOperation(containerPath, parentFolder, fileSystemStructureProvider, myQueryImpl, subList); |
002f9f07 | 1716 | operation.setContext(getShell()); |
002f9f07 | 1717 | |
252c602c | 1718 | operation.setCreateContainerStructure(false); |
16f91bd5 | 1719 | operation.setOverwriteResources(false); |
d0e34947 | 1720 | operation.setCreateLinks(createLinksInWorkspace); |
252c602c | 1721 | operation.setVirtualFolders(false); |
002f9f07 | 1722 | |
252c602c | 1723 | operation.run(new SubProgressMonitor(monitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK)); |
5609386c | 1724 | String sourceLocation = fileSystemElement.getSourceLocation(); |
0e1d517e | 1725 | IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(tracePath); |
c8cf44dc MAL |
1726 | if (sourceLocation != null) { |
1727 | resource.setPersistentProperty(TmfCommonConstants.SOURCE_LOCATION, sourceLocation); | |
1728 | } | |
89730b51 | 1729 | |
0e1d517e | 1730 | return resource; |
16f91bd5 | 1731 | } |
002f9f07 | 1732 | |
c8cf44dc MAL |
1733 | private boolean isDirectoryTrace(TraceFileSystemElement fileSystemElement) { |
1734 | String path = fileSystemElement.getFileSystemObject().getAbsolutePath(fBaseSourceContainerPath.toOSString()); | |
a4a116c3 | 1735 | if (TmfTraceType.isDirectoryTrace(path)) { |
252c602c BH |
1736 | return true; |
1737 | } | |
002f9f07 BH |
1738 | return false; |
1739 | } | |
1740 | ||
0e1d517e MAL |
1741 | /** |
1742 | * @return the initial destination path, before rename, if any | |
1743 | */ | |
1744 | private IPath getInitialDestinationPath(TraceFileSystemElement fileSystemElement) { | |
1745 | IPath traceFolderPath = fileSystemElement.getDestinationContainerPath(); | |
c8cf44dc | 1746 | return traceFolderPath.append(fileSystemElement.getFileSystemObject().getLabel()); |
0e1d517e MAL |
1747 | } |
1748 | ||
252c602c BH |
1749 | /** |
1750 | * Set the status for this operation | |
1751 | * | |
1752 | * @param status | |
1753 | * the status | |
1754 | */ | |
1755 | protected void setStatus(IStatus status) { | |
1756 | fStatus = status; | |
002f9f07 BH |
1757 | } |
1758 | ||
252c602c BH |
1759 | public IStatus getStatus() { |
1760 | return fStatus; | |
1761 | } | |
002f9f07 BH |
1762 | } |
1763 | ||
252c602c | 1764 | /** |
ba560b10 MK |
1765 | * The <code>TraceFileSystemElement</code> is a |
1766 | * <code>FileSystemElement</code> that knows if it has been populated or | |
1767 | * not. | |
252c602c | 1768 | */ |
16f91bd5 | 1769 | private static class TraceFileSystemElement extends FileSystemElement { |
252c602c | 1770 | |
16f91bd5 BH |
1771 | private boolean fIsPopulated = false; |
1772 | private String fLabel = null; | |
0e1d517e | 1773 | private IPath fDestinationContainerPath; |
c8cf44dc | 1774 | private FileSystemObjectImportStructureProvider fProvider; |
5609386c | 1775 | private String fSourceLocation; |
252c602c | 1776 | |
c8cf44dc | 1777 | public TraceFileSystemElement(String name, FileSystemElement parent, boolean isDirectory, FileSystemObjectImportStructureProvider provider) { |
252c602c | 1778 | super(name, parent, isDirectory); |
c8cf44dc | 1779 | fProvider = provider; |
252c602c BH |
1780 | } |
1781 | ||
0e1d517e MAL |
1782 | public void setDestinationContainerPath(IPath destinationContainerPath) { |
1783 | fDestinationContainerPath = destinationContainerPath; | |
1784 | } | |
1785 | ||
252c602c | 1786 | public void setPopulated() { |
16f91bd5 | 1787 | fIsPopulated = true; |
252c602c BH |
1788 | } |
1789 | ||
1790 | public boolean isPopulated() { | |
16f91bd5 | 1791 | return fIsPopulated; |
252c602c BH |
1792 | } |
1793 | ||
1794 | @Override | |
1795 | public AdaptableList getFiles() { | |
ba560b10 | 1796 | if (!fIsPopulated) { |
252c602c BH |
1797 | populateElementChildren(); |
1798 | } | |
1799 | return super.getFiles(); | |
1800 | } | |
1801 | ||
1802 | @Override | |
1803 | public AdaptableList getFolders() { | |
ba560b10 | 1804 | if (!fIsPopulated) { |
252c602c BH |
1805 | populateElementChildren(); |
1806 | } | |
1807 | return super.getFolders(); | |
1808 | } | |
002f9f07 | 1809 | |
16f91bd5 BH |
1810 | /** |
1811 | * Sets the label for the trace to be used when importing at trace. | |
ba560b10 | 1812 | * |
16f91bd5 BH |
1813 | * @param name |
1814 | * the label for the trace | |
1815 | */ | |
1816 | public void setLabel(String name) { | |
1817 | fLabel = name; | |
1818 | } | |
1819 | ||
1820 | /** | |
1821 | * Returns the label for the trace to be used when importing at trace. | |
1822 | * | |
1823 | * @return the label of trace resource | |
1824 | */ | |
1825 | public String getLabel() { | |
1826 | if (fLabel == null) { | |
c8cf44dc | 1827 | return getFileSystemObject().getLabel(); |
16f91bd5 BH |
1828 | } |
1829 | return fLabel; | |
1830 | } | |
1831 | ||
0e1d517e MAL |
1832 | /** |
1833 | * The full path to the container that will contain the trace | |
1834 | * | |
1835 | * @return the destination container path | |
1836 | */ | |
1837 | public IPath getDestinationContainerPath() { | |
1838 | return fDestinationContainerPath; | |
1839 | } | |
1840 | ||
252c602c | 1841 | /** |
ba560b10 MK |
1842 | * Populates the children of the specified parent |
1843 | * <code>FileSystemElement</code> | |
252c602c BH |
1844 | */ |
1845 | private void populateElementChildren() { | |
c8cf44dc MAL |
1846 | List<IFileSystemObject> allchildren = fProvider.getChildren(this.getFileSystemObject()); |
1847 | Object child = null; | |
252c602c | 1848 | TraceFileSystemElement newelement = null; |
c8cf44dc | 1849 | Iterator<IFileSystemObject> iter = allchildren.iterator(); |
ba560b10 | 1850 | while (iter.hasNext()) { |
252c602c | 1851 | child = iter.next(); |
c8cf44dc | 1852 | newelement = new TraceFileSystemElement(fProvider.getLabel(child), this, fProvider.isFolder(child), fProvider); |
252c602c BH |
1853 | newelement.setFileSystemObject(child); |
1854 | } | |
1855 | setPopulated(); | |
1856 | } | |
c8cf44dc MAL |
1857 | |
1858 | public FileSystemObjectImportStructureProvider getProvider() { | |
1859 | return fProvider; | |
1860 | } | |
1861 | ||
1862 | @Override | |
1863 | public IFileSystemObject getFileSystemObject() { | |
1864 | Object fileSystemObject = super.getFileSystemObject(); | |
1865 | return (IFileSystemObject) fileSystemObject; | |
1866 | } | |
5609386c PT |
1867 | |
1868 | public String getSourceLocation() { | |
1869 | if (fSourceLocation == null) { | |
1870 | fSourceLocation = getFileSystemObject().getSourceLocation(); | |
1871 | } | |
1872 | return fSourceLocation; | |
1873 | } | |
1874 | ||
1875 | public void setSourceLocation(String sourceLocation) { | |
1876 | fSourceLocation = sourceLocation; | |
1877 | } | |
252c602c | 1878 | } |
16f91bd5 | 1879 | |
c8cf44dc MAL |
1880 | /** |
1881 | * This interface abstracts the differences between different kinds of | |
1882 | * FileSystemObjects such as File, TarEntry and ZipEntry. This allows | |
1883 | * clients (TraceFileSystemElement, TraceValidateAndImportOperation) to | |
1884 | * handle all the types transparently. | |
1885 | */ | |
1886 | private interface IFileSystemObject { | |
1887 | String getLabel(); | |
ba560b10 | 1888 | |
5609386c PT |
1889 | String getName(); |
1890 | ||
c8cf44dc | 1891 | String getAbsolutePath(String parentContainerPath); |
ba560b10 | 1892 | |
c8cf44dc | 1893 | String getSourceLocation(); |
ba560b10 | 1894 | |
c8cf44dc | 1895 | Object getRawFileSystemObject(); |
ba560b10 | 1896 | |
c8cf44dc MAL |
1897 | boolean exists(); |
1898 | } | |
1899 | ||
1900 | /** | |
1901 | * The "File" implementation of an IFileSystemObject | |
1902 | */ | |
1903 | private static class FileFileSystemObject implements IFileSystemObject { | |
1904 | ||
1905 | private File fFileSystemObject; | |
1906 | ||
1907 | private FileFileSystemObject(File fileSystemObject) { | |
1908 | fFileSystemObject = fileSystemObject; | |
1909 | } | |
1910 | ||
1911 | @Override | |
1912 | public String getLabel() { | |
1913 | String name = fFileSystemObject.getName(); | |
1914 | if (name.length() == 0) { | |
1915 | return fFileSystemObject.getPath(); | |
1916 | } | |
1917 | return name; | |
1918 | } | |
1919 | ||
5609386c PT |
1920 | @Override |
1921 | public String getName() { | |
1922 | return fFileSystemObject.getName(); | |
1923 | } | |
1924 | ||
c8cf44dc MAL |
1925 | @Override |
1926 | public String getAbsolutePath(String parentContainerPath) { | |
1927 | return fFileSystemObject.getAbsolutePath(); | |
1928 | } | |
1929 | ||
1930 | @Override | |
1931 | public boolean exists() { | |
1932 | return fFileSystemObject.exists(); | |
1933 | } | |
1934 | ||
1935 | @Override | |
1936 | public String getSourceLocation() { | |
1937 | IResource sourceResource; | |
1938 | String sourceLocation = null; | |
1939 | if (fFileSystemObject.isDirectory()) { | |
1940 | sourceResource = ResourcesPlugin.getWorkspace().getRoot().getContainerForLocation(Path.fromOSString(fFileSystemObject.getAbsolutePath())); | |
1941 | } else { | |
1942 | sourceResource = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(Path.fromOSString(fFileSystemObject.getAbsolutePath())); | |
1943 | } | |
1944 | if (sourceResource != null && sourceResource.exists()) { | |
1945 | try { | |
1946 | sourceLocation = sourceResource.getPersistentProperty(TmfCommonConstants.SOURCE_LOCATION); | |
1947 | } catch (CoreException e) { | |
1948 | // Something went wrong with the already existing resource. | |
1949 | // This is not a problem, we'll assign a new location below. | |
1950 | } | |
1951 | } | |
1952 | if (sourceLocation == null) { | |
1953 | sourceLocation = URIUtil.toUnencodedString(fFileSystemObject.toURI()); | |
1954 | } | |
1955 | return sourceLocation; | |
1956 | } | |
1957 | ||
1958 | @Override | |
1959 | public Object getRawFileSystemObject() { | |
1960 | return fFileSystemObject; | |
1961 | } | |
1962 | } | |
1963 | ||
1964 | /** | |
1965 | * The "Tar" implementation of an IFileSystemObject | |
1966 | */ | |
1967 | private static class TarFileSystemObject implements IFileSystemObject { | |
1968 | ||
1969 | private TarEntry fFileSystemObject; | |
1970 | private String fArchivePath; | |
1971 | ||
1972 | private TarFileSystemObject(TarEntry fileSystemObject, String archivePath) { | |
1973 | fFileSystemObject = fileSystemObject; | |
1974 | fArchivePath = archivePath; | |
1975 | } | |
16f91bd5 | 1976 | |
c8cf44dc MAL |
1977 | @Override |
1978 | public String getLabel() { | |
1979 | return new Path(fFileSystemObject.getName()).lastSegment(); | |
1980 | } | |
1981 | ||
5609386c PT |
1982 | @Override |
1983 | public String getName() { | |
1984 | return fFileSystemObject.getName(); | |
1985 | } | |
1986 | ||
c8cf44dc MAL |
1987 | @Override |
1988 | public String getAbsolutePath(String parentContainerPath) { | |
1989 | return new Path(parentContainerPath).append(fFileSystemObject.getName()).toOSString(); | |
1990 | } | |
1991 | ||
1992 | @Override | |
1993 | public boolean exists() { | |
1994 | return true; | |
1995 | } | |
1996 | ||
1997 | @Override | |
1998 | public String getSourceLocation() { | |
1999 | URI uri = new File(fArchivePath).toURI(); | |
2000 | IPath entryPath = new Path(fFileSystemObject.getName()); | |
2001 | return URIUtil.toUnencodedString(URIUtil.toJarURI(uri, entryPath)); | |
2002 | } | |
2003 | ||
2004 | @Override | |
2005 | public Object getRawFileSystemObject() { | |
2006 | return fFileSystemObject; | |
2007 | } | |
2008 | } | |
2009 | ||
2010 | /** | |
2011 | * The "Zip" implementation of an IFileSystemObject | |
2012 | */ | |
2013 | private static class ZipFileSystemObject implements IFileSystemObject { | |
2014 | ||
2015 | private ZipEntry fFileSystemObject; | |
2016 | private String fArchivePath; | |
2017 | ||
2018 | private ZipFileSystemObject(ZipEntry fileSystemObject, String archivePath) { | |
2019 | fFileSystemObject = fileSystemObject; | |
2020 | fArchivePath = archivePath; | |
2021 | } | |
2022 | ||
2023 | @Override | |
2024 | public String getLabel() { | |
2025 | return new Path(fFileSystemObject.getName()).lastSegment(); | |
2026 | } | |
2027 | ||
5609386c PT |
2028 | @Override |
2029 | public String getName() { | |
2030 | return fFileSystemObject.getName(); | |
2031 | } | |
2032 | ||
c8cf44dc MAL |
2033 | @Override |
2034 | public String getAbsolutePath(String parentContainerPath) { | |
2035 | return new Path(parentContainerPath).append(fFileSystemObject.getName()).toOSString(); | |
2036 | } | |
2037 | ||
2038 | @Override | |
2039 | public boolean exists() { | |
2040 | return true; | |
2041 | } | |
2042 | ||
2043 | @Override | |
2044 | public String getSourceLocation() { | |
2045 | URI uri = new File(fArchivePath).toURI(); | |
2046 | IPath entryPath = new Path(fFileSystemObject.getName()); | |
2047 | return URIUtil.toUnencodedString(URIUtil.toJarURI(uri, entryPath)); | |
2048 | } | |
2049 | ||
2050 | @Override | |
2051 | public Object getRawFileSystemObject() { | |
2052 | return fFileSystemObject; | |
2053 | } | |
2054 | } | |
2055 | ||
2056 | private class ImportProvider implements IImportStructureProvider { | |
16f91bd5 BH |
2057 | |
2058 | ImportProvider() { | |
2059 | } | |
2060 | ||
2061 | @Override | |
2062 | public String getLabel(Object element) { | |
ba560b10 | 2063 | TraceFileSystemElement resource = (TraceFileSystemElement) element; |
16f91bd5 BH |
2064 | return resource.getLabel(); |
2065 | } | |
2066 | ||
2067 | @Override | |
2068 | public List getChildren(Object element) { | |
ba560b10 | 2069 | TraceFileSystemElement resource = (TraceFileSystemElement) element; |
16f91bd5 | 2070 | Object[] array = resource.getFiles().getChildren(); |
ba560b10 MK |
2071 | List<Object> list = new ArrayList<>(); |
2072 | for (int i = 0; i < array.length; i++) { | |
2073 | list.add(array[i]); | |
2074 | } | |
16f91bd5 BH |
2075 | return list; |
2076 | } | |
2077 | ||
2078 | @Override | |
2079 | public InputStream getContents(Object element) { | |
ba560b10 | 2080 | TraceFileSystemElement resource = (TraceFileSystemElement) element; |
c8cf44dc | 2081 | return resource.getProvider().getContents(resource.getFileSystemObject()); |
16f91bd5 BH |
2082 | } |
2083 | ||
2084 | @Override | |
2085 | public String getFullPath(Object element) { | |
ba560b10 | 2086 | TraceFileSystemElement resource = (TraceFileSystemElement) element; |
c8cf44dc | 2087 | return resource.getProvider().getFullPath(resource.getFileSystemObject()); |
16f91bd5 BH |
2088 | } |
2089 | ||
2090 | @Override | |
2091 | public boolean isFolder(Object element) { | |
ba560b10 | 2092 | TraceFileSystemElement resource = (TraceFileSystemElement) element; |
16f91bd5 BH |
2093 | return resource.isDirectory(); |
2094 | } | |
2095 | } | |
002f9f07 | 2096 | } |