Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %Bundle-Name
-Bundle-SymbolicName: org.eclipse.tracecompass.tmf.analysis.xml.core.tests
+Bundle-SymbolicName: org.eclipse.tracecompass.tmf.analysis.xml.core.tests;singleton:=true
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: org.eclipse.tracecompass.tmf.analysis.xml.core.tests.Activator
Bundle-Vendor: %Bundle-Vendor
org.eclipse.tracecompass.statesystem.core
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-ActivationPolicy: lazy
-Import-Package: org.eclipse.tracecompass.testtraces.ctf;version="1.0.0",
+Import-Package: com.google.common.collect;version="10.0.1",
+ org.eclipse.tracecompass.testtraces.ctf;version="1.0.0",
org.junit.runners
Export-Package: org.eclipse.tracecompass.tmf.analysis.xml.core.tests,
org.eclipse.tracecompass.tmf.analysis.xml.core.tests.common;x-friends:="org.eclipse.tracecompass.tmf.analysis.xml.ui.tests"
bin.includes = META-INF/,\
.,\
about.html,\
+ plugin.xml,\
test_xml_files/
src.includes = about.html
additional.bundles = org.eclipse.jdt.annotation
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+ <extension
+ point="org.eclipse.linuxtools.tmf.analysis.xml.core.files">
+ <xmlfile
+ file="test_xml_files/test_builtin.xml">
+ </xmlfile>
+ </extension>
+
+</plugin>
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2014 École Polytechnique de Montréal
+ *
+ * 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:
+ * Geneviève Bastien - Initial implementation
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.tmf.analysis.xml.core.tests.module;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+
+import org.eclipse.tracecompass.tmf.analysis.xml.core.module.XmlAnalysisModuleSource;
+import org.eclipse.tracecompass.tmf.analysis.xml.core.module.XmlUtils;
+import org.eclipse.tracecompass.tmf.analysis.xml.core.tests.common.TmfXmlTestFiles;
+import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModuleHelper;
+import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisManager;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.collect.Multimap;
+
+/**
+ * Test suite for the {@link XmlAnalysisModuleSource} class
+ *
+ * @author Geneviève Bastien
+ */
+public class XmlAnalysisModuleSourceTest {
+
+ private static final String SS_MODULE = "kernel.linux.sp";
+ private static final String BUILTIN_MODULE = "test.builtin.sp";
+
+ private static void emptyXmlFolder() {
+ File fFolder = XmlUtils.getXmlFilesPath().toFile();
+ if (!(fFolder.isDirectory() && fFolder.exists())) {
+ return;
+ }
+ for (File xmlFile : fFolder.listFiles()) {
+ xmlFile.delete();
+ }
+ XmlAnalysisModuleSource.notifyModuleChange();
+ }
+
+ /**
+ * Empty the XML directory before the test, just in case
+ */
+ @Before
+ public void setUp() {
+ emptyXmlFolder();
+ }
+
+ /**
+ * Empty the XML directory after the test
+ */
+ @After
+ public void cleanUp() {
+ emptyXmlFolder();
+ }
+
+ /**
+ * Test the {@link XmlAnalysisModuleSource#getAnalysisModules()} method
+ */
+ @Test
+ public void testPopulateModules() {
+ XmlAnalysisModuleSource module = new XmlAnalysisModuleSource();
+
+ Iterable<IAnalysisModuleHelper> modules = module.getAnalysisModules();
+ assertFalse("Module present", findModule(modules, SS_MODULE));
+
+ /* Test that the builtin module is present */
+ assertTrue("builtin module present", findModule(modules, BUILTIN_MODULE));
+
+ /* use the valid XML test file */
+ File testXmlFile = TmfXmlTestFiles.VALID_FILE.getFile();
+ if ((testXmlFile == null) || !testXmlFile.exists()) {
+ fail("XML test file does not exist");
+ }
+
+ XmlUtils.addXmlFile(testXmlFile);
+ XmlAnalysisModuleSource.notifyModuleChange();
+ modules = module.getAnalysisModules();
+
+ assertTrue("Modules available from source", modules.iterator().hasNext());
+ assertTrue("Module present after add file", findModule(modules, SS_MODULE));
+ assertTrue("Builtin module present after add file", findModule(modules, BUILTIN_MODULE));
+ }
+
+ private static boolean findModule(Iterable<IAnalysisModuleHelper> modules, String moduleName) {
+ for (IAnalysisModuleHelper helper : modules) {
+ if (moduleName.equals(helper.getId())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Test that XML modules are available through the analysis manager
+ */
+ @Test
+ public void testPopulateModulesWithAnalysisManager() {
+
+ /*
+ * Make sure module sources are initialized. When run as unit test, the
+ * XML module source is sometimes missing
+ */
+ TmfAnalysisManager.initialize();
+
+ Multimap<String, IAnalysisModuleHelper> modules = TmfAnalysisManager.getAnalysisModules();
+ assertFalse(findModule(modules.values(), SS_MODULE));
+ /* Test that the builtin module is present */
+ assertTrue(findModule(modules.values(), BUILTIN_MODULE));
+
+ /* use the valid XML test file */
+ File testXmlFile = TmfXmlTestFiles.VALID_FILE.getFile();
+ if ((testXmlFile == null) || !testXmlFile.exists()) {
+ fail("XML test file does not exist");
+ }
+
+ XmlUtils.addXmlFile(testXmlFile);
+ XmlAnalysisModuleSource.notifyModuleChange();
+ modules = TmfAnalysisManager.getAnalysisModules();
+ assertTrue(findModule(modules.values(), SS_MODULE));
+ assertTrue(findModule(modules.values(), BUILTIN_MODULE));
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- ***************************************************************************
+* Copyright (c) 2014 École Polytechnique de Montréal
+*
+* 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:
+* Geneviève Bastien - Initial API and implementation
+*************************************************************************** -->
+<tmfxml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="xmldefinition.xsd">
+
+ <stateProvider id="test.builtin.sp" version="1">
+ <head>
+ <label value="Test a builtin XML module file" />
+ </head>
+
+ <eventHandler eventName="test">
+ <stateChange>
+ <stateAttribute type="constant" value="cpu" />
+ <stateValue type="eventField" value="cpu" />
+ </stateChange>
+ </eventHandler>
+ </stateProvider>
+</tmfxml>
\ No newline at end of file
Bundle-ManifestVersion: 2
Bundle-Name: %Bundle-Name
Bundle-Vendor: %Bundle-Vendor
-Bundle-Version: 1.0.0.qualifier
+Bundle-Version: 2.0.0.qualifier
Bundle-Localization: plugin
Bundle-SymbolicName: org.eclipse.tracecompass.tmf.analysis.xml.core;singleton:=true
Bundle-Activator: org.eclipse.tracecompass.internal.tmf.analysis.xml.core.Activator
<?eclipse version="3.4"?>
<plugin>
<extension-point id="org.eclipse.linuxtools.tmf.analysis.xml.core.files" name="%extensionpoint.xml_files.name" schema="schema/org.eclipse.linuxtools.tmf.analysis.xml.core.files.exsd"/>
-
+ <extension
+ point="org.eclipse.linuxtools.tmf.core.analysis">
+ <source
+ class="org.eclipse.tracecompass.tmf.analysis.xml.core.module.XmlAnalysisModuleSource">
+ </source>
+ </extension>
</plugin>
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2014, 2016 École Polytechnique de Montréal
+ *
+ * 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
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.tmf.analysis.xml.core.module;
+
+import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
+
+import java.io.File;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.Activator;
+import org.eclipse.tracecompass.tmf.analysis.xml.core.stateprovider.TmfXmlStrings;
+import org.eclipse.tracecompass.tmf.analysis.xml.core.stateprovider.XmlStateSystemModule;
+import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule;
+import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModuleHelper;
+import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisManager;
+import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisRequirement;
+import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException;
+import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType;
+import org.eclipse.tracecompass.tmf.core.project.model.TraceTypeHelper;
+import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+import org.osgi.framework.Bundle;
+import org.w3c.dom.Element;
+
+/**
+ * Analysis module helpers for modules provided by XML files
+ *
+ * @author Geneviève Bastien
+ * @since 2.0
+ */
+public class TmfAnalysisModuleHelperXml implements IAnalysisModuleHelper {
+
+ /**
+ * The types of analysis that can be XML-defined
+ */
+ public enum XmlAnalysisModuleType {
+ /** Analysis will be of type XmlStateSystemModule */
+ STATE_SYSTEM
+ }
+
+ private final File fSourceFile;
+ private final Element fSourceElement;
+ private final XmlAnalysisModuleType fType;
+
+ /**
+ * Constructor
+ *
+ * @param xmlFile
+ * The XML file containing the details of this analysis
+ * @param node
+ * The XML node element
+ * @param type
+ * The type of analysis
+ */
+ public TmfAnalysisModuleHelperXml(File xmlFile, Element node, XmlAnalysisModuleType type) {
+ fSourceFile = xmlFile;
+ fSourceElement = node;
+ fType = type;
+ }
+
+ @Override
+ public String getId() {
+ /*
+ * The attribute ID cannot be null because the XML has been validated
+ * and it is mandatory
+ */
+ return checkNotNull(fSourceElement.getAttribute(TmfXmlStrings.ID));
+ }
+
+ @Override
+ public String getName() {
+ String name = null;
+ /* Label may be available in XML header */
+ List<Element> head = XmlUtils.getChildElements(fSourceElement, TmfXmlStrings.HEAD);
+ if (head.size() == 1) {
+ List<Element> labels = XmlUtils.getChildElements(head.get(0), TmfXmlStrings.LABEL);
+ if (!labels.isEmpty()) {
+ name = labels.get(0).getAttribute(TmfXmlStrings.VALUE);
+ }
+ }
+
+ if (name == null) {
+ name = getId();
+ }
+ return name;
+ }
+
+ @Override
+ public boolean isAutomatic() {
+ return false;
+ }
+
+ /**
+ * @since 1.0
+ */
+ @Override
+ public boolean appliesToExperiment() {
+ return false;
+ }
+
+ @Override
+ public String getHelpText() {
+ return ""; //$NON-NLS-1$
+ }
+
+ @Override
+ public String getHelpText(@NonNull ITmfTrace trace) {
+ return ""; //$NON-NLS-1$
+ }
+
+ @Override
+ public String getIcon() {
+ return null;
+ }
+
+ @Override
+ public Bundle getBundle() {
+ return Activator.getDefault().getBundle();
+ }
+
+ @Override
+ public boolean appliesToTraceType(Class<? extends ITmfTrace> traceClass) {
+ /* Trace types may be available in XML header */
+ List<Element> head = XmlUtils.getChildElements(fSourceElement, TmfXmlStrings.HEAD);
+ if (head.size() != 1) {
+ return true;
+ }
+ /*
+ * TODO: Test with custom trace types
+ */
+ List<Element> elements = XmlUtils.getChildElements(head.get(0), TmfXmlStrings.TRACETYPE);
+ if (elements.isEmpty()) {
+ return true;
+ }
+
+ for (Element element : elements) {
+ String traceTypeId = element.getAttribute(TmfXmlStrings.ID);
+ traceTypeId = TmfTraceType.buildCompatibilityTraceTypeId(traceTypeId);
+ TraceTypeHelper helper = TmfTraceType.getTraceType(traceTypeId);
+ if ((helper != null) && helper.getTrace().getClass().isAssignableFrom(traceClass)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public Iterable<Class<? extends ITmfTrace>> getValidTraceTypes() {
+ return Collections.EMPTY_SET;
+ }
+
+ @Override
+ public Iterable<TmfAnalysisRequirement> getAnalysisRequirements() {
+ return Collections.EMPTY_SET;
+ }
+
+ @Override
+ public IAnalysisModule newModule(ITmfTrace trace) throws TmfAnalysisException {
+ String analysisid = getId();
+ IAnalysisModule module = null;
+ switch (fType) {
+ case STATE_SYSTEM:
+ module = new XmlStateSystemModule();
+ XmlStateSystemModule ssModule = (XmlStateSystemModule) module;
+ module.setId(analysisid);
+ ssModule.setXmlFile(new Path(fSourceFile.getAbsolutePath()));
+
+ /*
+ * FIXME: There is no way to know if a module is automatic, so we
+ * default to true
+ */
+ ssModule.setAutomatic(true);
+
+ break;
+ default:
+ break;
+
+ }
+ if (module != null) {
+ if (module.setTrace(trace)) {
+ TmfAnalysisManager.analysisModuleCreated(module);
+ } else {
+ /* The analysis does not apply to the trace, dispose of the module */
+ module.dispose();
+ module = null;
+ }
+ }
+
+ return module;
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2014, 2016 École Polytechnique de Montréal and others
+ *
+ * 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
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.tmf.analysis.xml.core.module;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.URL;
+import java.nio.channels.FileChannel;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.ISafeRunnable;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.SafeRunner;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.Activator;
+import org.eclipse.tracecompass.tmf.analysis.xml.core.module.TmfAnalysisModuleHelperXml.XmlAnalysisModuleType;
+import org.eclipse.tracecompass.tmf.analysis.xml.core.stateprovider.TmfXmlStrings;
+import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModuleHelper;
+import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModuleSource;
+import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisManager;
+import org.osgi.framework.Bundle;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+/**
+ * Analysis module source who creates helpers for the analysis modules described
+ * in the imported XML files
+ *
+ * @author Geneviève Bastien
+ * @since 2.0
+ */
+public class XmlAnalysisModuleSource implements IAnalysisModuleSource {
+
+ /** Extension point ID */
+ private static final String TMF_XML_BUILTIN_ID = "org.eclipse.linuxtools.tmf.analysis.xml.core.files"; //$NON-NLS-1$
+ private static final String XML_FILE_ELEMENT = "xmlfile"; //$NON-NLS-1$
+
+ private static final String XML_FILE_ATTRIB = "file"; //$NON-NLS-1$
+
+ /*
+ * Legacy (Linux Tools) XML directory.
+ * TODO Remove once we feel the transition phase is over.
+ */
+ private static final IPath XML_DIRECTORY_LEGACY =
+ Activator.getDefault().getStateLocation().removeLastSegments(1)
+ .append("org.eclipse.linuxtools.tmf.analysis.xml.core") //$NON-NLS-1$
+ .append("xml_files"); //$NON-NLS-1$
+
+ private static List<@NonNull IAnalysisModuleHelper> fModules = null;
+
+ /**
+ * Constructor. It adds the new module listener to the analysis manager.
+ */
+ public XmlAnalysisModuleSource() {
+
+ }
+
+ @Override
+ public synchronized Iterable<IAnalysisModuleHelper> getAnalysisModules() {
+ List<@NonNull IAnalysisModuleHelper> modules = fModules;
+ if (modules == null) {
+ modules = new ArrayList<>();
+ fModules = modules;
+ populateBuiltinModules();
+ populateAnalysisModules();
+ }
+ return modules;
+ }
+
+ private static void processFile(File xmlFile) {
+ if (!XmlUtils.xmlValidate(xmlFile).isOK()) {
+ return;
+ }
+
+ try {
+ /* Load the XML File */
+ DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
+ Document doc = dBuilder.parse(xmlFile);
+ doc.getDocumentElement().normalize();
+
+ /* get State Providers modules */
+ NodeList stateproviderNodes = doc.getElementsByTagName(TmfXmlStrings.STATE_PROVIDER);
+ for (int i = 0; i < stateproviderNodes.getLength(); i++) {
+ Element node = (Element) stateproviderNodes.item(i);
+
+ IAnalysisModuleHelper helper = new TmfAnalysisModuleHelperXml(xmlFile, node, XmlAnalysisModuleType.STATE_SYSTEM);
+ fModules.add(helper);
+ }
+ } catch (ParserConfigurationException | SAXException | IOException e) {
+ Activator.logError("Error opening XML file", e); //$NON-NLS-1$
+ }
+ }
+
+ private static void populateBuiltinModules() {
+ /* Get the XML files advertised through the extension point */
+ IConfigurationElement[] elements = Platform.getExtensionRegistry().getConfigurationElementsFor(TMF_XML_BUILTIN_ID);
+ for (IConfigurationElement element : elements) {
+ if (element.getName().equals(XML_FILE_ELEMENT)) {
+ final String filename = element.getAttribute(XML_FILE_ATTRIB);
+ final String name = element.getContributor().getName();
+ // Run this in a safe runner in case there is an exception
+ // (IOException, FileNotFoundException, NPE, etc).
+ // This makes sure other extensions are not prevented from
+ // working if one is faulty.
+ SafeRunner.run(new ISafeRunnable() {
+
+ @Override
+ public void run() throws Exception {
+ if (name != null) {
+ Bundle bundle = Platform.getBundle(name);
+ if (bundle != null) {
+ URL xmlUrl = bundle.getResource(filename);
+ if (xmlUrl == null) {
+ throw new FileNotFoundException(filename);
+ }
+ URL locatedURL = FileLocator.toFileURL(xmlUrl);
+ processFile(new File(locatedURL.getFile()));
+ }
+ }
+ }
+
+ @Override
+ public void handleException(Throwable exception) {
+ // Handled sufficiently in SafeRunner
+ }
+ });
+ }
+ }
+ }
+
+ private static void populateAnalysisModules() {
+ IPath pathToFiles = XmlUtils.getXmlFilesPath();
+ File fFolder = pathToFiles.toFile();
+ if (!(fFolder.isDirectory() && fFolder.exists())) {
+ return;
+ }
+
+ /*
+ * Transfer files from Linux Tools directory.
+ */
+ File fOldFolder = XML_DIRECTORY_LEGACY.toFile();
+ if ((fOldFolder.isDirectory() && fOldFolder.exists())) {
+ for (File fromFile : fOldFolder.listFiles()) {
+ File toFile = pathToFiles.append(fromFile.getName()).toFile();
+ if (!toFile.exists() && !fromFile.isDirectory()) {
+ try (FileInputStream fis = new FileInputStream(fromFile);
+ FileOutputStream fos = new FileOutputStream(toFile);
+ FileChannel source = fis.getChannel();
+ FileChannel destination = fos.getChannel();) {
+ destination.transferFrom(source, 0, source.size());
+ } catch (IOException e) {
+ String error = Messages.XmlUtils_ErrorCopyingFile;
+ Activator.logError(error, e);
+ }
+ }
+ }
+ }
+
+ for (File xmlFile : fFolder.listFiles()) {
+ processFile(xmlFile);
+ }
+ }
+
+ /**
+ * Notifies the main XML analysis module that the executable modules list
+ * may have changed and needs to be refreshed.
+ */
+ public static void notifyModuleChange() {
+ fModules = null;
+ TmfAnalysisManager.refreshModules();
+ }
+
+}
output.. = bin/
bin.includes = META-INF/,\
.,\
- about.html,\
- plugin.xml,\
- test_xml_files/
+ about.html
src.includes = about.html
additional.bundles = org.eclipse.jdt.annotation
jars.extra.classpath = platform:/plugin/org.eclipse.jdt.annotation
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<?eclipse version="3.4"?>
-<plugin>
- <extension
- point="org.eclipse.linuxtools.tmf.analysis.xml.core.files">
- <xmlfile
- file="test_xml_files/test_builtin.xml">
- </xmlfile>
- </extension>
-
-</plugin>
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2014 École Polytechnique de Montréal
- *
- * 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:
- * Geneviève Bastien - Initial implementation
- *******************************************************************************/
-
-package org.eclipse.tracecompass.tmf.analysis.xml.ui.tests.module;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.io.File;
-
-import org.eclipse.tracecompass.tmf.analysis.xml.core.module.XmlUtils;
-import org.eclipse.tracecompass.tmf.analysis.xml.core.tests.common.TmfXmlTestFiles;
-import org.eclipse.tracecompass.tmf.analysis.xml.ui.module.XmlAnalysisModuleSource;
-import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModuleHelper;
-import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisManager;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import com.google.common.collect.Multimap;
-
-/**
- * Test suite for the {@link XmlAnalysisModuleSource} class
- *
- * @author Geneviève Bastien
- */
-public class XmlAnalysisModuleSourceTest {
-
- private static final String SS_MODULE = "kernel.linux.sp";
- private static final String BUILTIN_MODULE = "test.builtin.sp";
-
- private static void emptyXmlFolder() {
- File fFolder = XmlUtils.getXmlFilesPath().toFile();
- if (!(fFolder.isDirectory() && fFolder.exists())) {
- return;
- }
- for (File xmlFile : fFolder.listFiles()) {
- xmlFile.delete();
- }
- XmlAnalysisModuleSource.notifyModuleChange();
- }
-
- /**
- * Empty the XML directory before the test, just in case
- */
- @Before
- public void setUp() {
- emptyXmlFolder();
- }
-
- /**
- * Empty the XML directory after the test
- */
- @After
- public void cleanUp() {
- emptyXmlFolder();
- }
-
- /**
- * Test the {@link XmlAnalysisModuleSource#getAnalysisModules()} method
- */
- @Test
- public void testPopulateModules() {
- XmlAnalysisModuleSource module = new XmlAnalysisModuleSource();
-
- Iterable<IAnalysisModuleHelper> modules = module.getAnalysisModules();
- assertFalse("Module present", findModule(modules, SS_MODULE));
-
- /* Test that the builtin module is present */
- assertTrue("builtin module present", findModule(modules, BUILTIN_MODULE));
-
- /* use the valid XML test file */
- File testXmlFile = TmfXmlTestFiles.VALID_FILE.getFile();
- if ((testXmlFile == null) || !testXmlFile.exists()) {
- fail("XML test file does not exist");
- }
-
- XmlUtils.addXmlFile(testXmlFile);
- XmlAnalysisModuleSource.notifyModuleChange();
- modules = module.getAnalysisModules();
-
- assertTrue("Modules available from source", modules.iterator().hasNext());
- assertTrue("Module present after add file", findModule(modules, SS_MODULE));
- assertTrue("Builtin module present after add file", findModule(modules, BUILTIN_MODULE));
- }
-
- private static boolean findModule(Iterable<IAnalysisModuleHelper> modules, String moduleName) {
- for (IAnalysisModuleHelper helper : modules) {
- if (moduleName.equals(helper.getId())) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Test that XML modules are available through the analysis manager
- */
- @Test
- public void testPopulateModulesWithAnalysisManager() {
-
- /*
- * Make sure module sources are initialized. When run as unit test, the
- * XML module source is sometimes missing
- */
- TmfAnalysisManager.initialize();
-
- Multimap<String, IAnalysisModuleHelper> modules = TmfAnalysisManager.getAnalysisModules();
- assertFalse(findModule(modules.values(), SS_MODULE));
- /* Test that the builtin module is present */
- assertTrue(findModule(modules.values(), BUILTIN_MODULE));
-
- /* use the valid XML test file */
- File testXmlFile = TmfXmlTestFiles.VALID_FILE.getFile();
- if ((testXmlFile == null) || !testXmlFile.exists()) {
- fail("XML test file does not exist");
- }
-
- XmlUtils.addXmlFile(testXmlFile);
- XmlAnalysisModuleSource.notifyModuleChange();
- modules = TmfAnalysisManager.getAnalysisModules();
- assertTrue(findModule(modules.values(), SS_MODULE));
- assertTrue(findModule(modules.values(), BUILTIN_MODULE));
- }
-}
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- ***************************************************************************
-* Copyright (c) 2014 École Polytechnique de Montréal
-*
-* 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:
-* Geneviève Bastien - Initial API and implementation
-*************************************************************************** -->
-<tmfxml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:noNamespaceSchemaLocation="xmldefinition.xsd">
-
- <stateProvider id="test.builtin.sp" version="1">
- <head>
- <label value="Test a builtin XML module file" />
- </head>
-
- <eventHandler eventName="test">
- <stateChange>
- <stateAttribute type="constant" value="cpu" />
- <stateValue type="eventField" value="cpu" />
- </stateChange>
- </eventHandler>
- </stateProvider>
-</tmfxml>
\ No newline at end of file
Bundle-ManifestVersion: 2
Bundle-Name: %Bundle-Name
Bundle-Vendor: %Bundle-Vendor
-Bundle-Version: 1.0.0.qualifier
+Bundle-Version: 2.0.0.qualifier
Bundle-Localization: plugin
Bundle-SymbolicName: org.eclipse.tracecompass.tmf.analysis.xml.ui;singleton:=true
Bundle-Activator: org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.Activator
<plugin>
<extension
point="org.eclipse.linuxtools.tmf.core.analysis">
- <source
- class="org.eclipse.tracecompass.tmf.analysis.xml.ui.module.XmlAnalysisModuleSource">
- </source>
<listener
class="org.eclipse.tracecompass.tmf.analysis.xml.ui.module.TmfXmlAnalysisOutputSource">
</listener>
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Shell;
+import org.eclipse.tracecompass.tmf.analysis.xml.core.module.XmlAnalysisModuleSource;
import org.eclipse.tracecompass.tmf.analysis.xml.core.module.XmlUtils;
import org.eclipse.tracecompass.tmf.analysis.xml.ui.module.Messages;
-import org.eclipse.tracecompass.tmf.analysis.xml.ui.module.XmlAnalysisModuleSource;
import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectModelElement;
import org.eclipse.tracecompass.tmf.ui.project.model.TraceUtils;
import org.eclipse.ui.IWorkbenchPage;
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2014 École Polytechnique de Montréal
- *
- * 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:
- * Geneviève Bastien - Initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.tracecompass.tmf.analysis.xml.ui.module;
-
-import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
-
-import java.io.File;
-import java.util.Collections;
-import java.util.List;
-
-import org.eclipse.core.runtime.Path;
-import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.Activator;
-import org.eclipse.tracecompass.tmf.analysis.xml.core.module.XmlUtils;
-import org.eclipse.tracecompass.tmf.analysis.xml.core.stateprovider.TmfXmlStrings;
-import org.eclipse.tracecompass.tmf.analysis.xml.core.stateprovider.XmlStateSystemModule;
-import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule;
-import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModuleHelper;
-import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisManager;
-import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisRequirement;
-import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException;
-import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType;
-import org.eclipse.tracecompass.tmf.core.project.model.TraceTypeHelper;
-import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
-import org.osgi.framework.Bundle;
-import org.w3c.dom.Element;
-
-/**
- * Analysis module helpers for modules provided by XML files
- *
- * @author Geneviève Bastien
- */
-public class TmfAnalysisModuleHelperXml implements IAnalysisModuleHelper {
-
- /**
- * The types of analysis that can be XML-defined
- */
- public enum XmlAnalysisModuleType {
- /** Analysis will be of type XmlStateSystemModule */
- STATE_SYSTEM
- }
-
- private final File fSourceFile;
- private final Element fSourceElement;
- private final XmlAnalysisModuleType fType;
-
- /**
- * Constructor
- *
- * @param xmlFile
- * The XML file containing the details of this analysis
- * @param node
- * The XML node element
- * @param type
- * The type of analysis
- */
- public TmfAnalysisModuleHelperXml(File xmlFile, Element node, XmlAnalysisModuleType type) {
- fSourceFile = xmlFile;
- fSourceElement = node;
- fType = type;
- }
-
- @Override
- public String getId() {
- /*
- * The attribute ID cannot be null because the XML has been validated
- * and it is mandatory
- */
- return checkNotNull(fSourceElement.getAttribute(TmfXmlStrings.ID));
- }
-
- @Override
- public String getName() {
- String name = null;
- /* Label may be available in XML header */
- List<Element> head = XmlUtils.getChildElements(fSourceElement, TmfXmlStrings.HEAD);
- if (head.size() == 1) {
- List<Element> labels = XmlUtils.getChildElements(head.get(0), TmfXmlStrings.LABEL);
- if (!labels.isEmpty()) {
- name = labels.get(0).getAttribute(TmfXmlStrings.VALUE);
- }
- }
-
- if (name == null) {
- name = getId();
- }
- return name;
- }
-
- @Override
- public boolean isAutomatic() {
- return false;
- }
-
- /**
- * @since 1.0
- */
- @Override
- public boolean appliesToExperiment() {
- return false;
- }
-
- @Override
- public String getHelpText() {
- return ""; //$NON-NLS-1$
- }
-
- @Override
- public String getHelpText(@NonNull ITmfTrace trace) {
- return ""; //$NON-NLS-1$
- }
-
- @Override
- public String getIcon() {
- return null;
- }
-
- @Override
- public Bundle getBundle() {
- return Activator.getDefault().getBundle();
- }
-
- @Override
- public boolean appliesToTraceType(Class<? extends ITmfTrace> traceClass) {
- /* Trace types may be available in XML header */
- List<Element> head = XmlUtils.getChildElements(fSourceElement, TmfXmlStrings.HEAD);
- if (head.size() != 1) {
- return true;
- }
- /*
- * TODO: Test with custom trace types
- */
- List<Element> elements = XmlUtils.getChildElements(head.get(0), TmfXmlStrings.TRACETYPE);
- if (elements.isEmpty()) {
- return true;
- }
-
- for (Element element : elements) {
- String traceTypeId = element.getAttribute(TmfXmlStrings.ID);
- traceTypeId = TmfTraceType.buildCompatibilityTraceTypeId(traceTypeId);
- TraceTypeHelper helper = TmfTraceType.getTraceType(traceTypeId);
- if ((helper != null) && helper.getTrace().getClass().isAssignableFrom(traceClass)) {
- return true;
- }
- }
- return false;
- }
-
- @Override
- public Iterable<Class<? extends ITmfTrace>> getValidTraceTypes() {
- return Collections.EMPTY_SET;
- }
-
- @Override
- public Iterable<TmfAnalysisRequirement> getAnalysisRequirements() {
- return Collections.EMPTY_SET;
- }
-
- @Override
- public IAnalysisModule newModule(ITmfTrace trace) throws TmfAnalysisException {
- String analysisid = getId();
- IAnalysisModule module = null;
- switch (fType) {
- case STATE_SYSTEM:
- module = new XmlStateSystemModule();
- XmlStateSystemModule ssModule = (XmlStateSystemModule) module;
- module.setId(analysisid);
- ssModule.setXmlFile(new Path(fSourceFile.getAbsolutePath()));
-
- /*
- * FIXME: There is no way to know if a module is automatic, so we
- * default to true
- */
- ssModule.setAutomatic(true);
-
- break;
- default:
- break;
-
- }
- if (module != null) {
- if (module.setTrace(trace)) {
- TmfAnalysisManager.analysisModuleCreated(module);
- } else {
- /* The analysis does not apply to the trace, dispose of the module */
- module.dispose();
- module = null;
- }
- }
-
- return module;
- }
-
-}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2014, 2015 École Polytechnique de Montréal and others
- *
- * 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:
- * Geneviève Bastien - Initial API and implementation
- * Bernd Hufmann - Ensure backwards compatibility to Linux Tools
- *******************************************************************************/
-
-package org.eclipse.tracecompass.tmf.analysis.xml.ui.module;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.net.URL;
-import java.nio.channels.FileChannel;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.eclipse.core.runtime.FileLocator;
-import org.eclipse.core.runtime.IConfigurationElement;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.ISafeRunnable;
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.core.runtime.SafeRunner;
-import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.Activator;
-import org.eclipse.tracecompass.tmf.analysis.xml.core.module.Messages;
-import org.eclipse.tracecompass.tmf.analysis.xml.core.module.XmlUtils;
-import org.eclipse.tracecompass.tmf.analysis.xml.core.stateprovider.TmfXmlStrings;
-import org.eclipse.tracecompass.tmf.analysis.xml.ui.module.TmfAnalysisModuleHelperXml.XmlAnalysisModuleType;
-import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModuleHelper;
-import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModuleSource;
-import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisManager;
-import org.osgi.framework.Bundle;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NodeList;
-import org.xml.sax.SAXException;
-
-/**
- * Analysis module source who creates helpers for the analysis modules described
- * in the imported XML files
- *
- * @author Geneviève Bastien
- */
-public class XmlAnalysisModuleSource implements IAnalysisModuleSource {
-
- /** Extension point ID */
- private static final String TMF_XML_BUILTIN_ID = "org.eclipse.linuxtools.tmf.analysis.xml.core.files"; //$NON-NLS-1$
- private static final String XML_FILE_ELEMENT = "xmlfile"; //$NON-NLS-1$
-
- private static final String XML_FILE_ATTRIB = "file"; //$NON-NLS-1$
-
- /*
- * Legacy (Linux Tools) XML directory.
- * TODO Remove once we feel the transition phase is over.
- */
- private static final IPath XML_DIRECTORY_LEGACY =
- Activator.getDefault().getStateLocation().removeLastSegments(1)
- .append("org.eclipse.linuxtools.tmf.analysis.xml.core") //$NON-NLS-1$
- .append("xml_files"); //$NON-NLS-1$
-
- private static List<@NonNull IAnalysisModuleHelper> fModules = null;
-
- /**
- * Constructor. It adds the new module listener to the analysis manager.
- */
- public XmlAnalysisModuleSource() {
-
- }
-
- @Override
- public synchronized Iterable<IAnalysisModuleHelper> getAnalysisModules() {
- List<@NonNull IAnalysisModuleHelper> modules = fModules;
- if (modules == null) {
- modules = new ArrayList<>();
- fModules = modules;
- populateBuiltinModules();
- populateAnalysisModules();
- }
- return modules;
- }
-
- private static void processFile(File xmlFile) {
- if (!XmlUtils.xmlValidate(xmlFile).isOK()) {
- return;
- }
-
- try {
- /* Load the XML File */
- DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
- DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
- Document doc = dBuilder.parse(xmlFile);
- doc.getDocumentElement().normalize();
-
- /* get State Providers modules */
- NodeList stateproviderNodes = doc.getElementsByTagName(TmfXmlStrings.STATE_PROVIDER);
- for (int i = 0; i < stateproviderNodes.getLength(); i++) {
- Element node = (Element) stateproviderNodes.item(i);
-
- IAnalysisModuleHelper helper = new TmfAnalysisModuleHelperXml(xmlFile, node, XmlAnalysisModuleType.STATE_SYSTEM);
- fModules.add(helper);
- }
- } catch (ParserConfigurationException | SAXException | IOException e) {
- Activator.logError("Error opening XML file", e); //$NON-NLS-1$
- }
- }
-
- private static void populateBuiltinModules() {
- /* Get the XML files advertised through the extension point */
- IConfigurationElement[] elements = Platform.getExtensionRegistry().getConfigurationElementsFor(TMF_XML_BUILTIN_ID);
- for (IConfigurationElement element : elements) {
- if (element.getName().equals(XML_FILE_ELEMENT)) {
- final String filename = element.getAttribute(XML_FILE_ATTRIB);
- final String name = element.getContributor().getName();
- // Run this in a safe runner in case there is an exception
- // (IOException, FileNotFoundException, NPE, etc).
- // This makes sure other extensions are not prevented from
- // working if one is faulty.
- SafeRunner.run(new ISafeRunnable() {
-
- @Override
- public void run() throws Exception {
- if (name != null) {
- Bundle bundle = Platform.getBundle(name);
- if (bundle != null) {
- URL xmlUrl = bundle.getResource(filename);
- if (xmlUrl == null) {
- throw new FileNotFoundException(filename);
- }
- URL locatedURL = FileLocator.toFileURL(xmlUrl);
- processFile(new File(locatedURL.getFile()));
- }
- }
- }
-
- @Override
- public void handleException(Throwable exception) {
- // Handled sufficiently in SafeRunner
- }
- });
- }
- }
- }
-
- private static void populateAnalysisModules() {
- IPath pathToFiles = XmlUtils.getXmlFilesPath();
- File fFolder = pathToFiles.toFile();
- if (!(fFolder.isDirectory() && fFolder.exists())) {
- return;
- }
-
- /*
- * Transfer files from Linux Tools directory.
- */
- File fOldFolder = XML_DIRECTORY_LEGACY.toFile();
- if ((fOldFolder.isDirectory() && fOldFolder.exists())) {
- for (File fromFile : fOldFolder.listFiles()) {
- File toFile = pathToFiles.append(fromFile.getName()).toFile();
- if (!toFile.exists() && !fromFile.isDirectory()) {
- try (FileInputStream fis = new FileInputStream(fromFile);
- FileOutputStream fos = new FileOutputStream(toFile);
- FileChannel source = fis.getChannel();
- FileChannel destination = fos.getChannel();) {
- destination.transferFrom(source, 0, source.size());
- } catch (IOException e) {
- String error = Messages.XmlUtils_ErrorCopyingFile;
- Activator.logError(error, e);
- }
- }
- }
- }
-
- for (File xmlFile : fFolder.listFiles()) {
- processFile(xmlFile);
- }
- }
-
- /**
- * Notifies the main XML analysis module that the executable modules list
- * may have changed and needs to be refreshed.
- */
- public static void notifyModuleChange() {
- fModules = null;
- TmfAnalysisManager.refreshModules();
- }
-
-}