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
.HashSet
;
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
;
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
;
57 * An operation that exports a trace package to an archive
59 * @author Marc-Andre Laperle
61 @SuppressWarnings("restriction")
62 public class TracePackageExportOperation
extends AbstractTracePackageOperation
{
64 private static final String TRACE_EXPORT_TEMP_FOLDER
= ".traceExport"; //$NON-NLS-1$
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
;
73 * Constructs a new export operation
75 * @param traceExportElements
76 * the trace elements to be exported
77 * @param useCompression
78 * whether or not to use compression
80 * use tar format or zip
82 * the output file name
84 public TracePackageExportOperation(TracePackageTraceElement
[] traceExportElements
, boolean useCompression
, boolean useTar
, String fileName
) {
86 fTraceExportElements
= traceExportElements
;
87 fUseCompression
= useCompression
;
89 fResources
= new HashSet
<IResource
>();
93 * Run the operation. The status (result) of the operation can be obtained
94 * with {@link #getStatus}
96 * @param progressMonitor
97 * the progress monitor to use to display progress and receive
98 * requests for cancellation
101 public void run(IProgressMonitor progressMonitor
) {
104 int totalWork
= getNbCheckedElements(fTraceExportElements
) * 2;
105 progressMonitor
.beginTask(Messages
.TracePackageExportOperation_GeneratingPackage
, totalWork
);
107 fExportFolder
= createExportFolder(progressMonitor
);
109 Document doc
= DocumentBuilderFactory
.newInstance().newDocumentBuilder().newDocument();
110 Element createElement
= doc
.createElement(ITracePackageConstants
.TMF_EXPORT_ELEMENT
);
111 Node tmfNode
= doc
.appendChild(createElement
);
113 for (TracePackageTraceElement tracePackageElement
: fTraceExportElements
) {
114 if (!isFilesChecked(tracePackageElement
)) {
118 exportTrace(progressMonitor
, tmfNode
, tracePackageElement
);
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();
130 ModalContext
.checkCanceled(progressMonitor
);
132 exportManifest(content
);
134 setStatus(exportToArchive(progressMonitor
, totalWork
));
136 fExportFolder
.delete(true, new SubProgressMonitor(progressMonitor
, 1, SubProgressMonitor
.PREPEND_MAIN_LABEL_TO_SUBTASK
));
138 progressMonitor
.done();
140 } catch (Exception e
) {
141 if (e
instanceof InterruptedException
) {
142 setStatus(Status
.CANCEL_STATUS
);
144 setStatus(new Status(IStatus
.ERROR
, Activator
.PLUGIN_ID
, org
.eclipse
.linuxtools
.internal
.tmf
.ui
.project
.wizards
.tracepkg
.Messages
.TracePackage_ErrorOperation
, e
));
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);
154 folder
.create(IResource
.FORCE
| IResource
.HIDDEN
, true, new SubProgressMonitor(monitor
, 1, SubProgressMonitor
.PREPEND_MAIN_LABEL_TO_SUBTASK
));
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
);
165 for (TracePackageElement element
: tracePackageElement
.getChildren()) {
166 ModalContext
.checkCanceled(monitor
);
167 if (!element
.isChecked()) {
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
);
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
));
190 IFolder traceSuppFilesFolder
= suppFilesFolder
.getFolder(traceElement
.getResource().getName());
191 traceSuppFilesFolder
.create(IResource
.FORCE
, true, new SubProgressMonitor(monitor
, 1, SubProgressMonitor
.PREPEND_MAIN_LABEL_TO_SUBTASK
));
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
);
204 fResources
.add(suppFilesFolder
);
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
));
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
);
224 * Creates a linked resource in the specified folder
226 * @param exportFolder the folder that will contain the linked resource
227 * @param res the resource to export
228 * @throws CoreException when createLink fails
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);
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
);
250 for (IMarker marker
: findMarkers
) {
251 ModalContext
.checkCanceled(monitor
);
253 Element singleBookmarkXmlElement
= doc
.createElement(ITracePackageConstants
.BOOKMARK_ELEMENT
);
254 for (String key
: marker
.getAttributes().keySet()) {
255 singleBookmarkXmlElement
.setAttribute(key
, marker
.getAttribute(key
).toString());
258 bookmarksNode
.appendChild(singleBookmarkXmlElement
);
264 private void exportManifest(String content
) throws CoreException
{
265 IFile file
= fExportFolder
.getFile(ITracePackageConstants
.MANIFEST_FILENAME
);
266 ByteArrayInputStream inputStream
= new ByteArrayInputStream(content
.getBytes());
268 file
.setContents(inputStream
, IResource
.FORCE
, null);
270 file
.create(inputStream
, IResource
.FORCE
| IResource
.HIDDEN
, null);
272 fResources
.add(file
);
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
));
282 return op
.getStatus();