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
.IOException
;
16 import java
.io
.InputStream
;
18 import java
.text
.MessageFormat
;
19 import java
.util
.ArrayList
;
20 import java
.util
.Enumeration
;
21 import java
.util
.HashMap
;
22 import java
.util
.HashSet
;
23 import java
.util
.List
;
27 import javax
.xml
.XMLConstants
;
28 import javax
.xml
.parsers
.DocumentBuilderFactory
;
29 import javax
.xml
.parsers
.ParserConfigurationException
;
30 import javax
.xml
.transform
.stream
.StreamSource
;
31 import javax
.xml
.validation
.Schema
;
32 import javax
.xml
.validation
.SchemaFactory
;
33 import javax
.xml
.validation
.Validator
;
35 import org
.eclipse
.core
.runtime
.FileLocator
;
36 import org
.eclipse
.core
.runtime
.IPath
;
37 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
38 import org
.eclipse
.core
.runtime
.IStatus
;
39 import org
.eclipse
.core
.runtime
.Path
;
40 import org
.eclipse
.core
.runtime
.Status
;
41 import org
.eclipse
.jface
.operation
.ModalContext
;
42 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.Activator
;
43 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.project
.wizards
.tracepkg
.AbstractTracePackageOperation
;
44 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.project
.wizards
.tracepkg
.ITracePackageConstants
;
45 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.project
.wizards
.tracepkg
.TracePackageBookmarkElement
;
46 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.project
.wizards
.tracepkg
.TracePackageElement
;
47 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.project
.wizards
.tracepkg
.TracePackageFilesElement
;
48 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.project
.wizards
.tracepkg
.TracePackageSupplFileElement
;
49 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.project
.wizards
.tracepkg
.TracePackageSupplFilesElement
;
50 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.project
.wizards
.tracepkg
.TracePackageTraceElement
;
51 import org
.w3c
.dom
.Document
;
52 import org
.w3c
.dom
.Element
;
53 import org
.w3c
.dom
.NamedNodeMap
;
54 import org
.w3c
.dom
.Node
;
55 import org
.w3c
.dom
.NodeList
;
56 import org
.xml
.sax
.SAXException
;
59 * An operation that extracts information from the manifest located in an
62 * @author Marc-Andre Laperle
64 public class TracePackageExtractManifestOperation
extends AbstractTracePackageOperation
{
66 private static final String SCHEMA_FOLDER_NAME
= "schema"; //$NON-NLS-1$
67 private static final String EXPORT_MANIFEST_SCHEMA_FILE_NAME
= "export-manifest.xsd"; //$NON-NLS-1$
69 // Result of reading the manifest
70 private TracePackageElement
[] fResultElements
;
73 * Constructs a new import operation for reading the manifest
76 * the output file name
78 public TracePackageExtractManifestOperation(String fileName
) {
83 * Run extract the manifest operation. The status (result) of the operation
84 * can be obtained with {@link #getStatus}
86 * @param progressMonitor
87 * the progress monitor to use to display progress and receive
88 * requests for cancellation
91 public void run(IProgressMonitor progressMonitor
) {
92 TracePackageElement
[] elements
= null;
94 progressMonitor
.worked(1);
95 ArchiveFile archiveFile
= getSpecifiedArchiveFile();
96 progressMonitor
.worked(1);
97 if (archiveFile
== null) {
98 setStatus(new Status(IStatus
.ERROR
, Activator
.PLUGIN_ID
, Messages
.TracePackageExtractManifestOperation_InvalidFormat
));
102 Enumeration
<?
> entries
= archiveFile
.entries();
104 boolean found
= false;
105 while (entries
.hasMoreElements()) {
106 ModalContext
.checkCanceled(progressMonitor
);
108 ArchiveEntry entry
= (ArchiveEntry
) entries
.nextElement();
109 IPath p
= new Path(entry
.getName());
110 //Remove project name
111 p
= p
.removeFirstSegments(1);
113 if (entry
.getName().endsWith(ITracePackageConstants
.MANIFEST_FILENAME
)) {
115 InputStream inputStream
= archiveFile
.getInputStream(entry
);
116 validateManifest(inputStream
);
118 inputStream
= archiveFile
.getInputStream(entry
);
119 elements
= loadElementsFromManifest(inputStream
);
123 progressMonitor
.worked(1);
127 setStatus(Status
.OK_STATUS
);
130 elements
= generateElementsFromArchive();
131 if (elements
.length
> 0) {
132 setStatus(Status
.OK_STATUS
);
134 setStatus(new Status(IStatus
.ERROR
, Activator
.PLUGIN_ID
, MessageFormat
.format(Messages
.TracePackageExtractManifestOperation_ErrorManifestNotFound
, ITracePackageConstants
.MANIFEST_FILENAME
)));
138 fResultElements
= elements
;
140 } catch (InterruptedException e
) {
141 setStatus(Status
.CANCEL_STATUS
);
142 } catch (Exception e
) {
143 setStatus(new Status(IStatus
.ERROR
, Activator
.PLUGIN_ID
, Messages
.TracePackageExtractManifestOperation_ErrorReadingManifest
, e
));
147 private TracePackageElement
[] generateElementsFromArchive() {
148 ArchiveFile archiveFile
= getSpecifiedArchiveFile();
149 Enumeration
<?
> entries
= archiveFile
.entries();
150 Set
<String
> traceFileNames
= new HashSet
<>();
151 while (entries
.hasMoreElements()) {
152 ArchiveEntry entry
= (ArchiveEntry
) entries
.nextElement();
153 String entryName
= entry
.getName();
154 IPath fullArchivePath
= new Path(entryName
);
155 if (!fullArchivePath
.hasTrailingSeparator() && fullArchivePath
.segmentCount() > 0) {
156 traceFileNames
.add(fullArchivePath
.segment(0));
160 List
<TracePackageElement
> packageElements
= new ArrayList
<>();
161 for (String traceFileName
: traceFileNames
) {
162 TracePackageTraceElement traceElement
= new TracePackageTraceElement(null, traceFileName
, null);
163 traceElement
.setChildren(new TracePackageElement
[] { new TracePackageFilesElement(traceElement
, traceFileName
) });
164 packageElements
.add(traceElement
);
167 return packageElements
.toArray(new TracePackageElement
[] {});
171 * Get the resulting element from extracting the manifest from the archive
173 * @return the resulting element
175 public TracePackageElement
[] getResultElement() {
176 return fResultElements
;
179 private static void validateManifest(InputStream xml
) throws IOException
181 URL schemaFileUrl
= FileLocator
.find(Activator
.getDefault().getBundle(), new Path(SCHEMA_FOLDER_NAME
).append(EXPORT_MANIFEST_SCHEMA_FILE_NAME
), null);
182 if (schemaFileUrl
== null) {
183 throw new IOException(MessageFormat
.format(Messages
.TracePackageExtractManifestOperation_SchemaFileNotFound
, EXPORT_MANIFEST_SCHEMA_FILE_NAME
));
187 SchemaFactory factory
= SchemaFactory
.newInstance(XMLConstants
.W3C_XML_SCHEMA_NS_URI
);
188 Schema schema
= factory
.newSchema(new StreamSource(schemaFileUrl
.openStream()));
189 Validator validator
= schema
.newValidator();
190 validator
.validate(new StreamSource(xml
));
191 } catch (SAXException e
) {
192 throw new IOException(Messages
.TracePackageExtractManifestOperation_ErrorManifestNotValid
, e
);
193 } catch (IOException e
) {
194 throw new IOException(Messages
.TracePackageExtractManifestOperation_ErrorManifestNotValid
, e
);
198 private static TracePackageElement
[] loadElementsFromManifest(InputStream inputStream
) throws IOException
, SAXException
, ParserConfigurationException
{
199 List
<TracePackageElement
> packageElements
= new ArrayList
<>();
200 TracePackageElement element
= null;
201 Document doc
= DocumentBuilderFactory
.newInstance().newDocumentBuilder().parse(inputStream
);
203 NodeList traceElements
= doc
.getDocumentElement().getElementsByTagName(ITracePackageConstants
.TRACE_ELEMENT
);
204 for (int i
= 0; i
< traceElements
.getLength(); ++i
) {
205 Node traceNode
= traceElements
.item(i
);
206 if (traceNode
.getNodeType() == Node
.ELEMENT_NODE
) {
207 Element traceElement
= (Element
) traceNode
;
208 String traceName
= traceElement
.getAttribute(ITracePackageConstants
.TRACE_NAME_ATTRIB
);
209 String traceType
= traceElement
.getAttribute(ITracePackageConstants
.TRACE_TYPE_ATTRIB
);
210 element
= new TracePackageTraceElement(null, traceName
, traceType
);
212 List
<TracePackageElement
> children
= new ArrayList
<>();
213 NodeList fileElements
= traceElement
.getElementsByTagName(ITracePackageConstants
.TRACE_FILE_ELEMENT
);
214 for (int j
= 0; j
< fileElements
.getLength(); ++j
) {
215 Node fileNode
= fileElements
.item(j
);
216 if (fileNode
.getNodeType() == Node
.ELEMENT_NODE
) {
217 Element fileElement
= (Element
) fileNode
;
218 String fileName
= fileElement
.getAttribute(ITracePackageConstants
.TRACE_FILE_NAME_ATTRIB
);
219 children
.add(new TracePackageFilesElement(element
, fileName
));
223 TracePackageSupplFilesElement supplFilesElement
= new TracePackageSupplFilesElement(element
);
225 // Supplementary files
226 List
<TracePackageSupplFileElement
> suppFiles
= new ArrayList
<>();
227 NodeList suppFilesElements
= traceElement
.getElementsByTagName(ITracePackageConstants
.SUPPLEMENTARY_FILE_ELEMENT
);
228 for (int j
= 0; j
< suppFilesElements
.getLength(); ++j
) {
229 Node suppFileNode
= suppFilesElements
.item(j
);
230 if (suppFileNode
.getNodeType() == Node
.ELEMENT_NODE
) {
231 Element suppFileElement
= (Element
) suppFileNode
;
232 String fileName
= suppFileElement
.getAttribute(ITracePackageConstants
.SUPPLEMENTARY_FILE_NAME_ATTRIB
);
233 TracePackageSupplFileElement supplFile
= new TracePackageSupplFileElement(fileName
, supplFilesElement
);
234 suppFiles
.add(supplFile
);
238 if (!suppFiles
.isEmpty()) {
239 supplFilesElement
.setChildren(suppFiles
.toArray(new TracePackageElement
[] {}));
240 children
.add(supplFilesElement
);
244 List
<Map
<String
, String
>> bookmarkAttribs
= new ArrayList
<>();
245 NodeList bookmarksElements
= traceElement
.getElementsByTagName(ITracePackageConstants
.BOOKMARKS_ELEMENT
);
246 for (int j
= 0; j
< bookmarksElements
.getLength(); ++j
) {
247 Node bookmarksNode
= bookmarksElements
.item(j
);
248 if (bookmarksNode
.getNodeType() == Node
.ELEMENT_NODE
) {
249 NodeList bookmarkElements
= traceElement
.getElementsByTagName(ITracePackageConstants
.BOOKMARK_ELEMENT
);
250 for (int k
= 0; k
< bookmarkElements
.getLength(); ++k
) {
251 Node bookmarkNode
= bookmarkElements
.item(k
);
252 if (bookmarkNode
.getNodeType() == Node
.ELEMENT_NODE
) {
253 Element bookmarkElement
= (Element
) bookmarkNode
;
254 NamedNodeMap attributesMap
= bookmarkElement
.getAttributes();
255 Map
<String
, String
> attribs
= new HashMap
<>();
256 for (int l
= 0; l
< attributesMap
.getLength(); ++l
) {
257 Node item
= attributesMap
.item(l
);
258 attribs
.put(item
.getNodeName(), item
.getNodeValue());
260 bookmarkAttribs
.add(attribs
);
265 if (!bookmarkAttribs
.isEmpty()) {
266 children
.add(new TracePackageBookmarkElement(element
, bookmarkAttribs
));
269 element
.setChildren(children
.toArray(new TracePackageElement
[] {}));
270 packageElements
.add(element
);
273 return packageElements
.toArray(new TracePackageElement
[] {});