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
CommitLineData
6151d86c 1/*******************************************************************************
53f17e49 2 * Copyright (c) 2010, 2016 Ericsson
6151d86c
PT
3 *
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
8 *
9 * Contributors:
10 * Patrick Tasse - Initial API and implementation
11 *******************************************************************************/
12
2bdf0193 13package org.eclipse.tracecompass.tmf.core.parsers.custom;
6151d86c 14
0fa1aec2
PT
15import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
16import static org.eclipse.tracecompass.common.core.NonNullUtils.nullToEmptyString;
17
6151d86c 18import java.text.ParseException;
0fa1aec2 19import java.util.Collection;
efeeb733 20import java.util.LinkedHashMap;
6151d86c 21import java.util.Map;
efeeb733 22import java.util.Map.Entry;
7a0ebe01 23import java.util.Objects;
6151d86c 24
ca5b04ad 25import org.eclipse.jdt.annotation.NonNull;
efeeb733 26import org.eclipse.tracecompass.internal.tmf.core.parsers.custom.CustomExtraField;
2bdf0193
AM
27import org.eclipse.tracecompass.tmf.core.event.ITmfEventField;
28import org.eclipse.tracecompass.tmf.core.event.ITmfEventType;
29import org.eclipse.tracecompass.tmf.core.event.TmfEvent;
30import org.eclipse.tracecompass.tmf.core.event.TmfEventField;
31import org.eclipse.tracecompass.tmf.core.event.TmfEventType;
32import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTraceDefinition.OutputColumn;
f5cc6ed1 33import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTraceDefinition.Tag;
2bdf0193 34import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp;
2bdf0193
AM
35import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
36import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestampFormat;
0c7471fb 37import org.eclipse.tracecompass.tmf.core.trace.ITmfContext;
2bdf0193 38import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
6151d86c 39
0fa1aec2
PT
40import com.google.common.collect.Iterables;
41
a0a88f65
AM
42/**
43 * Base event for custom text parsers.
44 *
45 * @author Patrick Tassé
46 */
6151d86c
PT
47public class CustomEvent extends TmfEvent {
48
f5cc6ed1
PT
49 /** Payload data map key
50 * @since 2.1*/
51 protected enum Key {
52 /** Timestamp input format */
53 TIMESTAMP_INPUT_FORMAT
54 }
55
56 /** Input format key
57 * @deprecated Use {@link Key#TIMESTAMP_INPUT_FORMAT} instead. */
58 @Deprecated
6151d86c 59 protected static final String TIMESTAMP_INPUT_FORMAT_KEY = "CE_TS_I_F"; //$NON-NLS-1$
a0a88f65
AM
60
61 /** Empty message */
6151d86c 62 protected static final String NO_MESSAGE = ""; //$NON-NLS-1$
6151d86c 63
bd54d363 64 /** Replacement for the super-class' timestamp field */
cbf0057c 65 private @NonNull ITmfTimestamp customEventTimestamp;
bd54d363
AM
66
67 /** Replacement for the super-class' content field */
68 private ITmfEventField customEventContent;
69
70 /** Replacement for the super-class' type field */
71 private ITmfEventType customEventType;
72
a0a88f65 73 /** The trace to which this event belongs */
6151d86c 74 protected CustomTraceDefinition fDefinition;
a0a88f65 75
f5cc6ed1
PT
76 /**
77 * The payload data of this event, where the key is one of: the {@link Tag},
78 * the field name string if the tag is {@link Tag#OTHER}, or
79 * {@link Key#TIMESTAMP_INPUT_FORMAT}.
80 */
81 protected Map<Object, String> fData;
a0a88f65 82
a0a88f65
AM
83 /**
84 * Basic constructor.
85 *
86 * @param definition
87 * The trace definition to which this event belongs
88 */
6151d86c 89 public CustomEvent(CustomTraceDefinition definition) {
e1de2fd4 90 super(null, ITmfContext.UNKNOWN_RANK, null, null, null);
6151d86c 91 fDefinition = definition;
efeeb733 92 fData = new LinkedHashMap<>();
cbf0057c 93 customEventTimestamp = TmfTimestamp.ZERO;
6151d86c
PT
94 }
95
a0a88f65
AM
96 /**
97 * Build a new CustomEvent from an existing TmfEvent.
98 *
99 * @param definition
100 * The trace definition to which this event belongs
101 * @param other
102 * The TmfEvent to copy
103 */
ca5b04ad 104 public CustomEvent(CustomTraceDefinition definition, @NonNull TmfEvent other) {
6151d86c
PT
105 super(other);
106 fDefinition = definition;
efeeb733 107 fData = new LinkedHashMap<>();
bd54d363
AM
108
109 /* Set our overridden fields */
110 customEventTimestamp = other.getTimestamp();
111 customEventContent = other.getContent();
112 customEventType = other.getType();
6151d86c
PT
113 }
114
a0a88f65
AM
115 /**
116 * Full constructor
117 *
118 * @param definition
119 * Trace definition of this event
120 * @param parentTrace
121 * Parent trace object
122 * @param timestamp
123 * Timestamp of this event
a0a88f65
AM
124 * @param type
125 * Event type
a0a88f65
AM
126 */
127 public CustomEvent(CustomTraceDefinition definition, ITmfTrace parentTrace,
e1de2fd4 128 ITmfTimestamp timestamp, TmfEventType type) {
bd54d363 129 /* Do not use upstream's fields for stuff we override */
e1de2fd4 130 super(parentTrace, ITmfContext.UNKNOWN_RANK, null, null, null);
6151d86c 131 fDefinition = definition;
efeeb733 132 fData = new LinkedHashMap<>();
bd54d363
AM
133
134 /* Set our overridden fields */
cbf0057c
GB
135 if (timestamp == null) {
136 customEventTimestamp = TmfTimestamp.ZERO;
137 } else {
138 customEventTimestamp = timestamp;
139 }
bd54d363
AM
140 customEventContent = null;
141 customEventType = type;
6151d86c
PT
142 }
143
bd54d363
AM
144 // ------------------------------------------------------------------------
145 // Overridden getters
146 // ------------------------------------------------------------------------
147
6151d86c
PT
148 @Override
149 public ITmfTimestamp getTimestamp() {
150 if (fData != null) {
151 processData();
152 }
bd54d363 153 return customEventTimestamp;
6151d86c
PT
154 }
155
bd54d363
AM
156 @Override
157 public ITmfEventField getContent() {
0ff3b4eb
PT
158 if (fData != null) {
159 processData();
160 }
bd54d363
AM
161 return customEventContent;
162 }
163
164 @Override
165 public ITmfEventType getType() {
166 return customEventType;
167 }
168
53f17e49
GB
169 @Override
170 public String getName() {
171 if (fData != null) {
172 processData();
173 }
174 return super.getName();
175 }
176
bd54d363
AM
177 // ------------------------------------------------------------------------
178 // Setters
179 // ------------------------------------------------------------------------
180
181 /**
182 * Set this event's timestamp
183 *
184 * @param timestamp
185 * The new timestamp
186 */
cbf0057c 187 protected void setTimestamp(@NonNull ITmfTimestamp timestamp) {
bd54d363
AM
188 customEventTimestamp = timestamp;
189 }
190
191 /**
192 * Set this event's content
193 *
194 * @param content
195 * The new content
196 */
197 protected void setContent(ITmfEventField content) {
198 customEventContent = content;
199 }
200
eab78906
PT
201 /**
202 * Get this event's content value.
203 * <p>
204 * This does not process the payload data and is therefore safe to call in
205 * the middle of parsing an event.
206 *
207 * @return the event's content value.
208 */
209 Object getContentValue() {
210 return customEventContent.getValue();
211 }
212
bd54d363
AM
213 /**
214 * Set this event's type
215 *
216 * @param type
217 * The new type
218 */
219 protected void setType(ITmfEventType type) {
220 customEventType = type;
221 }
222
223 // ------------------------------------------------------------------------
224 // Other operations
225 // ------------------------------------------------------------------------
226
baafe54c
AM
227 /**
228 * Get the contents of an event table cell for this event's row.
229 *
230 * @param index
231 * The ID/index of the field to display. This corresponds to the
232 * index in the event content.
233 * @return The String to display in the cell
0fa1aec2 234 * @deprecated Use {@link ITmfEventField#getField(String...)} instead.
baafe54c 235 */
0fa1aec2 236 @Deprecated
baafe54c 237 public String getEventString(int index) {
0fa1aec2
PT
238 Collection<? extends ITmfEventField> fields = getContent().getFields();
239 if (index < 0 || index >= fields.size()) {
baafe54c
AM
240 return ""; //$NON-NLS-1$
241 }
242
0fa1aec2 243 return nullToEmptyString(checkNotNull(Iterables.get(fields, index)).getValue());
baafe54c
AM
244 }
245
6151d86c 246 private void processData() {
efeeb733
GB
247 // Remove the values as they are processed, so we can process the extra values at the end
248 String timestampString = fData.remove(Tag.TIMESTAMP);
249 String timestampInputFormat = fData.remove(Key.TIMESTAMP_INPUT_FORMAT);
b2c971ec 250 ITmfTimestamp timestamp = null;
738beb68
PT
251 if (timestampInputFormat != null && timestampString != null) {
252 TmfTimestampFormat timestampFormat = new TmfTimestampFormat(timestampInputFormat);
6151d86c 253 try {
738beb68 254 long time = timestampFormat.parseValue(timestampString);
b2c971ec 255 timestamp = TmfTimestamp.fromNanos(getTrace().getTimestampTransform().transform(time));
738beb68 256 setTimestamp(timestamp);
6151d86c
PT
257 } catch (ParseException e) {
258 setTimestamp(TmfTimestamp.ZERO);
259 }
260 } else {
261 setTimestamp(TmfTimestamp.ZERO);
262 }
263
53f17e49 264 // Update the custom event type of this event if set
efeeb733 265 String eventName = fData.remove(Tag.EVENT_TYPE);
53f17e49
GB
266 ITmfEventType type = getType();
267 if (eventName != null && type instanceof CustomEventType) {
268 ((CustomEventType) type).setName(eventName);
269 }
270
efeeb733 271 Map<String, TmfEventField> fieldMap = new LinkedHashMap<>();
6151d86c 272 for (OutputColumn outputColumn : fDefinition.outputs) {
4d12b563
PT
273 if (outputColumn.tag.equals(Tag.TIMESTAMP)) {
274 if (timestamp != null && fDefinition.timeStampOutputFormat != null && !fDefinition.timeStampOutputFormat.isEmpty()) {
275 TmfTimestampFormat timestampFormat = new TmfTimestampFormat(fDefinition.timeStampOutputFormat);
efeeb733 276 fieldMap.put(outputColumn.name, new TmfEventField(outputColumn.name, timestampFormat.format(timestamp.getValue()), null));
4d12b563 277 }
efeeb733
GB
278 } else if (outputColumn.tag.equals(Tag.OTHER) || outputColumn.tag.equals(Tag.MESSAGE)) {
279 Object key = (outputColumn.tag.equals(Tag.OTHER) ? outputColumn.name : outputColumn.tag);
280 fieldMap.put(outputColumn.name, new TmfEventField(outputColumn.name, nullToEmptyString(fData.remove(key)), null));
6151d86c
PT
281 }
282 }
efeeb733
GB
283 // This event contains extra values, we process them now
284 for (Entry<Object, String> entry : fData.entrySet()) {
285 String fieldName = nullToEmptyString(entry.getKey().toString());
286 // Ignore extra fields if a field of same name is already set
287 if (!fieldMap.containsKey(fieldName)) {
288 fieldMap.put(fieldName, new CustomExtraField(fieldName, nullToEmptyString(entry.getValue()), null));
289 }
290 }
291 setContent(new CustomEventContent(customEventContent.getName(), customEventContent.getValue(), fieldMap.values().toArray(new ITmfEventField[fieldMap.size()])));
6151d86c
PT
292 fData = null;
293 }
294
6151d86c
PT
295 @Override
296 public int hashCode() {
297 final int prime = 31;
298 int result = super.hashCode();
299 result = prime * result + ((fDefinition == null) ? 0 : fDefinition.hashCode());
cbf0057c 300 result = prime * result + customEventTimestamp.hashCode();
bd54d363
AM
301 result = prime * result + ((customEventContent == null) ? 0 : customEventContent.hashCode());
302 result = prime * result + ((customEventType == null) ? 0 : customEventType.hashCode());
6151d86c
PT
303 return result;
304 }
305
6151d86c
PT
306 @Override
307 public boolean equals(Object obj) {
308 if (this == obj) {
309 return true;
310 }
311 if (!super.equals(obj)) {
312 return false;
313 }
314 if (!(obj instanceof CustomEvent)) {
315 return false;
316 }
317 CustomEvent other = (CustomEvent) obj;
7a0ebe01 318 if (!Objects.equals(fDefinition, other.fDefinition)) {
6151d86c
PT
319 return false;
320 }
bd54d363 321
cbf0057c 322 if (!customEventTimestamp.equals(other.customEventTimestamp)) {
bd54d363
AM
323 return false;
324 }
325
7a0ebe01 326 if (!Objects.equals(customEventContent, other.customEventContent)) {
bd54d363
AM
327 return false;
328 }
329
7a0ebe01 330 if (!Objects.equals(customEventType, other.customEventType)) {
bd54d363
AM
331 return false;
332 }
6151d86c
PT
333 return true;
334 }
335
336}
This page took 0.104412 seconds and 5 git commands to generate.