1 /*******************************************************************************
2 * Copyright (c) 2010, 2016 Ericsson
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
10 * Patrick Tasse - Initial API and implementation
11 *******************************************************************************/
13 package org
.eclipse
.tracecompass
.tmf
.core
.parsers
.custom
;
15 import static org
.eclipse
.tracecompass
.common
.core
.NonNullUtils
.checkNotNull
;
17 import java
.io
.ByteArrayInputStream
;
18 import java
.io
.IOException
;
20 import java
.text
.SimpleDateFormat
;
21 import java
.util
.AbstractMap
.SimpleEntry
;
22 import java
.util
.ArrayList
;
23 import java
.util
.Collection
;
24 import java
.util
.List
;
25 import java
.util
.Map
.Entry
;
27 import org
.eclipse
.core
.runtime
.FileLocator
;
28 import org
.eclipse
.core
.runtime
.IConfigurationElement
;
29 import org
.eclipse
.core
.runtime
.ISafeRunnable
;
30 import org
.eclipse
.core
.runtime
.Platform
;
31 import org
.eclipse
.core
.runtime
.SafeRunner
;
32 import org
.eclipse
.jdt
.annotation
.NonNull
;
33 import org
.eclipse
.tracecompass
.tmf
.core
.event
.aspect
.TmfBaseAspects
;
34 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.TmfTimestamp
;
35 import org
.osgi
.framework
.Bundle
;
36 import org
.w3c
.dom
.Element
;
37 import org
.xml
.sax
.EntityResolver
;
38 import org
.xml
.sax
.ErrorHandler
;
39 import org
.xml
.sax
.InputSource
;
40 import org
.xml
.sax
.SAXException
;
41 import org
.xml
.sax
.SAXParseException
;
44 * Base class for custom trace definitions.
46 * @author Patrick Tassé
48 public abstract class CustomTraceDefinition
{
51 public static final int ACTION_SET
= 0;
53 /** "append" action */
54 public static final int ACTION_APPEND
= 1;
56 /** "append with separator" action */
57 public static final int ACTION_APPEND_WITH_SEPARATOR
= 2;
66 IGNORE(Messages
.CustomXmlTraceDefinition_ignoreTag
),
68 TIMESTAMP(TmfBaseAspects
.getTimestampAspect().getName()),
70 EVENT_TYPE(TmfBaseAspects
.getEventTypeAspect().getName()),
72 MESSAGE(Messages
.CustomTraceDefinition_messageTag
),
75 EXTRA_FIELD_NAME(Messages
.CustomTraceDefinition_extraFieldNameTag
),
78 EXTRA_FIELD_VALUE(Messages
.CustomTraceDefinition_extraFieldValueTag
),
82 * Used as output tag corresponding to the {@link #EXTRA_FIELD_NAME} and
83 * {@link #EXTRA_FIELD_VALUE} input tags.
86 EXTRA_FIELDS(Messages
.CustomExtraFieldsAspect_extraFieldsAspectName
),
88 OTHER(Messages
.CustomTraceDefinition_otherTag
);
90 private final String fLabel
;
92 private Tag(String label
) {
97 public String
toString() {
102 * Get a tag from its label (toString).
106 * @return the corresponding tag, or null
108 public static Tag
fromLabel(String label
) {
109 for (Tag tag
: Tag
.values()) {
110 if (tag
.toString().equals(label
)) {
118 * Get a tag from its name (identifier).
122 * @return the corresponding tag, or null
124 public static Tag
fromName(String name
) {
125 for (Tag tag
: Tag
.values()) {
126 if (tag
.name().equals(name
)) {
135 * Separator to use with the
136 * {@link CustomTraceDefinition#ACTION_APPEND_WITH_SEPARATOR}
140 public static final @NonNull String SEPARATOR
= " | "; //$NON-NLS-1$
142 private static final String TMF_CUSTOM_TRACE_BUILTIN_EXTENSION_ID
= "org.eclipse.tracecompass.tmf.core.custom.trace"; //$NON-NLS-1$
143 private static final String ATTRIBUTE_NAME_FILE
= "file"; //$NON-NLS-1$
144 private static final String ATTRIBUTE_NAME_TRACE_CONTENT_TYPE
= "traceContentType"; //$NON-NLS-1$
145 private static final String ELEMENT_NAME_CUSTOM_TRACE
= "customTrace"; //$NON-NLS-1$
147 /** Category of this trace definition */
148 public String categoryName
;
150 /** Name of this trace definition */
151 public String definitionName
;
153 /** List of output columns */
154 public List
<OutputColumn
> outputs
;
156 /** Timestamp format */
157 public String timeStampOutputFormat
;
160 * Definition of an output column
162 public static class OutputColumn
{
164 /** Tag of this input
166 public @NonNull Tag tag
;
168 /** Name of this column */
169 public @NonNull String name
;
175 * Tag of this output column
177 * Name of this output column
180 public OutputColumn(@NonNull Tag tag
, @NonNull String name
) {
186 public String
toString() {
192 * Format a timestamp in this trace's current time stamp format.
195 * The timestamp to format
196 * @return The same timestamp as a formatted string
198 public String
formatTimeStamp(TmfTimestamp timestamp
) {
199 SimpleDateFormat simpleDateFormat
= new SimpleDateFormat(timeStampOutputFormat
);
200 return simpleDateFormat
.format(timestamp
.getValue());
204 * Save this custom trace in the default path.
206 public abstract void save();
209 * Save this custom trace in the supplied path.
212 * The path to save to
214 public abstract void save(String path
);
217 * Creates a new empty entity resolver
219 * @return a new entity resolver
221 protected static EntityResolver
createEmptyEntityResolver() {
222 return new EntityResolver() {
224 public InputSource
resolveEntity(String publicId
, String systemId
) {
225 String empty
= ""; //$NON-NLS-1$
226 ByteArrayInputStream bais
= new ByteArrayInputStream(empty
.getBytes());
227 return new InputSource(bais
);
233 * Creates an error handler for parse exceptions
235 * @return a new error handler
237 protected static ErrorHandler
createErrorHandler() {
238 return new ErrorHandler() {
240 public void error(SAXParseException saxparseexception
) throws SAXException
{
244 public void warning(SAXParseException saxparseexception
) throws SAXException
{
248 public void fatalError(SAXParseException saxparseexception
) throws SAXException
{
249 throw saxparseexception
;
255 * Extract the tag and name from an XML element
259 * @param tagAttribute
261 * @param nameAttribute
263 * @return an entry where the key is the tag and the value is the name
266 protected static Entry
<@NonNull Tag
, @NonNull String
> extractTagAndName(Element element
, String tagAttribute
, String nameAttribute
) {
267 Tag tag
= Tag
.fromName(element
.getAttribute(tagAttribute
));
268 String name
= element
.getAttribute(nameAttribute
);
270 // Backward compatibility
271 if (name
.equals(Messages
.CustomTraceDefinition_timestampTag
)) {
273 name
= checkNotNull(Tag
.TIMESTAMP
.toString());
274 } else if (name
.equals(Messages
.CustomTraceDefinition_messageTag
)) {
276 name
= checkNotNull(Tag
.MESSAGE
.toString());
277 } else if (name
.equals(Messages
.CustomXmlTraceDefinition_ignoreTag
)) {
279 name
= checkNotNull(Tag
.IGNORE
.toString());
283 } else if (name
.isEmpty()) {
284 name
= checkNotNull(tag
.toString());
286 return new SimpleEntry
<>(tag
, name
);
290 * Get all the custom trace definition paths contributed by extensions, for
291 * a given content type (XML or Text).
293 * @param traceContentTypeToLoad
294 * XML or Text (extension attribute value)
297 * Note: This method is package-visible by design.
299 static final Collection
<String
> getExtensionDefinitionsPaths(String traceContentTypeToLoad
) {
300 List
<String
> extensionDefinitionsPaths
= new ArrayList
<>();
301 IConfigurationElement
[] elements
= Platform
.getExtensionRegistry().getConfigurationElementsFor(TMF_CUSTOM_TRACE_BUILTIN_EXTENSION_ID
);
302 for (IConfigurationElement element
: elements
) {
303 if (!element
.getName().equals(ELEMENT_NAME_CUSTOM_TRACE
)) {
307 final String traceContentType
= element
.getAttribute(ATTRIBUTE_NAME_TRACE_CONTENT_TYPE
);
308 if (!traceContentType
.equals(traceContentTypeToLoad
)) {
312 final String filename
= element
.getAttribute(ATTRIBUTE_NAME_FILE
);
313 final String name
= element
.getContributor().getName();
314 SafeRunner
.run(new ISafeRunnable() {
316 public void run() throws IOException
{
318 Bundle bundle
= Platform
.getBundle(name
);
319 if (bundle
!= null) {
320 URL xmlUrl
= bundle
.getResource(filename
);
321 URL locatedURL
= FileLocator
.toFileURL(xmlUrl
);
322 extensionDefinitionsPaths
.add(locatedURL
.getPath());
328 public void handleException(Throwable exception
) {
329 // Handled sufficiently in SafeRunner
334 return extensionDefinitionsPaths
;