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