/*******************************************************************************
- * 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.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.
*
*/
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 */
/** 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.
public CustomEvent(CustomTraceDefinition definition) {
super(null, ITmfContext.UNKNOWN_RANK, null, null, null);
fDefinition = definition;
- fData = new HashMap<>();
+ fData = new LinkedHashMap<>();
customEventTimestamp = TmfTimestamp.ZERO;
}
public CustomEvent(CustomTraceDefinition definition, @NonNull TmfEvent other) {
super(other);
fDefinition = definition;
- fData = new HashMap<>();
+ fData = new LinkedHashMap<>();
/* Set our overridden fields */
customEventTimestamp = other.getTimestamp();
/* 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) {
return customEventType;
}
+ @Override
+ public String getName() {
+ if (fData != null) {
+ processData();
+ }
+ return super.getName();
+ }
+
// ------------------------------------------------------------------------
// Setters
// ------------------------------------------------------------------------
* 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);
+ // 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);
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;
}
return false;
}
CustomEvent other = (CustomEvent) obj;
- if (!equalsNullable(fDefinition, other.fDefinition)) {
+ if (!Objects.equals(fDefinition, other.fDefinition)) {
return false;
}
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;