tmf: bug 494698 Add per-event fields to custom parsers
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.core / src / org / eclipse / tracecompass / tmf / core / parsers / custom / CustomEvent.java
index 6d55a9664a6d1865980cd29f609a6d8d2441a97f..4eba7d848bcaa377d98eea3d3a6156d8a925ec8a 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2010, 2014 Ericsson
+ * Copyright (c) 2010, 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
 
 package org.eclipse.tracecompass.tmf.core.parsers.custom;
 
-import static org.eclipse.tracecompass.common.core.NonNullUtils.equalsNullable;
+import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
+import static org.eclipse.tracecompass.common.core.NonNullUtils.nullToEmptyString;
 
 import java.text.ParseException;
-import java.util.HashMap;
+import java.util.Collection;
+import java.util.LinkedHashMap;
 import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Objects;
 
 import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.tracecompass.internal.tmf.core.parsers.custom.CustomExtraField;
 import org.eclipse.tracecompass.tmf.core.event.ITmfEventField;
 import org.eclipse.tracecompass.tmf.core.event.ITmfEventType;
 import org.eclipse.tracecompass.tmf.core.event.TmfEvent;
 import org.eclipse.tracecompass.tmf.core.event.TmfEventField;
 import org.eclipse.tracecompass.tmf.core.event.TmfEventType;
 import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTraceDefinition.OutputColumn;
+import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTraceDefinition.Tag;
 import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp;
-import org.eclipse.tracecompass.tmf.core.timestamp.TmfNanoTimestamp;
 import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
 import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestampFormat;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfContext;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
 
+import com.google.common.collect.Iterables;
+
 /**
  * Base event for custom text parsers.
  *
@@ -39,7 +46,16 @@ import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
  */
 public class CustomEvent extends TmfEvent {
 
-    /** Input format key */
+    /** Payload data map key
+     * @since 2.1*/
+    protected enum Key {
+        /** Timestamp input format */
+        TIMESTAMP_INPUT_FORMAT
+    }
+
+    /** Input format key
+     * @deprecated Use {@link Key#TIMESTAMP_INPUT_FORMAT} instead. */
+    @Deprecated
     protected static final String TIMESTAMP_INPUT_FORMAT_KEY = "CE_TS_I_F"; //$NON-NLS-1$
 
     /** Empty message */
@@ -57,10 +73,12 @@ public class CustomEvent extends TmfEvent {
     /** The trace to which this event belongs */
     protected CustomTraceDefinition fDefinition;
 
-    /** The payload data of this event, <field name, value> */
-    protected Map<String, String> fData;
-
-    private TmfEventField[] fColumnData;
+    /**
+     * The payload data of this event, where the key is one of: the {@link Tag},
+     * the field name string if the tag is {@link Tag#OTHER}, or
+     * {@link Key#TIMESTAMP_INPUT_FORMAT}.
+     */
+    protected Map<Object, String> fData;
 
     /**
      * Basic constructor.
@@ -71,7 +89,7 @@ public class CustomEvent extends TmfEvent {
     public CustomEvent(CustomTraceDefinition definition) {
         super(null, ITmfContext.UNKNOWN_RANK, null, null, null);
         fDefinition = definition;
-        fData = new HashMap<>();
+        fData = new LinkedHashMap<>();
         customEventTimestamp = TmfTimestamp.ZERO;
     }
 
@@ -86,7 +104,7 @@ public class CustomEvent extends TmfEvent {
     public CustomEvent(CustomTraceDefinition definition, @NonNull TmfEvent other) {
         super(other);
         fDefinition = definition;
-        fData = new HashMap<>();
+        fData = new LinkedHashMap<>();
 
         /* Set our overridden fields */
         customEventTimestamp = other.getTimestamp();
@@ -111,7 +129,7 @@ public class CustomEvent extends TmfEvent {
         /* Do not use upstream's fields for stuff we override */
         super(parentTrace, ITmfContext.UNKNOWN_RANK, null, null, null);
         fDefinition = definition;
-        fData = new HashMap<>();
+        fData = new LinkedHashMap<>();
 
         /* Set our overridden fields */
         if (timestamp == null) {
@@ -148,6 +166,14 @@ public class CustomEvent extends TmfEvent {
         return customEventType;
     }
 
+    @Override
+    public String getName() {
+        if (fData != null) {
+            processData();
+        }
+        return super.getName();
+    }
+
     // ------------------------------------------------------------------------
     // Setters
     // ------------------------------------------------------------------------
@@ -205,27 +231,28 @@ public class CustomEvent extends TmfEvent {
      *            The ID/index of the field to display. This corresponds to the
      *            index in the event content.
      * @return The String to display in the cell
+     * @deprecated Use {@link ITmfEventField#getField(String...)} instead.
      */
+    @Deprecated
     public String getEventString(int index) {
-        if (fData != null) {
-            processData();
-        }
-        if (index < 0 || index >= fColumnData.length) {
+        Collection<? extends ITmfEventField> fields = getContent().getFields();
+        if (index < 0 || index >= fields.size()) {
             return ""; //$NON-NLS-1$
         }
 
-        return fColumnData[index].getValue().toString();
+        return nullToEmptyString(checkNotNull(Iterables.get(fields, index)).getValue());
     }
 
     private void processData() {
-        String timestampString = fData.get(CustomTraceDefinition.TAG_TIMESTAMP);
-        String timestampInputFormat = fData.get(TIMESTAMP_INPUT_FORMAT_KEY);
-        TmfTimestamp timestamp = null;
+        // Remove the values as they are processed, so we can process the extra values at the end
+        String timestampString = fData.remove(Tag.TIMESTAMP);
+        String timestampInputFormat = fData.remove(Key.TIMESTAMP_INPUT_FORMAT);
+        ITmfTimestamp timestamp = null;
         if (timestampInputFormat != null && timestampString != null) {
             TmfTimestampFormat timestampFormat = new TmfTimestampFormat(timestampInputFormat);
             try {
                 long time = timestampFormat.parseValue(timestampString);
-                timestamp = new TmfNanoTimestamp(getTrace().getTimestampTransform().transform(time));
+                timestamp = TmfTimestamp.fromNanos(getTrace().getTimestampTransform().transform(time));
                 setTimestamp(timestamp);
             } catch (ParseException e) {
                 setTimestamp(TmfTimestamp.ZERO);
@@ -234,18 +261,34 @@ public class CustomEvent extends TmfEvent {
             setTimestamp(TmfTimestamp.ZERO);
         }
 
-        int i = 0;
-        fColumnData = new TmfEventField[fDefinition.outputs.size()];
+        // Update the custom event type of this event if set
+        String eventName = fData.remove(Tag.EVENT_TYPE);
+        ITmfEventType type = getType();
+        if (eventName != null && type instanceof CustomEventType) {
+            ((CustomEventType) type).setName(eventName);
+        }
+
+        Map<String, TmfEventField> fieldMap = new LinkedHashMap<>();
         for (OutputColumn outputColumn : fDefinition.outputs) {
-            String value = fData.get(outputColumn.name);
-            if (outputColumn.name.equals(CustomTraceDefinition.TAG_TIMESTAMP) && timestamp != null) {
-                TmfTimestampFormat timestampFormat = new TmfTimestampFormat(fDefinition.timeStampOutputFormat);
-                fColumnData[i++] = new TmfEventField(outputColumn.name, timestampFormat.format(timestamp.getValue()), null);
-            } else {
-                fColumnData[i++] = new TmfEventField(outputColumn.name, (value != null ? value : ""), null); //$NON-NLS-1$
+            if (outputColumn.tag.equals(Tag.TIMESTAMP)) {
+                if (timestamp != null && fDefinition.timeStampOutputFormat != null && !fDefinition.timeStampOutputFormat.isEmpty()) {
+                    TmfTimestampFormat timestampFormat = new TmfTimestampFormat(fDefinition.timeStampOutputFormat);
+                    fieldMap.put(outputColumn.name, new TmfEventField(outputColumn.name, timestampFormat.format(timestamp.getValue()), null));
+                }
+            } else if (outputColumn.tag.equals(Tag.OTHER) || outputColumn.tag.equals(Tag.MESSAGE)) {
+                Object key = (outputColumn.tag.equals(Tag.OTHER) ? outputColumn.name : outputColumn.tag);
+                fieldMap.put(outputColumn.name, new TmfEventField(outputColumn.name, nullToEmptyString(fData.remove(key)), null));
+            }
+        }
+        // This event contains extra values, we process them now
+        for (Entry<Object, String> entry : fData.entrySet()) {
+            String fieldName = nullToEmptyString(entry.getKey().toString());
+            // Ignore extra fields if a field of same name is already set
+            if (!fieldMap.containsKey(fieldName)) {
+                fieldMap.put(fieldName, new CustomExtraField(fieldName, nullToEmptyString(entry.getValue()), null));
             }
         }
-        setContent(new CustomEventContent(customEventContent.getName(), customEventContent.getValue(), fColumnData));
+        setContent(new CustomEventContent(customEventContent.getName(), customEventContent.getValue(), fieldMap.values().toArray(new ITmfEventField[fieldMap.size()])));
         fData = null;
     }
 
@@ -272,7 +315,7 @@ public class CustomEvent extends TmfEvent {
             return false;
         }
         CustomEvent other = (CustomEvent) obj;
-        if (!equalsNullable(fDefinition, other.fDefinition)) {
+        if (!Objects.equals(fDefinition, other.fDefinition)) {
             return false;
         }
 
@@ -280,11 +323,11 @@ public class CustomEvent extends TmfEvent {
             return false;
         }
 
-        if (!equalsNullable(customEventContent, other.customEventContent)) {
+        if (!Objects.equals(customEventContent, other.customEventContent)) {
             return false;
         }
 
-        if (!equalsNullable(customEventType, other.customEventType)) {
+        if (!Objects.equals(customEventType, other.customEventType)) {
             return false;
         }
         return true;
This page took 0.031689 seconds and 5 git commands to generate.