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