1 /*******************************************************************************
2 * Copyright (c) 2013 Ericsson
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
10 * Marc-Andre Laperle - Initial API and implementation
11 *******************************************************************************/
13 package org
.eclipse
.linuxtools
.internal
.tmf
.ui
.project
.wizards
.tracepkg
.importexport
;
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
;
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
;
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
;
56 * An operation that exports a trace package to an archive
58 * @author Marc-Andre Laperle
60 @SuppressWarnings("restriction")
61 public class TracePackageExportOperation
extends AbstractTracePackageOperation
{
63 private static final String TRACE_EXPORT_TEMP_FOLDER
= ".traceExport"; //$NON-NLS-1$
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
;
72 * Constructs a new export operation
74 * @param traceExportElements
75 * the trace elements to be exported
76 * @param useCompression
77 * whether or not to use compression
79 * use tar format or zip
81 * the output file name
83 public TracePackageExportOperation(TracePackageTraceElement
[] traceExportElements
, boolean useCompression
, boolean useTar
, String fileName
) {
85 fTraceExportElements
= traceExportElements
;
86 fUseCompression
= useCompression
;
88 fResources
= new ArrayList
<IResource
>();
92 * Run the operation. The status (result) of the operation can be obtained
93 * with {@link #getStatus}
95 * @param progressMonitor
96 * the progress monitor to use to display progress and receive
97 * requests for cancellation
100 public void run(IProgressMonitor progressMonitor
) {
103 int totalWork
= getNbCheckedElements(fTraceExportElements
) * 2;
104 progressMonitor
.beginTask(Messages
.TracePackageExportOperation_GeneratingPackage
, totalWork
);
106 fExportFolder
= createExportFolder(progressMonitor
);
108 Document doc
= DocumentBuilderFactory
.newInstance().newDocumentBuilder().newDocument();
109 Element createElement
= doc
.createElement(ITracePackageConstants
.TMF_EXPORT_ELEMENT
);
110 Node tmfNode
= doc
.appendChild(createElement
);
112 for (TracePackageTraceElement tracePackageElement
: fTraceExportElements
) {
113 exportTrace(progressMonitor
, tmfNode
, tracePackageElement
);
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();
125 ModalContext
.checkCanceled(progressMonitor
);
127 exportManifest(content
);
129 setStatus(exportToArchive(progressMonitor
, totalWork
));
131 fExportFolder
.delete(true, new SubProgressMonitor(progressMonitor
, 1, SubProgressMonitor
.PREPEND_MAIN_LABEL_TO_SUBTASK
));
133 progressMonitor
.done();
135 } catch (Exception e
) {
136 if (e
instanceof InterruptedException
) {
137 setStatus(Status
.CANCEL_STATUS
);
139 setStatus(new Status(IStatus
.ERROR
, Activator
.PLUGIN_ID
, org
.eclipse
.linuxtools
.internal
.tmf
.ui
.project
.wizards
.tracepkg
.Messages
.TracePackage_ErrorOperation
, e
));
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);
149 folder
.create(IResource
.FORCE
| IResource
.HIDDEN
, true, new SubProgressMonitor(monitor
, 1, SubProgressMonitor
.PREPEND_MAIN_LABEL_TO_SUBTASK
));
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
);
160 for (TracePackageElement element
: tracePackageElement
.getChildren()) {
161 ModalContext
.checkCanceled(monitor
);
162 if (!element
.isChecked()) {
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
);
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
));
185 IFolder traceSuppFilesFolder
= suppFilesFolder
.getFolder(traceElement
.getResource().getName());
186 traceSuppFilesFolder
.create(IResource
.FORCE
, true, new SubProgressMonitor(monitor
, 1, SubProgressMonitor
.PREPEND_MAIN_LABEL_TO_SUBTASK
));
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
);
199 fResources
.add(suppFilesFolder
);
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
));
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
);
219 * Creates a linked resource in the specified folder
221 * @param exportFolder the folder that will contain the linked resource
222 * @param res the resource to export
223 * @throws CoreException when createLink fails
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);
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
);
245 for (IMarker marker
: findMarkers
) {
246 ModalContext
.checkCanceled(monitor
);
248 Element singleBookmarkXmlElement
= doc
.createElement(ITracePackageConstants
.BOOKMARK_ELEMENT
);
249 for (String key
: marker
.getAttributes().keySet()) {
250 singleBookmarkXmlElement
.setAttribute(key
, marker
.getAttribute(key
).toString());
253 bookmarksNode
.appendChild(singleBookmarkXmlElement
);
259 private void exportManifest(String content
) throws CoreException
{
260 IFile file
= fExportFolder
.getFile(ITracePackageConstants
.MANIFEST_FILENAME
);
261 ByteArrayInputStream inputStream
= new ByteArrayInputStream(content
.getBytes());
263 file
.setContents(inputStream
, IResource
.FORCE
, null);
265 file
.create(inputStream
, IResource
.FORCE
| IResource
.HIDDEN
, null);
267 fResources
.add(file
);
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
));
277 return op
.getStatus();