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