Commit | Line | Data |
---|---|---|
30bf6b07 MAL |
1 | /******************************************************************************* |
2 | * Copyright (c) 2013, 2014 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.HashMap; | |
21 | import java.util.List; | |
22 | import java.util.Map; | |
23 | ||
24 | import javax.xml.XMLConstants; | |
25 | import javax.xml.parsers.DocumentBuilderFactory; | |
26 | import javax.xml.parsers.ParserConfigurationException; | |
27 | import javax.xml.transform.stream.StreamSource; | |
28 | import javax.xml.validation.Schema; | |
29 | import javax.xml.validation.SchemaFactory; | |
30 | import javax.xml.validation.Validator; | |
31 | ||
32 | import org.eclipse.core.runtime.FileLocator; | |
33 | import org.eclipse.core.runtime.Path; | |
34 | import org.eclipse.linuxtools.internal.tmf.ui.Activator; | |
35 | import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.ITracePackageConstants; | |
36 | import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageBookmarkElement; | |
37 | import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageElement; | |
38 | import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageFilesElement; | |
39 | import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageSupplFileElement; | |
40 | import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageSupplFilesElement; | |
41 | import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageTraceElement; | |
42 | import org.w3c.dom.Document; | |
43 | import org.w3c.dom.Element; | |
44 | import org.w3c.dom.NamedNodeMap; | |
45 | import org.w3c.dom.Node; | |
46 | import org.w3c.dom.NodeList; | |
47 | import org.xml.sax.SAXException; | |
48 | ||
49 | /** | |
50 | * Reads a manifest from an input stream | |
51 | * | |
52 | * @author Marc-Andre Laperle | |
53 | */ | |
54 | public class ManifestReader { | |
55 | ||
56 | private static final String SCHEMA_FOLDER_NAME = "schema"; //$NON-NLS-1$ | |
57 | private static final String EXPORT_MANIFEST_SCHEMA_FILE_NAME = "export-manifest.xsd"; //$NON-NLS-1$ | |
58 | private static final TracePackageElement [] EMPTY_ARRAY = new TracePackageElement[0]; | |
59 | ||
60 | /** | |
61 | * Validate the content of a manifest from an input stream | |
62 | * | |
63 | * @param input the input stream to validate from | |
64 | * @throws IOException on error | |
65 | */ | |
66 | public static void validateManifest(InputStream input) throws IOException | |
67 | { | |
68 | URL schemaFileUrl = FileLocator.find(Activator.getDefault().getBundle(), new Path(SCHEMA_FOLDER_NAME).append(EXPORT_MANIFEST_SCHEMA_FILE_NAME), null); | |
69 | if (schemaFileUrl == null) { | |
70 | throw new IOException(MessageFormat.format(Messages.TracePackageExtractManifestOperation_SchemaFileNotFound, EXPORT_MANIFEST_SCHEMA_FILE_NAME)); | |
71 | } | |
72 | ||
73 | try { | |
74 | SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); | |
75 | Schema schema = factory.newSchema(new StreamSource(schemaFileUrl.openStream())); | |
76 | Validator validator = schema.newValidator(); | |
77 | validator.validate(new StreamSource(input)); | |
78 | } catch (SAXException e) { | |
79 | throw new IOException(Messages.TracePackageExtractManifestOperation_ErrorManifestNotValid, e); | |
80 | } catch (IOException e) { | |
81 | throw new IOException(Messages.TracePackageExtractManifestOperation_ErrorManifestNotValid, e); | |
82 | } | |
83 | } | |
84 | ||
85 | /** | |
86 | * Load package elements from a manifest (input stream) | |
87 | * | |
88 | * The manifest looks like this: | |
89 | * | |
90 | * <?xml version="1.0" encoding="UTF-8" standalone="no"?> | |
91 | * <tmf-export> | |
92 | * <trace name="trace2" type="org.eclipse.linuxtools.lttng2.kernel.tracetype"> | |
93 | * <file name="Traces/trace2"/> <supplementary-file name=".tracing/trace2/stateHistory.ht"/> | |
94 | * <bookmarks> | |
95 | * <bookmark location="4" message= "15:50:47.314 069 885, channel0_0, sys_recvmsg, fd=16, msg=0x7faada7d1ae0, flags=256" /> | |
96 | * </bookmarks> | |
97 | * </trace> | |
98 | * </tmf-export> | |
99 | * | |
100 | * See schema/export-manifest.xsd for details. | |
101 | * | |
102 | * @param inputStream | |
103 | * the input stream that contains the manifest | |
104 | * @return the loaded elements | |
105 | * @throws IOException | |
106 | * when an error occurs when parsing | |
107 | * @throws SAXException | |
108 | * when an error occurs when parsing | |
109 | * @throws ParserConfigurationException | |
110 | * when an error occurs when parsing | |
111 | */ | |
112 | public static TracePackageElement[] loadElementsFromManifest(InputStream inputStream) throws IOException, SAXException, ParserConfigurationException { | |
113 | ||
114 | List<TracePackageElement> packageElements = new ArrayList<>(); | |
115 | TracePackageElement element = null; | |
116 | Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(inputStream); | |
117 | ||
118 | NodeList traceElements = doc.getDocumentElement().getElementsByTagName(ITracePackageConstants.TRACE_ELEMENT); | |
119 | for (int i = 0; i < traceElements.getLength(); i++) { | |
120 | Node traceNode = traceElements.item(i); | |
121 | if (traceNode.getNodeType() == Node.ELEMENT_NODE) { | |
122 | Element traceElement = (Element) traceNode; | |
123 | String traceName = traceElement.getAttribute(ITracePackageConstants.TRACE_NAME_ATTRIB); | |
124 | String traceType = traceElement.getAttribute(ITracePackageConstants.TRACE_TYPE_ATTRIB); | |
125 | element = new TracePackageTraceElement(null, traceName, traceType); | |
126 | ||
127 | List<TracePackageElement> children = new ArrayList<>(); | |
128 | NodeList fileElements = traceElement.getElementsByTagName(ITracePackageConstants.TRACE_FILE_ELEMENT); | |
129 | for (int j = 0; j < fileElements.getLength(); j++) { | |
130 | Node fileNode = fileElements.item(j); | |
131 | if (fileNode.getNodeType() == Node.ELEMENT_NODE) { | |
132 | Element fileElement = (Element) fileNode; | |
133 | String fileName = fileElement.getAttribute(ITracePackageConstants.TRACE_FILE_NAME_ATTRIB); | |
134 | children.add(new TracePackageFilesElement(element, fileName)); | |
135 | } | |
136 | } | |
137 | ||
138 | TracePackageSupplFilesElement supplFilesElement = new TracePackageSupplFilesElement(element); | |
139 | ||
140 | // Supplementary files | |
141 | List<TracePackageSupplFileElement> suppFiles = new ArrayList<>(); | |
142 | NodeList suppFilesElements = traceElement.getElementsByTagName(ITracePackageConstants.SUPPLEMENTARY_FILE_ELEMENT); | |
143 | for (int j = 0; j < suppFilesElements.getLength(); j++) { | |
144 | Node suppFileNode = suppFilesElements.item(j); | |
145 | if (suppFileNode.getNodeType() == Node.ELEMENT_NODE) { | |
146 | Element suppFileElement = (Element) suppFileNode; | |
147 | String fileName = suppFileElement.getAttribute(ITracePackageConstants.SUPPLEMENTARY_FILE_NAME_ATTRIB); | |
148 | TracePackageSupplFileElement supplFile = new TracePackageSupplFileElement(fileName, supplFilesElement); | |
149 | suppFiles.add(supplFile); | |
150 | } | |
151 | } | |
152 | ||
153 | if (!suppFiles.isEmpty()) { | |
154 | supplFilesElement.setChildren(suppFiles.toArray(EMPTY_ARRAY)); | |
155 | children.add(supplFilesElement); | |
156 | } | |
157 | ||
158 | // bookmarks | |
159 | List<Map<String, String>> bookmarkAttribs = new ArrayList<>(); | |
160 | NodeList bookmarksElements = traceElement.getElementsByTagName(ITracePackageConstants.BOOKMARKS_ELEMENT); | |
161 | for (int j = 0; j < bookmarksElements.getLength(); j++) { | |
162 | Node bookmarksNode = bookmarksElements.item(j); | |
163 | if (bookmarksNode.getNodeType() == Node.ELEMENT_NODE) { | |
164 | NodeList bookmarkElements = traceElement.getElementsByTagName(ITracePackageConstants.BOOKMARK_ELEMENT); | |
165 | for (int k = 0; k < bookmarkElements.getLength(); k++) { | |
166 | Node bookmarkNode = bookmarkElements.item(k); | |
167 | if (bookmarkNode.getNodeType() == Node.ELEMENT_NODE) { | |
168 | Element bookmarkElement = (Element) bookmarkNode; | |
169 | NamedNodeMap attributesMap = bookmarkElement.getAttributes(); | |
170 | Map<String, String> attribs = new HashMap<>(); | |
171 | for (int l = 0; l < attributesMap.getLength(); l++) { | |
172 | Node item = attributesMap.item(l); | |
173 | attribs.put(item.getNodeName(), item.getNodeValue()); | |
174 | } | |
175 | bookmarkAttribs.add(attribs); | |
176 | } | |
177 | } | |
178 | } | |
179 | } | |
180 | if (!bookmarkAttribs.isEmpty()) { | |
181 | children.add(new TracePackageBookmarkElement(element, bookmarkAttribs)); | |
182 | } | |
183 | ||
184 | element.setChildren(children.toArray(EMPTY_ARRAY)); | |
185 | packageElements.add(element); | |
186 | } | |
187 | } | |
188 | return packageElements.toArray(EMPTY_ARRAY); | |
189 | } | |
190 | ||
191 | } |