blob: b40bd1646e4f1042d243a5b65280331c9df4b9a0 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2015 Ericsson
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License 2.0 which
* accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Marc-Andre Laperle - Initial API and implementation
*******************************************************************************/
package org.eclipse.tracecompass.internal.tmf.remote.ui.wizards.fetch.model;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import javax.xml.XMLConstants;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.tracecompass.common.core.xml.XmlUtils;
import org.eclipse.tracecompass.internal.tmf.remote.ui.Activator;
import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageElement;
import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.importexport.ManifestReader;
import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.importexport.Messages;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
/**
* Reads a profiles file from an input stream
*
* @author Marc-Andre Laperle
*/
public class RemoteImportProfilesReader {
private static final String SCHEMA_FOLDER_NAME = "schema"; //$NON-NLS-1$
private static final String PROFILES_SCHEMA_FILE_NAME = "remote-profile.xsd"; //$NON-NLS-1$
private static final @NonNull TracePackageElement @NonNull [] EMPTY_ARRAY =
new @NonNull TracePackageElement[0];
private RemoteImportProfilesReader() {
// Do nothing, private constructor
}
/**
* Validate the content of the profiles file from an input stream
*
* @param input
* the input stream to validate from
* @throws IOException
* on error
* @throws SAXException
* on error
*/
public static void validate(InputStream input) throws IOException, SAXException {
URL schemaFileUrl = FileLocator.find(
Activator.getDefault().getBundle(),
new Path(SCHEMA_FOLDER_NAME).append(PROFILES_SCHEMA_FILE_NAME),
null);
if (schemaFileUrl == null) {
throw new IOException(
MessageFormat.format(
Messages.TracePackageExtractManifestOperation_SchemaFileNotFound,
PROFILES_SCHEMA_FILE_NAME));
}
try {
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = factory.newSchema(new StreamSource(
schemaFileUrl.openStream()));
if (schema == null) {
throw new SAXException("Schema failed to create"); //$NON-NLS-1$
}
XmlUtils.safeValidate(schema, new StreamSource(input));
} catch (SAXException e) {
throw new SAXException(
Messages.TracePackageExtractManifestOperation_ErrorManifestNotValid,
e);
} catch (IOException e) {
throw new IOException(
Messages.TracePackageExtractManifestOperation_ErrorManifestNotValid,
e);
}
}
/**
* Load profile model elements the profiles file (input stream).
*
* The file format looks like this:
* <pre>
* &lt;?xml version="1.0" encoding="UTF-8" standalone="no"?>
* &lt;profiles>
* &lt;version>0.1&lt;/version>
* &lt;profile name="myProfile">
* &lt;node name="myhost">
* &lt;uri>ssh://user@127.0.0.1:22&lt;/uri>
* &lt;traceGroup root="/home/user/lttng-traces/" recursive="true">
* &lt;trace name="" type="org.eclipse.linuxtools.tmf.ui.type.ctf">
* &lt;file name=".*" />
* &lt;/trace>
* &lt;/traceGroup>
* &lt;/node>
* &lt;/profile>
* &lt;/profiles>
* </pre>
* See schema/remote-profile.xsd for details.
*
* @param inputStream
* the input stream that contains the profiles
* @return the loaded elements
* @throws IOException
* when an error occurs when parsing
* @throws SAXException
* when an error occurs when parsing
* @throws ParserConfigurationException
* when an error occurs when parsing
*/
public static TracePackageElement[] loadElementsFromProfiles(InputStream inputStream)
throws IOException, SAXException, ParserConfigurationException {
List<TracePackageElement> packageElements = new ArrayList<>();
RemoteImportProfileElement profile = null;
Document doc = XmlUtils.newSafeDocumentBuilderFactory().newDocumentBuilder().parse(
inputStream);
NodeList profileNodes = doc.getDocumentElement().getElementsByTagName(
RemoteImportProfileConstants.PROFILE_ELEMENT);
for (int i = 0; i < profileNodes.getLength(); i++) {
Node profileNode = profileNodes.item(i);
if (profileNode.getNodeType() == Node.ELEMENT_NODE) {
Element profileElement = (Element) profileNode;
String traceName = profileElement.getAttribute(RemoteImportProfileConstants.PROFILE_NAME_ATTRIB);
profile = new RemoteImportProfileElement(null, traceName);
NodeList nodeNodes = profileElement.getElementsByTagName(RemoteImportProfileConstants.NODE_ELEMENT);
for (int j = 0; j < nodeNodes.getLength(); j++) {
Node nodeNode = nodeNodes.item(j);
if (nodeNode.getNodeType() == Node.ELEMENT_NODE) {
Element nodeElement = (Element) nodeNode;
String nameAttr = nodeElement.getAttribute(RemoteImportProfileConstants.NODE_NAME_ATTRIB);
NodeList uriNodes = nodeElement.getElementsByTagName(RemoteImportProfileConstants.NODE_URI_ELEMENT);
String uri = ""; //$NON-NLS-1$
for (int k = 0; k < uriNodes.getLength(); k++) {
Node uriNode = uriNodes.item(k);
if (uriNode.getNodeType() == Node.ELEMENT_NODE) {
Element uriElement = (Element) uriNode;
uri = uriElement.getFirstChild().getNodeValue();
break;
}
}
RemoteImportConnectionNodeElement connectionNode = new RemoteImportConnectionNodeElement(profile,
nameAttr, uri);
NodeList traceGroupNodes = nodeElement.getElementsByTagName(RemoteImportProfileConstants.TRACE_GROUP_ELEMENT);
for (int k = 0; k < traceGroupNodes.getLength(); k++) {
Node traceGroupNode = traceGroupNodes.item(k);
if (traceGroupNode.getNodeType() == Node.ELEMENT_NODE) {
Element traceGroupElement = (Element) traceGroupNode;
String rootAttr = traceGroupElement.getAttribute(RemoteImportProfileConstants.TRACE_GROUP_ROOT_ATTRIB);
String recursiveAttr = traceGroupElement.getAttribute(RemoteImportProfileConstants.TRACE_GROUP_RECURSIVE_ATTRIB);
RemoteImportTraceGroupElement traceGroup = new RemoteImportTraceGroupElement(
connectionNode, rootAttr);
traceGroup.setRecursive(Boolean.TRUE.toString().equals(
recursiveAttr));
TracePackageElement[] e = ManifestReader.loadElementsFromNode(traceGroupElement);
for (TracePackageElement a : e) {
traceGroup.addChild(a);
}
}
}
}
}
packageElements.add(profile);
}
}
return packageElements.toArray(EMPTY_ARRAY);
}
}