id="org.eclipse.tracecompass.tmf.core.tests.analysis1">
</analysis>
</extension>
+ <extension
+ point="org.eclipse.tracecompass.tmf.core.custom.trace">
+ <customTrace
+ file="testfiles/txt/testTxtExtensionDefinition.xml"
+ traceContentType="text">
+ </customTrace>
+ </extension>
+ <extension
+ point="org.eclipse.tracecompass.tmf.core.custom.trace">
+ <customTrace
+ file="testfiles/xml/testXmlExtensionDefinition.xml"
+ traceContentType="xml">
+ </customTrace>
+ </extension>
</plugin>
--- /dev/null
+/******************************************************************************
+ * Copyright (c) 2016 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
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.tmf.core.tests.parsers.custom;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+import java.util.function.Predicate;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceImportException;
+import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType;
+import org.eclipse.tracecompass.tmf.core.project.model.TraceTypeHelper;
+import org.junit.Test;
+
+/**
+ * Common code for custom trace type extension points tests.
+ */
+public abstract class AbstractCustomTraceExtensionTest {
+
+ /**
+ * @return Get the extension Id that will provide the trace type to test.
+ */
+ protected abstract String getExtensionId();
+
+ /**
+ * @return Get the path of the trace to test with the trace type provided by
+ * an extension.
+ */
+ protected abstract String getTestTracePath();
+
+ /**
+ * Verifies that a trace type provided by an extension is present.
+ */
+ @Test
+ public void testTraceTypePresence() {
+ assertNotNull(TmfTraceType.getTraceType(getExtensionId()));
+ }
+
+ /**
+ * Verifies that a trace type contributed by an extension can validate a valid trace.
+ *
+ * @throws TmfTraceImportException
+ * on error
+ */
+ @Test
+ public void testValidate() throws TmfTraceImportException {
+ final Predicate<TraceTypeHelper> predicateTracetypeIdEquals = (t) -> t.getTraceTypeId().equals(getExtensionId());
+ @NonNull List<TraceTypeHelper> traceTypes = TmfTraceType.selectTraceType(getTestTracePath(), getExtensionId());
+ String failureMessage = String.format("Could not find expected custom trace type %s in extensions", getExtensionId());
+ assertTrue(failureMessage, traceTypes.stream().anyMatch(predicateTracetypeIdEquals));
+ }
+}
--- /dev/null
+/******************************************************************************
+ * Copyright (c) 2016 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
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.tmf.core.tests.parsers.custom;
+
+/**
+ * Tests for Custom Text trace extension point.
+ */
+public class CustomTxtExtensionTest extends AbstractCustomTraceExtensionTest {
+ private static final String TEXT_TRACE_TYPE_EXTENSION_ID = "custom.txt.trace:Custom Text:testtxtextension";
+ private static final String TRACE_PATH_NAME = "testfiles/txt/valid/001.txt";
+
+ @Override
+ protected String getExtensionId() {
+ return TEXT_TRACE_TYPE_EXTENSION_ID;
+ }
+
+ @Override
+ protected String getTestTracePath() {
+ return TRACE_PATH_NAME;
+ }
+}
--- /dev/null
+/******************************************************************************
+ * Copyright (c) 2016 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
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.tmf.core.tests.parsers.custom;
+
+/**
+ * Tests for Custom Text trace extension point.
+ */
+public class CustomXmlExtensionTest extends AbstractCustomTraceExtensionTest {
+ private static final String XML_TRACE_TYPE_EXTENSION_ID = "custom.xml.trace:Custom XML:testxmlextension";
+ private static final String TRACE_PATH_NAME = "testfiles/xml/valid/001.xml";
+
+ @Override
+ protected String getExtensionId() {
+ return XML_TRACE_TYPE_EXTENSION_ID;
+ }
+
+ @Override
+ protected String getTestTracePath() {
+ return TRACE_PATH_NAME;
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<CustomTxtTraceDefinitionList>
+<Definition name="testtxtextension">
+<TimeStampOutputFormat>Tn</TimeStampOutputFormat>
+<InputLine>
+<Cardinality max="2147483647" min="0"/>
+<RegEx>(\S+) (foo-event)</RegEx>
+<InputData action="0" format="dd/MM/yyyy HH:mm:ss:SSS" name="Timestamp" tag="TIMESTAMP"/>
+<InputData action="0" format="" name="Message" tag="MESSAGE"/>
+<InputLine>
+<Cardinality max="2147483647" min="0"/>
+<RegEx>(.*\S)</RegEx>
+<InputData action="2" tag="MESSAGE"/>
+</InputLine>
+</InputLine>
+<OutputColumn name="Timestamp" tag="TIMESTAMP"/>
+<OutputColumn name="Message" tag="MESSAGE"/>
+</Definition>
+</CustomTxtTraceDefinitionList>
--- /dev/null
+1 foo-event
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<CustomXMLTraceDefinitionList>
+<Definition name="testxmlextension">
+<TimeStampOutputFormat>Tn</TimeStampOutputFormat>
+<InputElement name="trace">
+<InputElement logentry="true" name="element">
+<InputData action="0" name="Message" tag="MESSAGE"/>
+<Attribute name="time">
+<InputData action="0" format="dd/MM/yyyy HH:mm:ss:SSS" name="Timestamp" tag="TIMESTAMP"/>
+</Attribute>
+</InputElement>
+</InputElement>
+<OutputColumn name="Timestamp" tag="TIMESTAMP"/>
+<OutputColumn name="Message" tag="MESSAGE"/>
+</Definition>
+</CustomXMLTraceDefinitionList>
###############################################################################
-# Copyright (c) 2013, 2014 Ericsson
+# Copyright (c) 2013, 2016 Ericsson
#
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0
extensionpoint.trace_type.name = Tmf Trace Type
extensionpoint.analysis_module.name = Trace Analysis Module
extensionpoint.ondemand_analysis.name = On-demand Analysis
+extensionpoint.custom_trace.name = Custom Trace
# Experiment type
experimenttype.type.generic = Generic Experiment
<extension-point id="org.eclipse.linuxtools.tmf.core.tracetype" name="%extensionpoint.trace_type.name" schema="schema/org.eclipse.linuxtools.tmf.core.tracetype.exsd"/>
<extension-point id="org.eclipse.linuxtools.tmf.core.analysis" name="%extensionpoint.analysis_module.name" schema="schema/org.eclipse.linuxtools.tmf.core.analysis.exsd"/>
<extension-point id="org.eclipse.tracecompass.tmf.core.analysis.ondemand" name="%extensionpoint.ondemand_analysis.name" schema="schema/org.eclipse.tracecompass.tmf.core.analysis.ondemand.exsd"/>
+ <extension-point id="org.eclipse.tracecompass.tmf.core.custom.trace" name="%extensionpoint.custom_trace.name" schema="schema/org.eclipse.tracecompass.tmf.core.custom.trace.exsd"/>
<extension
point="org.eclipse.core.runtime.preferences">
--- /dev/null
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.tracecompass.tmf.core" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appinfo>
+ <meta.schema plugin="org.eclipse.tracecompass.tmf.core" id="org.eclipse.tracecompass.tmf.core.custom.trace" name="Custom Trace"/>
+ </appinfo>
+ <documentation>
+ This extension point is used to contribute custom trace types so that they are available automatically without the need to be imported by the user.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appinfo>
+ <meta.element />
+ </appinfo>
+ </annotation>
+ <complexType>
+ <sequence minOccurs="1" maxOccurs="unbounded">
+ <element ref="customTrace"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+ </documentation>
+ <appinfo>
+ <meta.attribute translatable="true"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="customTrace">
+ <annotation>
+ <appInfo>
+ <meta.element labelAttribute="file"/>
+ </appInfo>
+ </annotation>
+ <complexType>
+ <attribute name="file" type="string" use="required">
+ <annotation>
+ <documentation>
+ The path to the XML file describing the text trace.
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="resource"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="traceContentType" use="required">
+ <annotation>
+ <documentation>
+ The type of content that the trace will have (XML or Text)
+ </documentation>
+ </annotation>
+ <simpleType>
+ <restriction base="string">
+ <enumeration value="xml">
+ </enumeration>
+ <enumeration value="text">
+ </enumeration>
+ </restriction>
+ </simpleType>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="since"/>
+ </appinfo>
+ <documentation>
+ Trace Compass 2.2
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="examples"/>
+ </appinfo>
+ <documentation>
+ <p>For example, a custom text parser can be exported using the "Manage Custom Parser" dialog, then included in a plug-in so that it is automatically loaded without the user having to import it manually. The path to XML file describing the parser is specified in the extension point.
+</p>
+<pre>
+ <extension
+ point="org.eclipse.tracecompass.tmf.core.custom.trace">
+ <customtrace
+ file="parsers/customTextDefinition.xml">
+ </customtrace>
+ </extension>
+</pre>
+ </documentation>
+ </annotation>
+
+
+
+ <annotation>
+ <appinfo>
+ <meta.section type="copyright"/>
+ </appinfo>
+ <documentation>
+ Copyright (c) 2016 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 <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>
+ </documentation>
+ </annotation>
+
+</schema>
import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.AbstractMap.SimpleEntry;
+import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
import java.util.Map.Entry;
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IConfigurationElement;
+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.tmf.core.event.aspect.TmfBaseAspects;
import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
+import org.osgi.framework.Bundle;
import org.w3c.dom.Element;
import org.xml.sax.EntityResolver;
import org.xml.sax.ErrorHandler;
@Deprecated
public static final String TAG_OTHER = Messages.CustomTraceDefinition_otherTag;
+ private static final String TMF_CUSTOM_TRACE_BUILTIN_EXTENSION_ID = "org.eclipse.tracecompass.tmf.core.custom.trace"; //$NON-NLS-1$
+ private static final String ATTRIBUTE_NAME_FILE = "file"; //$NON-NLS-1$
+ private static final String ATTRIBUTE_NAME_TRACE_CONTENT_TYPE = "traceContentType"; //$NON-NLS-1$
+ private static final String ELEMENT_NAME_CUSTOM_TRACE = "customTrace"; //$NON-NLS-1$
+
/** Category of this trace definition */
public String categoryName;
}
return new SimpleEntry<>(tag, name);
}
+
+ /**
+ * Get all the custom trace definition paths contributed by extensions, for
+ * a given content type (XML or Text).
+ *
+ * @param traceContentTypeToLoad
+ * XML or Text (extension attribute value)
+ * @return the paths
+ *
+ * Note: This method is package-visible by design.
+ */
+ static final Collection<String> getExtensionDefinitionsPaths(String traceContentTypeToLoad) {
+ List<String> extensionDefinitionsPaths = new ArrayList<>();
+ IConfigurationElement[] elements = Platform.getExtensionRegistry().getConfigurationElementsFor(TMF_CUSTOM_TRACE_BUILTIN_EXTENSION_ID);
+ for (IConfigurationElement element : elements) {
+ if (!element.getName().equals(ELEMENT_NAME_CUSTOM_TRACE)) {
+ continue;
+ }
+
+ final String traceContentType = element.getAttribute(ATTRIBUTE_NAME_TRACE_CONTENT_TYPE);
+ if (!traceContentType.equals(traceContentTypeToLoad)) {
+ continue;
+ }
+
+ final String filename = element.getAttribute(ATTRIBUTE_NAME_FILE);
+ final String name = element.getContributor().getName();
+ SafeRunner.run(new ISafeRunnable() {
+ @Override
+ public void run() throws IOException {
+ if (name != null) {
+ Bundle bundle = Platform.getBundle(name);
+ if (bundle != null) {
+ URL xmlUrl = bundle.getResource(filename);
+ URL locatedURL = FileLocator.toFileURL(xmlUrl);
+ extensionDefinitionsPaths.add(locatedURL.getPath());
+ }
+ }
+ }
+
+ @Override
+ public void handleException(Throwable exception) {
+ // Handled sufficiently in SafeRunner
+ }
+ });
+
+ }
+ return extensionDefinitionsPaths;
+ }
}
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
private static final String FORMAT_ATTRIBUTE = Messages.CustomTxtTraceDefinition_format;
private static final String OUTPUT_COLUMN_ELEMENT = Messages.CustomTxtTraceDefinition_outputColumn;
+ /**
+ * This is the value that the extension sets for traceContentType to be able
+ * to load an XML parser
+ **/
+ private static final String TRACE_CONTENT_TYPE_ATTRIBUTE_VALUE = "text"; //$NON-NLS-1$
+
/**
* Default constructor.
*/
defs.addAll(Arrays.asList(loadAll(CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME)));
if (includeDefaults) {
defs.addAll(Arrays.asList(loadAll(CUSTOM_TXT_TRACE_DEFINITIONS_DEFAULT_PATH_NAME)));
+
+ // Also load definitions contributed by extensions
+ Collection<String> paths = getExtensionDefinitionsPaths(TRACE_CONTENT_TYPE_ATTRIBUTE_VALUE);
+ for (String customTraceDefinitionPath : paths) {
+ defs.addAll(Arrays.asList(loadAll(customTraceDefinitionPath)));
+ }
}
return defs.toArray(new CustomTxtTraceDefinition[0]);
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Map.Entry;
private static final String FORMAT_ATTRIBUTE = Messages.CustomXmlTraceDefinition_format;
private static final String OUTPUT_COLUMN_ELEMENT = Messages.CustomXmlTraceDefinition_outputColumn;
+ /**
+ * This is the value that the extension sets for traceContentType to be able
+ * to load an XML parser
+ **/
+ private static final String TRACE_CONTENT_TYPE_ATTRIBUTE_VALUE = "xml"; //$NON-NLS-1$
+
/** Top-level input element */
public CustomXmlInputElement rootInputElement;
defs.addAll(Arrays.asList(loadAll(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME)));
if (includeDefaults) {
defs.addAll(Arrays.asList(loadAll(CUSTOM_XML_TRACE_DEFINITIONS_DEFAULT_PATH_NAME)));
+
+ // Also load definitions contributed by extensions
+ Collection<String> paths = getExtensionDefinitionsPaths(TRACE_CONTENT_TYPE_ATTRIBUTE_VALUE);
+ for (String customTraceDefinitionPath : paths) {
+ defs.addAll(Arrays.asList(loadAll(customTraceDefinitionPath)));
+ }
}
return defs.toArray(new CustomXmlTraceDefinition[0]);
}