32e7d8ed1af918105b2c5ed5e3727edcd29b7fb6
[deliverable/tracecompass.git] / ctf / org.eclipse.tracecompass.tmf.ctf.core / src / org / eclipse / tracecompass / tmf / ctf / core / event / CtfTmfEvent.java
1 /*******************************************************************************
2 * Copyright (c) 2011, 2015 Ericsson
3 *
4 * All rights reserved. This program and the accompanying materials are made
5 * 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 * Alexandre Montplaisir - Initial API and implementation
11 * Bernd Hufmann - Updated for source and model lookup interfaces
12 *******************************************************************************/
13
14 package org.eclipse.tracecompass.tmf.ctf.core.event;
15
16 import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
17
18 import java.util.ArrayList;
19 import java.util.Collections;
20 import java.util.HashSet;
21 import java.util.List;
22 import java.util.Map;
23 import java.util.Set;
24
25 import org.eclipse.jdt.annotation.NonNull;
26 import org.eclipse.jdt.annotation.NonNullByDefault;
27 import org.eclipse.jdt.annotation.Nullable;
28 import org.eclipse.tracecompass.ctf.core.event.IEventDeclaration;
29 import org.eclipse.tracecompass.ctf.core.event.IEventDefinition;
30 import org.eclipse.tracecompass.ctf.core.event.types.ICompositeDefinition;
31 import org.eclipse.tracecompass.ctf.core.event.types.IDefinition;
32 import org.eclipse.tracecompass.ctf.core.trace.ICTFStream;
33 import org.eclipse.tracecompass.tmf.core.event.ITmfCustomAttributes;
34 import org.eclipse.tracecompass.tmf.core.event.ITmfEventField;
35 import org.eclipse.tracecompass.tmf.core.event.ITmfEventType;
36 import org.eclipse.tracecompass.tmf.core.event.TmfEvent;
37 import org.eclipse.tracecompass.tmf.core.event.TmfEventField;
38 import org.eclipse.tracecompass.tmf.core.event.lookup.ITmfModelLookup;
39 import org.eclipse.tracecompass.tmf.core.timestamp.TmfNanoTimestamp;
40 import org.eclipse.tracecompass.tmf.core.trace.ITmfContext;
41 import org.eclipse.tracecompass.tmf.ctf.core.CtfConstants;
42 import org.eclipse.tracecompass.tmf.ctf.core.trace.CtfTmfTrace;
43
44 /**
45 * A wrapper class around CTF's Event Definition/Declaration that maps all types
46 * of Declaration to native Java types.
47 *
48 * @author Alexandre Montplaisir
49 */
50 @NonNullByDefault
51 public class CtfTmfEvent extends TmfEvent
52 implements ITmfModelLookup, ITmfCustomAttributes {
53
54 // ------------------------------------------------------------------------
55 // Constants
56 // ------------------------------------------------------------------------
57
58 private static final String EMPTY_CTF_EVENT_NAME = "Empty CTF event"; //$NON-NLS-1$
59
60 // ------------------------------------------------------------------------
61 // Support attributes
62 // Not part of this event's "definition", but used to populate lazy-loaded
63 // fields.
64 // ------------------------------------------------------------------------
65
66 private final @Nullable IEventDeclaration fEventDeclaration;
67 private final IEventDefinition fEvent;
68
69 // ------------------------------------------------------------------------
70 // Attributes
71 // ------------------------------------------------------------------------
72
73 /* Fields that are introduced by and part of this event's definition. */
74 private final int fSourceCpu;
75 private final String fChannel;
76
77 /**
78 * Field to override {@link TmfEvent#getName()}, to bypass the type-getting
79 */
80 private final String fEventName;
81
82 /** Lazy-loaded field containing the event's payload */
83 private transient @Nullable ITmfEventField fContent;
84
85 /** Lazy-loaded field for the type, overriding TmfEvent's field */
86 private transient @Nullable CtfTmfEventType fEventType;
87
88 private final @Nullable ICTFStream fStream;
89 private final Map<String, Object> fPacketAttributes;
90
91 // ------------------------------------------------------------------------
92 // Constructors
93 // ------------------------------------------------------------------------
94
95 /**
96 * Constructor, used by {@link CtfTmfEventFactory#createEvent}.
97 *
98 * Only subclasses should call this. It is imperative that the subclass also
99 * has a constructor with the EXACT same parameter signature, because the
100 * factory will look for a constructor with the same arguments.
101 *
102 * @param trace
103 * The trace to which this event belongs
104 * @param rank
105 * The rank of the event
106 * @param timestamp
107 * The timestamp
108 * @param channel
109 * The CTF channel of this event
110 * @param cpu
111 * The event's CPU
112 * @param declaration
113 * The event declaration
114 * @param eventDefinition
115 * The event definition
116 * @since 2.0
117 */
118 protected CtfTmfEvent(CtfTmfTrace trace,
119 long rank,
120 TmfNanoTimestamp timestamp,
121 String channel,
122 int cpu,
123 IEventDeclaration declaration,
124 IEventDefinition eventDefinition) {
125 super(trace,
126 rank,
127 timestamp,
128 /*
129 * Event type. We don't use TmfEvent's field here, we
130 * re-implement getType().
131 */
132 null,
133 /*
134 * Content handled with a lazy-loaded field re-implemented in
135 * getContent().
136 */
137 null);
138
139 fEventDeclaration = declaration;
140 fSourceCpu = cpu;
141 fEventName = checkNotNull(declaration.getName());
142 fEvent = eventDefinition;
143 fChannel = channel;
144 fStream = fEvent.getDeclaration().getStream();
145 fPacketAttributes = eventDefinition.getPacketAttributes();
146 }
147
148 /**
149 * Inner constructor to create "null" events. Don't use this directly in
150 * normal usage, use {@link CtfTmfEventFactory#getNullEvent(CtfTmfTrace)} to
151 * get an instance of an empty event.
152 *
153 * There is no need to give higher visibility to this method than package
154 * visible.
155 *
156 * @param trace
157 * The trace associated with this event
158 */
159 CtfTmfEvent(CtfTmfTrace trace) {
160 super(trace,
161 ITmfContext.UNKNOWN_RANK,
162 new TmfNanoTimestamp(-1),
163 null,
164 new TmfEventField("", null, new CtfTmfEventField[0])); //$NON-NLS-1$
165 fSourceCpu = -1;
166 fEventName = EMPTY_CTF_EVENT_NAME;
167 fEventDeclaration = null;
168 fEvent = NullEventDefinition.INSTANCE;
169 fChannel = ""; //$NON-NLS-1$
170 fStream = null;
171 fPacketAttributes = Collections.EMPTY_MAP;
172 }
173
174 /**
175 * Default constructor. Do not use directly, but it needs to be present
176 * because it's used in extension points, and the framework will use this
177 * constructor to get the class type.
178 *
179 * @deprecated Should not be called by normal code
180 */
181 @Deprecated
182 public CtfTmfEvent() {
183 super();
184 fSourceCpu = -1;
185 fEventName = EMPTY_CTF_EVENT_NAME;
186 fEventDeclaration = null;
187 fEvent = NullEventDefinition.INSTANCE;
188 fChannel = ""; //$NON-NLS-1$
189 fStream = null;
190 fPacketAttributes = Collections.EMPTY_MAP;
191 }
192
193 // ------------------------------------------------------------------------
194 // Getters/Setters/Predicates
195 // ------------------------------------------------------------------------
196
197 /**
198 * Gets the cpu core the event was recorded on.
199 *
200 * @return The cpu id for a given source. In lttng it's from CPUINFO
201 */
202 public int getCPU() {
203 return fSourceCpu;
204 }
205
206 /**
207 * Return the CTF trace's channel from which this event originates.
208 *
209 * @return The event's channel
210 * @since 2.0
211 */
212 public String getChannel() {
213 return fChannel;
214 }
215
216 /**
217 * Return this event's reference.
218 *
219 * @return The event's reference
220 * @deprecated This method was replaced by {@link #getChannel()}.
221 */
222 @Deprecated
223 public String getReference() {
224 return getChannel();
225 }
226
227 /**
228 * Get the stream Id
229 *
230 * @return the stream ID or -1 if the stream is null
231 * @since 2.0
232 */
233 public long getStreamId() {
234 ICTFStream stream = fStream;
235 if (stream == null) {
236 return -1;
237 }
238 return stream.getId();
239 }
240
241 // ------------------------------------------------------------------------
242 // TmfEvent
243 // ------------------------------------------------------------------------
244
245 @Override
246 public CtfTmfTrace getTrace() {
247 /*
248 * Should be of the right type, since we take a CtfTmfTrace at the
249 * constructor
250 */
251 return (CtfTmfTrace) super.getTrace();
252 }
253
254 @Override
255 public synchronized ITmfEventType getType() {
256 CtfTmfEventType type = fEventType;
257 if (type == null) {
258 type = new CtfTmfEventType(fEventName, getContent());
259
260 /*
261 * Register the event type in the owning trace, but only if there is
262 * one
263 */
264 getTrace().registerEventType(type);
265 fEventType = type;
266 }
267 return type;
268 }
269
270 @Override
271 public String getName() {
272 return fEventName;
273 }
274
275 @Override
276 public synchronized ITmfEventField getContent() {
277 ITmfEventField content = fContent;
278 if (content == null) {
279 content = new TmfEventField(
280 ITmfEventField.ROOT_FIELD_ID, null, parseFields(fEvent));
281 fContent = content;
282 }
283 return content;
284 }
285
286 /**
287 * Extract the field information from the structDefinition haze-inducing
288 * mess, and put them into something ITmfEventField can cope with.
289 */
290 private static CtfTmfEventField[] parseFields(IEventDefinition eventDef) {
291 List<CtfTmfEventField> fields = new ArrayList<>();
292
293 ICompositeDefinition structFields = eventDef.getFields();
294 if (structFields != null) {
295 if (structFields.getFieldNames() != null) {
296 for (String fn : structFields.getFieldNames()) {
297 fields.add(CtfTmfEventField.parseField((IDefinition) structFields.getDefinition(fn), fn));
298 }
299 }
300 }
301 /* Add context information as CtfTmfEventField */
302 ICompositeDefinition structContext = eventDef.getContext();
303 if (structContext != null) {
304 for (String contextName : structContext.getFieldNames()) {
305 /* Prefix field name */
306 String curContextName = CtfConstants.CONTEXT_FIELD_PREFIX + contextName;
307 fields.add(CtfTmfEventField.parseField((IDefinition) structContext.getDefinition(contextName), curContextName));
308 }
309 }
310
311 return fields.toArray(new @NonNull CtfTmfEventField[fields.size()]);
312 }
313
314 // ------------------------------------------------------------------------
315 // ITmfCustomAttributes
316 // ------------------------------------------------------------------------
317
318 @Override
319 public Set<String> listCustomAttributes() {
320 IEventDeclaration declaration = fEventDeclaration;
321 if (declaration == null) {
322 return new HashSet<>();
323 }
324 return declaration.getCustomAttributes();
325 }
326
327 @Override
328 public @Nullable String getCustomAttribute(@Nullable String name) {
329 IEventDeclaration declaration = fEventDeclaration;
330 if (declaration == null) {
331 return null;
332 }
333 return declaration.getCustomAttribute(name);
334 }
335
336 @Override
337 public @Nullable String getModelUri() {
338 return getCustomAttribute(CtfConstants.MODEL_URI_KEY);
339 }
340
341 /**
342 * Gets the packet attributes. The result is an instance of one of the
343 * following classes: <code>Entry<String, Long></code>, <code>Long</code>,
344 * <code>String</code> or <code>Double</code>. The map contains pairs of key
345 * and values where the key and value can never be null.
346 *
347 * @return gets the packet attributes
348 * @since 2.0
349 */
350 public Map<String, Object> getPacketAttributes() {
351 return fPacketAttributes;
352 }
353
354 // ------------------------------------------------------------------------
355 // Object
356 // ------------------------------------------------------------------------
357
358 @Override
359 public int hashCode() {
360 final int prime = 31;
361 int result = super.hashCode();
362 result = prime * result + getCPU();
363 result = prime * result + getChannel().hashCode();
364 return result;
365 }
366
367 @Override
368 public boolean equals(@Nullable Object obj) {
369 if (!super.equals(obj)) {
370 return false;
371 }
372 /* super.equals() checks that the classes are the same */
373 CtfTmfEvent other = checkNotNull((CtfTmfEvent) obj);
374 if (getCPU() != other.getCPU()) {
375 return false;
376 }
377 if (!getChannel().equals(other.getChannel())) {
378 return false;
379 }
380 return true;
381 }
382
383 }
This page took 0.042324 seconds and 4 git commands to generate.