/*******************************************************************************
* Copyright (c) 2015 Ericsson
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v1.0 which
* accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* 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.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.annotation.NonNull;
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];
/**
* 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()));
Validator validator = schema.newValidator();
validator.validate(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>
* <?xml version="1.0" encoding="UTF-8" standalone="no"?>
* <profiles>
* <version>0.1</version>
* <profile name="myProfile">
* <node name="myhost">
* <uri>ssh://user@127.0.0.1:22</uri>
* <traceGroup root="/home/user/lttng-traces/" recursive="true">
* <trace name="" type="org.eclipse.linuxtools.tmf.ui.type.ctf">
* <file name=".*" />
* </trace>
* </traceGroup>
* </node>
* </profile>
* </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 = DocumentBuilderFactory.newInstance().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);
}
}