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