ss: Move plugins to Trace Compass namespace
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / internal / tmf / ui / project / wizards / tracepkg / importexport / TracePackageExportOperation.java
1 /*******************************************************************************
2 * Copyright (c) 2013, 2014 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
13 package org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.importexport;
14
15 import java.io.ByteArrayInputStream;
16 import java.io.StringWriter;
17 import java.lang.reflect.InvocationTargetException;
18 import java.util.ArrayList;
19 import java.util.HashSet;
20 import java.util.Set;
21
22 import javax.xml.parsers.DocumentBuilderFactory;
23 import javax.xml.transform.OutputKeys;
24 import javax.xml.transform.Transformer;
25 import javax.xml.transform.TransformerFactory;
26 import javax.xml.transform.dom.DOMSource;
27 import javax.xml.transform.stream.StreamResult;
28
29 import org.eclipse.core.resources.IFile;
30 import org.eclipse.core.resources.IFolder;
31 import org.eclipse.core.resources.IMarker;
32 import org.eclipse.core.resources.IResource;
33 import org.eclipse.core.runtime.CoreException;
34 import org.eclipse.core.runtime.IPath;
35 import org.eclipse.core.runtime.IProgressMonitor;
36 import org.eclipse.core.runtime.IStatus;
37 import org.eclipse.core.runtime.Status;
38 import org.eclipse.core.runtime.SubProgressMonitor;
39 import org.eclipse.jface.operation.ModalContext;
40 import org.eclipse.linuxtools.internal.tmf.ui.Activator;
41 import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.AbstractTracePackageOperation;
42 import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.ITracePackageConstants;
43 import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageBookmarkElement;
44 import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageElement;
45 import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageFilesElement;
46 import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageSupplFileElement;
47 import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageSupplFilesElement;
48 import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageTraceElement;
49 import org.eclipse.linuxtools.tmf.core.TmfCommonConstants;
50 import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement;
51 import org.eclipse.linuxtools.tmf.ui.project.model.TraceUtils;
52 import org.eclipse.ui.internal.wizards.datatransfer.ArchiveFileExportOperation;
53 import org.w3c.dom.Document;
54 import org.w3c.dom.Element;
55 import org.w3c.dom.Node;
56
57 /**
58 * An operation that exports a trace package to an archive
59 *
60 * @author Marc-Andre Laperle
61 */
62 @SuppressWarnings("restriction")
63 public class TracePackageExportOperation extends AbstractTracePackageOperation {
64
65 private static final String TRACE_EXPORT_TEMP_FOLDER = ".traceExport"; //$NON-NLS-1$
66
67 private final TracePackageTraceElement[] fTraceExportElements;
68 private final boolean fUseCompression;
69 private final boolean fUseTar;
70 private final Set<IResource> fResources;
71 private IFolder fExportFolder;
72
73 /**
74 * Constructs a new export operation
75 *
76 * @param traceExportElements
77 * the trace elements to be exported
78 * @param useCompression
79 * whether or not to use compression
80 * @param useTar
81 * use tar format or zip
82 * @param fileName
83 * the output file name
84 */
85 public TracePackageExportOperation(TracePackageTraceElement[] traceExportElements, boolean useCompression, boolean useTar, String fileName) {
86 super(fileName);
87 fTraceExportElements = traceExportElements;
88 fUseCompression = useCompression;
89 fUseTar = useTar;
90 fResources = new HashSet<>();
91 }
92
93 /**
94 * Run the operation. The status (result) of the operation can be obtained
95 * with {@link #getStatus}
96 *
97 * @param progressMonitor
98 * the progress monitor to use to display progress and receive
99 * requests for cancellation
100 */
101 @Override
102 public void run(IProgressMonitor progressMonitor) {
103
104 try {
105 int totalWork = getNbCheckedElements(fTraceExportElements) * 2;
106 progressMonitor.beginTask(Messages.TracePackageExportOperation_GeneratingPackage, totalWork);
107
108 fExportFolder = createExportFolder(progressMonitor);
109
110 Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
111 Element createElement = doc.createElement(ITracePackageConstants.TMF_EXPORT_ELEMENT);
112 Node tmfNode = doc.appendChild(createElement);
113
114 for (TracePackageTraceElement tracePackageElement : fTraceExportElements) {
115 if (!isFilesChecked(tracePackageElement)) {
116 continue;
117 }
118
119 exportTrace(progressMonitor, tmfNode, tracePackageElement);
120 }
121
122 Transformer transformer = TransformerFactory.newInstance().newTransformer();
123 transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
124 transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); //$NON-NLS-1$ //$NON-NLS-2$
125 DOMSource source = new DOMSource(doc);
126 StringWriter buffer = new StringWriter();
127 StreamResult result = new StreamResult(buffer);
128 transformer.transform(source, result);
129 String content = buffer.getBuffer().toString();
130
131 ModalContext.checkCanceled(progressMonitor);
132
133 exportManifest(content);
134
135 setStatus(exportToArchive(progressMonitor, totalWork));
136
137 fExportFolder.delete(true, new SubProgressMonitor(progressMonitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK));
138
139 progressMonitor.done();
140
141 } catch (Exception e) {
142 if (e instanceof InterruptedException) {
143 setStatus(Status.CANCEL_STATUS);
144 } else {
145 setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.Messages.TracePackage_ErrorOperation, e));
146 }
147 }
148 }
149
150 private IFolder createExportFolder(IProgressMonitor monitor) throws CoreException {
151 IFolder folder = fTraceExportElements[0].getTraceElement().getProject().getResource().getFolder(TRACE_EXPORT_TEMP_FOLDER);
152 if (folder.exists()) {
153 folder.delete(true, null);
154 }
155 folder.create(IResource.FORCE | IResource.HIDDEN, true, new SubProgressMonitor(monitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK));
156 return folder;
157 }
158
159 private void exportTrace(IProgressMonitor monitor, Node tmfNode, TracePackageTraceElement tracePackageElement) throws InterruptedException, CoreException {
160 TmfTraceElement traceElement = tracePackageElement.getTraceElement();
161 Element traceXmlElement = tmfNode.getOwnerDocument().createElement(ITracePackageConstants.TRACE_ELEMENT);
162 traceXmlElement.setAttribute(ITracePackageConstants.TRACE_NAME_ATTRIB, traceElement.getResource().getName());
163 traceXmlElement.setAttribute(ITracePackageConstants.TRACE_TYPE_ATTRIB, traceElement.getTraceType());
164 Node traceNode = tmfNode.appendChild(traceXmlElement);
165
166 for (TracePackageElement element : tracePackageElement.getChildren()) {
167 ModalContext.checkCanceled(monitor);
168 if (!element.isChecked()) {
169 continue;
170 }
171
172 if (element instanceof TracePackageSupplFilesElement) {
173 exportSupplementaryFiles(monitor, traceNode, traceElement, (TracePackageSupplFilesElement) element);
174 } else if (element instanceof TracePackageBookmarkElement) {
175 exportBookmarks(monitor, traceNode, (TracePackageBookmarkElement) element);
176 } else if (element instanceof TracePackageFilesElement) {
177 exportTraceFiles(monitor, traceNode, (TracePackageFilesElement) element);
178 }
179
180 monitor.worked(1);
181 }
182 }
183
184 private void exportSupplementaryFiles(IProgressMonitor monitor, Node traceNode, TmfTraceElement traceElement, TracePackageSupplFilesElement element) throws InterruptedException, CoreException {
185 Document doc = traceNode.getOwnerDocument();
186 if (element.getChildren().length > 0) {
187
188 IPath projectPath = traceElement.getProject().getPath();
189
190 for (TracePackageElement child : element.getChildren()) {
191 TracePackageSupplFileElement supplFile = (TracePackageSupplFileElement) child;
192 ModalContext.checkCanceled(monitor);
193 IResource res = supplFile.getResource();
194 // project/.tracing/A/B/statistics.ht -> .tracing/A/B/statistics.ht
195 IPath relativeToExportFolder = res.getFullPath().makeRelativeTo(projectPath);
196
197 // project/.traceExport/.tracing/A/B
198 IFolder folder = fExportFolder.getFolder(relativeToExportFolder.removeLastSegments(1));
199 TraceUtils.createFolder(folder, new SubProgressMonitor(monitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK));
200
201 res.refreshLocal(0, new SubProgressMonitor(monitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK));
202 createExportResource(folder, res);
203 Element suppFileElement = doc.createElement(ITracePackageConstants.SUPPLEMENTARY_FILE_ELEMENT);
204
205 suppFileElement.setAttribute(ITracePackageConstants.SUPPLEMENTARY_FILE_NAME_ATTRIB, relativeToExportFolder.toString());
206 traceNode.appendChild(suppFileElement);
207 }
208
209 IFolder suppFilesFolder = fExportFolder.getFolder(TmfCommonConstants.TRACE_SUPPLEMENTARY_FOLDER_NAME);
210 fResources.add(suppFilesFolder);
211 }
212 }
213
214 private void exportTraceFiles(IProgressMonitor monitor, Node traceNode, TracePackageFilesElement element) throws CoreException {
215 Document doc = traceNode.getOwnerDocument();
216 TmfTraceElement traceElement = ((TracePackageTraceElement) element.getParent()).getTraceElement();
217 IResource resource = traceElement.getResource();
218 IPath traceFolderPath = traceElement.getProject().getTracesFolder().getPath();
219
220 // project/Traces/A/B/Kernel -> A/B/Kernel
221 IPath relativeToExportFolder = resource.getFullPath().makeRelativeTo(traceFolderPath);
222
223 // project/.traceExport/A/B
224 IFolder folder = fExportFolder.getFolder(relativeToExportFolder.removeLastSegments(1));
225 TraceUtils.createFolder(folder, new SubProgressMonitor(monitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK));
226
227 createExportResource(folder, resource);
228 Element fileElement = doc.createElement(ITracePackageConstants.TRACE_FILE_ELEMENT);
229
230 fileElement.setAttribute(ITracePackageConstants.TRACE_FILE_NAME_ATTRIB, relativeToExportFolder.toString());
231 traceNode.appendChild(fileElement);
232
233 // Always export the top-most folder containing the trace or the trace itself
234 IResource exportedResource = fExportFolder.findMember(relativeToExportFolder.segment(0));
235 fResources.add(exportedResource);
236 }
237
238 /**
239 * Creates a linked resource in the specified folder
240 *
241 * @param exportFolder the folder that will contain the linked resource
242 * @param res the resource to export
243 * @throws CoreException when createLink fails
244 * @return the created linked resource
245 */
246 private static IResource createExportResource(IFolder exportFolder, IResource res) throws CoreException {
247 IResource ret = null;
248 // Note: The resources cannot be HIDDEN or else they are ignored by ArchiveFileExportOperation
249 if (res instanceof IFolder) {
250 IFolder folder = exportFolder.getFolder(res.getName());
251 folder.createLink(res.getLocationURI(), IResource.NONE, null);
252 ret = folder;
253 } else if (res instanceof IFile) {
254 IFile file = exportFolder.getFile(res.getName());
255 file.createLink(res.getLocationURI(), IResource.NONE, null);
256 ret = file;
257 }
258 return ret;
259 }
260
261 private static void exportBookmarks(IProgressMonitor monitor, Node traceNode, TracePackageBookmarkElement element) throws CoreException, InterruptedException {
262 Document doc = traceNode.getOwnerDocument();
263 IFile bookmarksFile = ((TracePackageTraceElement) element.getParent()).getTraceElement().getBookmarksFile();
264 if (bookmarksFile != null && bookmarksFile.exists()) {
265 IMarker[] findMarkers = bookmarksFile.findMarkers(IMarker.BOOKMARK, false, IResource.DEPTH_ZERO);
266 if (findMarkers.length > 0) {
267 Element bookmarksXmlElement = doc.createElement(ITracePackageConstants.BOOKMARKS_ELEMENT);
268 Node bookmarksNode = traceNode.appendChild(bookmarksXmlElement);
269
270 for (IMarker marker : findMarkers) {
271 ModalContext.checkCanceled(monitor);
272
273 Element singleBookmarkXmlElement = doc.createElement(ITracePackageConstants.BOOKMARK_ELEMENT);
274 for (String key : marker.getAttributes().keySet()) {
275 singleBookmarkXmlElement.setAttribute(key, marker.getAttribute(key).toString());
276 }
277
278 bookmarksNode.appendChild(singleBookmarkXmlElement);
279 }
280 }
281 }
282 }
283
284 private void exportManifest(String content) throws CoreException {
285 IFile file = fExportFolder.getFile(ITracePackageConstants.MANIFEST_FILENAME);
286 ByteArrayInputStream inputStream = new ByteArrayInputStream(content.getBytes());
287 if (file.exists()) {
288 file.setContents(inputStream, IResource.FORCE, null);
289 } else {
290 file.create(inputStream, IResource.FORCE | IResource.HIDDEN, null);
291 }
292 fResources.add(file);
293 }
294
295 private IStatus exportToArchive(IProgressMonitor monitor, int totalWork) throws InvocationTargetException, InterruptedException {
296 ArchiveFileExportOperation op = new ArchiveFileExportOperation(new ArrayList<>(fResources), getFileName());
297 op.setCreateLeadupStructure(false);
298 op.setUseCompression(fUseCompression);
299 op.setUseTarFormat(fUseTar);
300 op.run(new SubProgressMonitor(monitor, totalWork / 2, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK));
301
302 return op.getStatus();
303 }
304 }
This page took 0.040469 seconds and 5 git commands to generate.