tmf: Import and Export trace package
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / internal / tmf / ui / project / wizards / tracepkg / importexport / TracePackageImportOperation.java
CommitLineData
6e651d8b
MAL
1/*******************************************************************************
2 * Copyright (c) 2013 Ericsson
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * Contributors:
10 * Marc-Andre Laperle - Initial API and implementation
11 *******************************************************************************/
12
13package org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.importexport;
14
15import java.io.IOException;
16import java.io.InputStream;
17import java.lang.reflect.InvocationTargetException;
18import java.text.MessageFormat;
19import java.util.ArrayList;
20import java.util.Enumeration;
21import java.util.List;
22import java.util.Map;
23
24import org.eclipse.core.resources.IFile;
25import org.eclipse.core.resources.IMarker;
26import org.eclipse.core.resources.IResource;
27import org.eclipse.core.runtime.CoreException;
28import org.eclipse.core.runtime.IPath;
29import org.eclipse.core.runtime.IProgressMonitor;
30import org.eclipse.core.runtime.IStatus;
31import org.eclipse.core.runtime.Path;
32import org.eclipse.core.runtime.Status;
33import org.eclipse.core.runtime.SubProgressMonitor;
34import org.eclipse.jface.operation.ModalContext;
35import org.eclipse.linuxtools.internal.tmf.ui.Activator;
36import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.AbstractTracePackageOperation;
37import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageBookmarkElement;
38import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageElement;
39import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageFilesElement;
40import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageSupplFileElement;
41import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageSupplFilesElement;
42import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageTraceElement;
43import org.eclipse.linuxtools.tmf.core.TmfCommonConstants;
44import org.eclipse.linuxtools.tmf.ui.editors.TmfEventsEditor;
45import org.eclipse.linuxtools.tmf.ui.project.model.TmfNavigatorContentProvider;
46import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement;
47import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceFolder;
48import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceType;
49import org.eclipse.linuxtools.tmf.ui.project.model.TraceTypeHelper;
50import org.eclipse.ui.dialogs.IOverwriteQuery;
51import org.eclipse.ui.ide.IDE;
52import org.eclipse.ui.internal.wizards.datatransfer.TarException;
53import org.eclipse.ui.wizards.datatransfer.IImportStructureProvider;
54import org.eclipse.ui.wizards.datatransfer.ImportOperation;
55
56/**
57 * An operation that imports a trace package from an archive
58 *
59 * @author Marc-Andre Laperle
60 */
61@SuppressWarnings("restriction")
62public class TracePackageImportOperation extends AbstractTracePackageOperation implements IOverwriteQuery {
63
64 private final TracePackageTraceElement fImportTraceElement;
65 private final TmfTraceFolder fTmfTraceFolder;
66
67 // Result of reading the manifest
68 private TracePackageElement fResultElement;
69
70 /**
71 * Constructs a new import operation
72 *
73 * @param importTraceElement
74 * the trace element to be imported
75 * @param fileName
76 * the output file name
77 * @param tmfTraceFolder
78 * the destination folder
79 */
80 public TracePackageImportOperation(String fileName, TracePackageTraceElement importTraceElement, TmfTraceFolder tmfTraceFolder) {
81 super(fileName);
82 fImportTraceElement = importTraceElement;
83 fTmfTraceFolder = tmfTraceFolder;
84 }
85
86 private class ImportProvider implements IImportStructureProvider {
87
88 private Exception fException;
89
90 @Override
91 public List getChildren(Object element) {
92 return null;
93 }
94
95 @Override
96 public InputStream getContents(Object element) {
97 InputStream inputStream = null;
98 // We can add throws
99 try {
100 inputStream = ((ArchiveProviderElement) element).getContents();
101 } catch (IOException e) {
102 fException = e;
103 } catch (TarException e) {
104 fException = e;
105 }
106 return inputStream;
107 }
108
109 @Override
110 public String getFullPath(Object element) {
111 return ((ArchiveProviderElement) element).getFullPath();
112 }
113
114 @Override
115 public String getLabel(Object element) {
116 return ((ArchiveProviderElement) element).getLabel();
117 }
118
119 @Override
120 public boolean isFolder(Object element) {
121 return ((ArchiveProviderElement) element).isFolder();
122 }
123
124 public Exception getException() {
125 return fException;
126 }
127 }
128
129 private class ArchiveProviderElement {
130
131 private final String fPath;
132 private final String fLabel;
133
134 private ArchiveFile fArchiveFile;
135 private ArchiveEntry fEntry;
136
137 public ArchiveProviderElement(String destinationPath, String label, ArchiveFile archiveFile, ArchiveEntry entry) {
138 fPath = destinationPath;
139 fLabel = label;
140 this.fArchiveFile = archiveFile;
141 this.fEntry = entry;
142 }
143
144 public InputStream getContents() throws TarException, IOException {
145 return fArchiveFile.getInputStream(fEntry);
146 }
147
148 public String getFullPath() {
149 return fPath;
150 }
151
152 public String getLabel() {
153 return fLabel;
154 }
155
156 public boolean isFolder() {
157 return false;
158 }
159 }
160
161 /**
162 * Run the operation. The status (result) of the operation can be obtained
163 * with {@link #getStatus}
164 *
165 * @param progressMonitor
166 * the progress monitor to use to display progress and receive
167 * requests for cancellation
168 */
169 @Override
170 public void run(IProgressMonitor progressMonitor) {
171 int totalWork = getNbCheckedElements(new TracePackageElement[] { fImportTraceElement }) * 2;
172 progressMonitor.beginTask(Messages.TracePackageImportOperation_ImportingPackage, totalWork);
173 doRun(progressMonitor);
174 progressMonitor.done();
175 }
176
177 private void doRun(IProgressMonitor progressMonitor) {
178 try {
179 setStatus(deleteExistingTrace(progressMonitor));
180 if (getStatus().getSeverity() != IStatus.OK) {
181 return;
182 }
183
184 TracePackageElement[] children = fImportTraceElement.getChildren();
185 for (TracePackageElement element : children) {
186 ModalContext.checkCanceled(progressMonitor);
187
188 if (element instanceof TracePackageFilesElement) {
189 TracePackageFilesElement traceFilesElement = (TracePackageFilesElement) element;
190 setStatus(importTraceFiles(progressMonitor, traceFilesElement));
191
192 } else if (element instanceof TracePackageSupplFilesElement) {
193 TracePackageSupplFilesElement suppFilesElement = (TracePackageSupplFilesElement) element;
194 setStatus(importSupplFiles(progressMonitor, suppFilesElement));
195 }
196
197 if (getStatus().getSeverity() != IStatus.OK) {
198 return;
199 }
200 }
201
202 String traceName = fImportTraceElement.getText();
203 IResource traceRes = fTmfTraceFolder.getResource().findMember(traceName);
204 if (traceRes == null || !traceRes.exists()) {
205 setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, MessageFormat.format(Messages.ImportTracePackageWizardPage_ErrorFindingImportedTrace, traceName)));
206 return;
207 }
208
209 TraceTypeHelper traceType = TmfTraceType.getInstance().getTraceType(fImportTraceElement.getTraceType());
210 if (traceType == null) {
211 setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, MessageFormat.format(Messages.ImportTracePackageWizardPage_ErrorSettingTraceType, fImportTraceElement.getTraceType(), traceName)));
212 return;
213 }
214
215 try {
216 TmfTraceType.setTraceType(traceRes.getFullPath(), traceType);
217 } catch (CoreException e) {
218 setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, MessageFormat.format(Messages.ImportTracePackageWizardPage_ErrorSettingTraceType, fImportTraceElement.getTraceType(), traceName), e));
219 }
220
221 importBookmarks(traceRes, progressMonitor);
222
223 } catch (InterruptedException e) {
224 setStatus(Status.CANCEL_STATUS);
225 }
226 }
227
228 private IStatus deleteExistingTrace(IProgressMonitor progressMonitor) {
229 List<TmfTraceElement> traces = fTmfTraceFolder.getTraces();
230 TmfTraceElement existingTrace = null;
231
232 for (TmfTraceElement t : traces) {
233 if (t.getName().equals(fImportTraceElement.getText())) {
234 existingTrace = t;
235 break;
236 }
237 }
238
239 if (existingTrace != null) {
240 try {
241 existingTrace.delete(new SubProgressMonitor(progressMonitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK));
242 } catch (CoreException e) {
243 return new Status(IStatus.ERROR, Activator.PLUGIN_ID, org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.Messages.TracePackage_ErrorOperation, e);
244 }
245 }
246
247 return Status.OK_STATUS;
248 }
249
250 private void importBookmarks(IResource traceRes, IProgressMonitor monitor) {
251 for (TracePackageElement o : fImportTraceElement.getChildren()) {
252 if (o instanceof TracePackageBookmarkElement && o.isChecked()) {
253
254 // Get element
255 IFile bookmarksFile = null;
256 List<TmfTraceElement> traces = fTmfTraceFolder.getTraces();
257 for (TmfTraceElement t : traces) {
258 if (t.getName().equals(traceRes.getName())) {
259 try {
260 bookmarksFile = t.createBookmarksFile();
261
262 // Make sure that if a bookmark is double-clicked first
263 // before opening the trace, it opens the right editor
264
265 // Get the editor id from the extension point
266 String traceEditorId = t.getEditorId();
267 final String editorId = (traceEditorId != null) ? traceEditorId : TmfEventsEditor.ID;
268 IDE.setDefaultEditor(bookmarksFile, editorId);
269
270 } catch (CoreException e) {
271 Activator.getDefault().logError(MessageFormat.format(Messages.TracePackageImportOperation_ErrorCreatingBookmarkFile, traceRes.getName()), e);
272 }
273 break;
274 }
275 }
276
277 if (bookmarksFile == null) {
278 break;
279 }
280
281 TracePackageBookmarkElement bookmarkElement = (TracePackageBookmarkElement) o;
282
283 List<Map<String, String>> bookmarks = bookmarkElement.getBookmarks();
284 for (Map<String, String> attrs : bookmarks) {
285 IMarker createMarker = null;
286 try {
287 createMarker = bookmarksFile.createMarker(IMarker.BOOKMARK);
288 } catch (CoreException e) {
289 Activator.getDefault().logError(MessageFormat.format(Messages.TracePackageImportOperation_ErrorCreatingBookmark, traceRes.getName()), e);
290 }
291 if (createMarker != null && createMarker.exists()) {
292 try {
293 for (String key : attrs.keySet()) {
294 String value = attrs.get(key);
295 if (key.equals(IMarker.LOCATION)) {
296 createMarker.setAttribute(IMarker.LOCATION, Integer.valueOf(value).intValue());
297 } else {
298 createMarker.setAttribute(key, value);
299 }
300 }
301 } catch (CoreException e) {
302 Activator.getDefault().logError(MessageFormat.format(Messages.TracePackageImportOperation_ErrorCreatingBookmark, traceRes.getName()), e);
303 }
304 }
305 }
306 }
307 }
308
309 monitor.worked(1);
310 }
311
312 private static boolean fileNameMatches(String fileName, String entryName) {
313 boolean fileMatch = entryName.equalsIgnoreCase(fileName);
314 boolean folderMatch = entryName.startsWith(fileName + "/"); //$NON-NLS-1$
315 return fileMatch || folderMatch;
316 }
317
318 private IStatus importTraceFiles(IProgressMonitor monitor, TracePackageFilesElement traceFilesElement) {
319 List<String> fileNames = new ArrayList<String>();
320 IPath prefix = new Path(TmfTraceFolder.TRACE_FOLDER_NAME);
321 fileNames.add(traceFilesElement.getFileName());
322 IPath containerPath = fTmfTraceFolder.getPath();
323 IStatus status = importFiles(getSpecifiedArchiveFile(), fileNames, prefix, containerPath, monitor);
324 if (status.isOK()) {
325 new TmfNavigatorContentProvider().getChildren(fTmfTraceFolder);
326 }
327 return status;
328 }
329
330 private IStatus importSupplFiles(IProgressMonitor monitor, TracePackageSupplFilesElement suppFilesElement) {
331 List<String> fileNames = new ArrayList<String>();
332 for (TracePackageElement child : suppFilesElement.getChildren()) {
333 TracePackageSupplFileElement supplFile = (TracePackageSupplFileElement) child;
334 fileNames.add(supplFile.getText());
335 }
336
337 if (!fileNames.isEmpty()) {
338 List<TmfTraceElement> traces = fTmfTraceFolder.getTraces();
339 TmfTraceElement traceElement = null;
340 for (TmfTraceElement t : traces) {
341 if (t.getName().equals(fImportTraceElement.getText())) {
342 traceElement = t;
343 break;
344 }
345 }
346
347 if (traceElement != null) {
348 ArchiveFile archiveFile = getSpecifiedArchiveFile();
349 traceElement.refreshSupplementaryFolder();
350 String traceName = traceElement.getResource().getName();
351 // Project/.tracing/tracename
352 IPath destinationContainerPath = traceElement.getTraceSupplementaryFolder(traceName).getFullPath();
353 // .tracing/tracename
354 IPath pathInArchive = new Path(TmfCommonConstants.TRACE_SUPPLEMENATARY_FOLDER_NAME).append(traceName);
355 return importFiles(archiveFile, fileNames, pathInArchive, destinationContainerPath, monitor);
356 }
357 }
358
359 return Status.OK_STATUS;
360 }
361
362 private IStatus importFiles(ArchiveFile archiveFile, List<String> fileNames, IPath pathInArchive, IPath destinationContainerPath, IProgressMonitor monitor) {
363 List<ArchiveProviderElement> objects = new ArrayList<ArchiveProviderElement>();
364 Enumeration<?> entries = archiveFile.entries();
365 while (entries.hasMoreElements()) {
366 ArchiveEntry entry = (ArchiveEntry) entries.nextElement();
367 String entryName = entry.getName();
368 IPath fullArchivePath = new Path(entryName);
369 if (fullArchivePath.hasTrailingSeparator()) {
370 // We only care about file entries as the folders will get created by the ImportOperation
371 continue;
372 }
373
374 for (String fileName : fileNames) {
375 // Check if this archive entry matches the searched file name at this archive location
376 IPath searchedArchivePath = pathInArchive.append(fileName);
377 if (fileNameMatches(searchedArchivePath.toString(), entryName)) {
378 // Traces/kernel/metadata
379 // kernel/metadata, the ImportOperation will take care of creating the kernel folder
380 IPath destinationPath = fullArchivePath.removeFirstSegments(pathInArchive.segmentCount());
381 // metadata
382 String resourceLabel = fullArchivePath.lastSegment();
383
384 ArchiveProviderElement pe = new ArchiveProviderElement(destinationPath.toString(), resourceLabel, archiveFile, entry);
385 objects.add(pe);
386 break;
387 }
388 }
389 }
390
391 ImportProvider provider = new ImportProvider();
392
393 ImportOperation operation = new ImportOperation(destinationContainerPath,
394 null, provider, this,
395 objects);
396 operation.setCreateContainerStructure(true);
397 operation.setOverwriteResources(true);
398
399 try {
400 operation.run(new SubProgressMonitor(monitor, fileNames.size(), SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK));
401 archiveFile.close();
402 } catch (InvocationTargetException e) {
403 return new Status(IStatus.ERROR, Activator.PLUGIN_ID, org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.Messages.TracePackage_ErrorOperation, e);
404 } catch (InterruptedException e) {
405 return Status.CANCEL_STATUS;
406 } catch (IOException e) {
407 return new Status(IStatus.ERROR, Activator.PLUGIN_ID, org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.Messages.TracePackage_ErrorOperation, e);
408 }
409
410 if (provider.getException() != null) {
411 return new Status(IStatus.ERROR, Activator.PLUGIN_ID, org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.Messages.TracePackage_ErrorOperation, provider.getException());
412 }
413
414 return operation.getStatus();
415 }
416
417 @Override
418 public String queryOverwrite(String pathString) {
419 // We always overwrite once we reach this point
420 return null;
421 }
422
423 /**
424 * Get the resulting element from extracting the manifest from the archive
425 *
426 * @return the resulting element
427 */
428 public TracePackageElement getResultElement() {
429 return fResultElement;
430 }
431
432}
This page took 0.03955 seconds and 5 git commands to generate.