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 / TracePackageExtractManifestOperation.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.IOException;
16 import java.io.InputStream;
17 import java.net.URL;
18 import java.text.MessageFormat;
19 import java.util.ArrayList;
20 import java.util.Enumeration;
21 import java.util.HashMap;
22 import java.util.List;
23 import java.util.Map;
24
25 import javax.xml.XMLConstants;
26 import javax.xml.parsers.DocumentBuilderFactory;
27 import javax.xml.parsers.ParserConfigurationException;
28 import javax.xml.transform.stream.StreamSource;
29 import javax.xml.validation.Schema;
30 import javax.xml.validation.SchemaFactory;
31 import javax.xml.validation.Validator;
32
33 import org.eclipse.core.runtime.FileLocator;
34 import org.eclipse.core.runtime.IPath;
35 import org.eclipse.core.runtime.IProgressMonitor;
36 import org.eclipse.core.runtime.IStatus;
37 import org.eclipse.core.runtime.Path;
38 import org.eclipse.core.runtime.Status;
39 import org.eclipse.jface.operation.ModalContext;
40 import org.eclipse.linuxtools.internal.tmf.ui.Activator;
41 import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.AbstractTracePackageOperation;
42 import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.ITracePackageConstants;
43 import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageBookmarkElement;
44 import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageElement;
45 import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageFilesElement;
46 import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageSupplFileElement;
47 import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageSupplFilesElement;
48 import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageTraceElement;
49 import org.w3c.dom.Document;
50 import org.w3c.dom.Element;
51 import org.w3c.dom.NamedNodeMap;
52 import org.w3c.dom.Node;
53 import org.w3c.dom.NodeList;
54 import org.xml.sax.SAXException;
55
56 /**
57 * An operation that extracts information from the manifest located in an
58 * archive
59 *
60 * @author Marc-Andre Laperle
61 */
62 public class TracePackageExtractManifestOperation extends AbstractTracePackageOperation {
63
64 private static final String SCHEMA_FOLDER_NAME = "schema"; //$NON-NLS-1$
65 private static final String EXPORT_MANIFEST_SCHEMA_FILE_NAME = "export-manifest.xsd"; //$NON-NLS-1$
66
67 // Result of reading the manifest
68 private TracePackageElement fResultElement;
69
70 /**
71 * Constructs a new import operation for reading the manifest
72 *
73 * @param fileName
74 * the output file name
75 */
76 public TracePackageExtractManifestOperation(String fileName) {
77 super(fileName);
78 }
79
80 /**
81 * Run extract the manifest operation. The status (result) of the operation
82 * can be obtained with {@link #getStatus}
83 *
84 * @param progressMonitor
85 * the progress monitor to use to display progress and receive
86 * requests for cancellation
87 */
88 @Override
89 public void run(IProgressMonitor progressMonitor) {
90 TracePackageElement element = null;
91 try {
92 progressMonitor.worked(1);
93 ArchiveFile archiveFile = getSpecifiedArchiveFile();
94 progressMonitor.worked(1);
95 if (archiveFile == null) {
96 setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.TracePackageExtractManifestOperation_InvalidFormat));
97 return;
98 }
99
100 Enumeration<?> entries = archiveFile.entries();
101
102 boolean found = false;
103 while (entries.hasMoreElements()) {
104 ModalContext.checkCanceled(progressMonitor);
105
106 ArchiveEntry entry = (ArchiveEntry) entries.nextElement();
107 IPath p = new Path(entry.getName());
108 //Remove project name
109 p = p.removeFirstSegments(1);
110
111 if (entry.getName().endsWith(ITracePackageConstants.MANIFEST_FILENAME)) {
112 found = true;
113 InputStream inputStream = archiveFile.getInputStream(entry);
114 validateManifest(inputStream);
115
116 inputStream = archiveFile.getInputStream(entry);
117 element = loadElementsFromManifest(inputStream);
118 break;
119 }
120
121 progressMonitor.worked(1);
122 }
123
124 if (found) {
125 setStatus(Status.OK_STATUS);
126 }
127 else {
128 setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, MessageFormat.format(Messages.TracePackageExtractManifestOperation_ErrorManifestNotFound, ITracePackageConstants.MANIFEST_FILENAME)));
129 }
130
131 fResultElement = element;
132
133 } catch (InterruptedException e) {
134 setStatus(Status.CANCEL_STATUS);
135 } catch (Exception e) {
136 setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.TracePackageExtractManifestOperation_ErrorReadingManifest, e));
137 }
138 }
139
140 /**
141 * Get the resulting element from extracting the manifest from the archive
142 *
143 * @return the resulting element
144 */
145 public TracePackageElement getResultElement() {
146 return fResultElement;
147 }
148
149 private static void validateManifest(InputStream xml) throws IOException
150 {
151 URL schemaFileUrl = FileLocator.find(Activator.getDefault().getBundle(), new Path(SCHEMA_FOLDER_NAME).append(EXPORT_MANIFEST_SCHEMA_FILE_NAME), null);
152 if (schemaFileUrl == null) {
153 throw new IOException(MessageFormat.format(Messages.TracePackageExtractManifestOperation_SchemaFileNotFound, EXPORT_MANIFEST_SCHEMA_FILE_NAME));
154 }
155
156 try {
157 SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
158 Schema schema = factory.newSchema(new StreamSource(schemaFileUrl.openStream()));
159 Validator validator = schema.newValidator();
160 validator.validate(new StreamSource(xml));
161 } catch (SAXException e) {
162 throw new IOException(Messages.TracePackageExtractManifestOperation_ErrorManifestNotValid, e);
163 } catch (IOException e) {
164 throw new IOException(Messages.TracePackageExtractManifestOperation_ErrorManifestNotValid, e);
165 }
166 }
167
168 private static TracePackageElement loadElementsFromManifest(InputStream inputStream) throws IOException, SAXException, ParserConfigurationException {
169 TracePackageElement element = null;
170 Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(inputStream);
171
172 NodeList traceElements = doc.getDocumentElement().getElementsByTagName(ITracePackageConstants.TRACE_ELEMENT);
173 for (int i = 0; i < traceElements.getLength(); ++i) {
174 Node traceNode = traceElements.item(i);
175 if (traceNode.getNodeType() == Node.ELEMENT_NODE) {
176 Element traceElement = (Element) traceNode;
177 String traceName = traceElement.getAttribute(ITracePackageConstants.TRACE_NAME_ATTRIB);
178 String traceType = traceElement.getAttribute(ITracePackageConstants.TRACE_TYPE_ATTRIB);
179 element = new TracePackageTraceElement(null, traceName, traceType);
180
181 List<TracePackageElement> children = new ArrayList<TracePackageElement>();
182 NodeList fileElements = traceElement.getElementsByTagName(ITracePackageConstants.TRACE_FILE_ELEMENT);
183 for (int j = 0; j < fileElements.getLength(); ++j) {
184 Node fileNode = fileElements.item(j);
185 if (fileNode.getNodeType() == Node.ELEMENT_NODE) {
186 Element fileElement = (Element) fileNode;
187 String fileName = fileElement.getAttribute(ITracePackageConstants.TRACE_FILE_NAME_ATTRIB);
188 children.add(new TracePackageFilesElement(element, fileName));
189 }
190 }
191
192 TracePackageSupplFilesElement supplFilesElement = new TracePackageSupplFilesElement(element);
193
194 // Supplementary files
195 List<TracePackageSupplFileElement> suppFiles = new ArrayList<TracePackageSupplFileElement>();
196 NodeList suppFilesElements = traceElement.getElementsByTagName(ITracePackageConstants.SUPPLEMENTARY_FILE_ELEMENT);
197 for (int j = 0; j < suppFilesElements.getLength(); ++j) {
198 Node suppFileNode = suppFilesElements.item(j);
199 if (suppFileNode.getNodeType() == Node.ELEMENT_NODE) {
200 Element suppFileElement = (Element) suppFileNode;
201 String fileName = suppFileElement.getAttribute(ITracePackageConstants.SUPPLEMENTARY_FILE_NAME_ATTRIB);
202 TracePackageSupplFileElement supplFile = new TracePackageSupplFileElement(fileName, supplFilesElement);
203 suppFiles.add(supplFile);
204 }
205 }
206
207 if (!suppFiles.isEmpty()) {
208 supplFilesElement.setChildren(suppFiles.toArray(new TracePackageElement[] {}));
209 children.add(supplFilesElement);
210 }
211
212 // bookmarks
213 List<Map<String, String>> bookmarkAttribs = new ArrayList<Map<String, String>>();
214 NodeList bookmarksElements = traceElement.getElementsByTagName(ITracePackageConstants.BOOKMARKS_ELEMENT);
215 for (int j = 0; j < bookmarksElements.getLength(); ++j) {
216 Node bookmarksNode = bookmarksElements.item(j);
217 if (bookmarksNode.getNodeType() == Node.ELEMENT_NODE) {
218 NodeList bookmarkElements = traceElement.getElementsByTagName(ITracePackageConstants.BOOKMARK_ELEMENT);
219 for (int k = 0; k < bookmarkElements.getLength(); ++k) {
220 Node bookmarkNode = bookmarkElements.item(k);
221 if (bookmarkNode.getNodeType() == Node.ELEMENT_NODE) {
222 Element bookmarkElement = (Element) bookmarkNode;
223 NamedNodeMap attributesMap = bookmarkElement.getAttributes();
224 Map<String, String> attribs = new HashMap<String, String>();
225 for (int l = 0; l < attributesMap.getLength(); ++l) {
226 Node item = attributesMap.item(l);
227 attribs.put(item.getNodeName(), item.getNodeValue());
228 }
229 bookmarkAttribs.add(attribs);
230 }
231 }
232 }
233 }
234 if (!bookmarkAttribs.isEmpty()) {
235 children.add(new TracePackageBookmarkElement(element, bookmarkAttribs));
236 }
237
238 element.setChildren(children.toArray(new TracePackageElement[] {}));
239 }
240 }
241 return element;
242 }
243 }
This page took 0.052165 seconds and 5 git commands to generate.