1 /*******************************************************************************
2 * Copyright (c) 2011, 2015 Ericsson
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
10 * Alexandre Montplaisir - Initial API and implementation
11 * Bernd Hufmann - Updated for source and model lookup interfaces
12 *******************************************************************************/
14 package org
.eclipse
.tracecompass
.tmf
.ctf
.core
.event
;
16 import static org
.eclipse
.tracecompass
.common
.core
.NonNullUtils
.checkNotNull
;
18 import java
.util
.ArrayList
;
19 import java
.util
.HashSet
;
20 import java
.util
.List
;
23 import org
.eclipse
.jdt
.annotation
.NonNullByDefault
;
24 import org
.eclipse
.jdt
.annotation
.Nullable
;
25 import org
.eclipse
.tracecompass
.ctf
.core
.event
.EventDefinition
;
26 import org
.eclipse
.tracecompass
.ctf
.core
.event
.IEventDeclaration
;
27 import org
.eclipse
.tracecompass
.ctf
.core
.event
.types
.ICompositeDefinition
;
28 import org
.eclipse
.tracecompass
.ctf
.core
.event
.types
.IDefinition
;
29 import org
.eclipse
.tracecompass
.tmf
.core
.event
.ITmfCustomAttributes
;
30 import org
.eclipse
.tracecompass
.tmf
.core
.event
.ITmfEventField
;
31 import org
.eclipse
.tracecompass
.tmf
.core
.event
.ITmfEventType
;
32 import org
.eclipse
.tracecompass
.tmf
.core
.event
.TmfEvent
;
33 import org
.eclipse
.tracecompass
.tmf
.core
.event
.TmfEventField
;
34 import org
.eclipse
.tracecompass
.tmf
.core
.event
.lookup
.ITmfModelLookup
;
35 import org
.eclipse
.tracecompass
.tmf
.core
.event
.lookup
.ITmfSourceLookup
;
36 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.TmfNanoTimestamp
;
37 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.ITmfContext
;
38 import org
.eclipse
.tracecompass
.tmf
.ctf
.core
.CtfConstants
;
39 import org
.eclipse
.tracecompass
.tmf
.ctf
.core
.event
.lookup
.CtfTmfCallsite
;
40 import org
.eclipse
.tracecompass
.tmf
.ctf
.core
.trace
.CtfTmfTrace
;
43 * A wrapper class around CTF's Event Definition/Declaration that maps all types
44 * of Declaration to native Java types.
46 * @author Alexandre Montplaisir
49 public class CtfTmfEvent
extends TmfEvent
50 implements ITmfSourceLookup
, ITmfModelLookup
, ITmfCustomAttributes
{
52 // ------------------------------------------------------------------------
54 // ------------------------------------------------------------------------
56 private static final String EMPTY_CTF_EVENT_NAME
= "Empty CTF event"; //$NON-NLS-1$
58 // ------------------------------------------------------------------------
60 // Not part of this event's "definition", but used to populate lazy-loaded
62 // ------------------------------------------------------------------------
64 private final @Nullable IEventDeclaration fEventDeclaration
;
65 private final EventDefinition fEvent
;
67 // ------------------------------------------------------------------------
69 // ------------------------------------------------------------------------
71 /* Fields that are introduced by and part of this event's definition. */
72 private final int fSourceCpu
;
73 private final String fChannel
;
75 /** Field to override {@link TmfEvent#getName()}, to bypass the type-getting */
76 private final String fEventName
;
78 /** Lazy-loaded field containing the event's payload */
79 private transient @Nullable ITmfEventField fContent
;
81 /** Lazy-loaded field for the type, overriding TmfEvent's field */
82 private transient @Nullable CtfTmfEventType fEventType
;
84 // ------------------------------------------------------------------------
86 // ------------------------------------------------------------------------
89 * Constructor used by {@link CtfTmfEventFactory#createEvent}
91 CtfTmfEvent(CtfTmfTrace trace
, long rank
, TmfNanoTimestamp timestamp
,
92 String channel
, int cpu
, IEventDeclaration declaration
, EventDefinition eventDefinition
) {
97 * Event type. We don't use TmfEvent's field here, we
98 * re-implement getType().
102 * Content handled with a lazy-loaded field re-implemented in
107 fEventDeclaration
= declaration
;
109 fEventName
= checkNotNull(declaration
.getName());
110 fEvent
= eventDefinition
;
115 * Inner constructor to create "null" events. Don't use this directly in
116 * normal usage, use {@link CtfTmfEventFactory#getNullEvent(CtfTmfTrace)} to
117 * get an instance of an empty event.
119 * There is no need to give higher visibility to this method than package
123 * The trace associated with this event
125 CtfTmfEvent(CtfTmfTrace trace
) {
127 ITmfContext
.UNKNOWN_RANK
,
128 new TmfNanoTimestamp(-1),
130 new TmfEventField("", null, new CtfTmfEventField
[0])); //$NON-NLS-1$
132 fEventName
= EMPTY_CTF_EVENT_NAME
;
133 fEventDeclaration
= null;
134 fEvent
= EventDefinition
.NULL_EVENT
;
135 fChannel
= ""; //$NON-NLS-1$
139 * Default constructor. Do not use directly, but it needs to be present
140 * because it's used in extension points, and the framework will use this
141 * constructor to get the class type.
143 * @deprecated Should not be called by normal code
146 public CtfTmfEvent() {
149 fEventName
= EMPTY_CTF_EVENT_NAME
;
150 fEventDeclaration
= null;
151 fEvent
= EventDefinition
.NULL_EVENT
;
152 fChannel
= ""; //$NON-NLS-1$
155 // ------------------------------------------------------------------------
156 // Getters/Setters/Predicates
157 // ------------------------------------------------------------------------
160 * Gets the cpu core the event was recorded on.
162 * @return The cpu id for a given source. In lttng it's from CPUINFO
165 public int getCpu() {
170 * Return the CTF trace's channel from which this event originates.
172 * @return The event's channel
175 public String
getChannel() {
179 // ------------------------------------------------------------------------
181 // ------------------------------------------------------------------------
184 public CtfTmfTrace
getTrace() {
186 * Should be of the right type, since we take a CtfTmfTrace at the
189 return (CtfTmfTrace
) super.getTrace();
193 public synchronized ITmfEventType
getType() {
194 CtfTmfEventType type
= fEventType
;
196 type
= new CtfTmfEventType(fEventName
, getContent());
199 * Register the event type in the owning trace, but only if there is
202 getTrace().registerEventType(type
);
209 public String
getName() {
214 public synchronized ITmfEventField
getContent() {
215 ITmfEventField content
= fContent
;
216 if (content
== null) {
217 content
= new TmfEventField(
218 ITmfEventField
.ROOT_FIELD_ID
, null, parseFields(fEvent
));
225 * Extract the field information from the structDefinition haze-inducing
226 * mess, and put them into something ITmfEventField can cope with.
228 private static CtfTmfEventField
[] parseFields(EventDefinition eventDef
) {
229 List
<CtfTmfEventField
> fields
= new ArrayList
<>();
231 ICompositeDefinition structFields
= eventDef
.getFields();
232 if (structFields
!= null) {
233 if (structFields
.getFieldNames() != null) {
234 for (String curFieldName
: structFields
.getFieldNames()) {
235 String fn
= checkNotNull(curFieldName
);
236 fields
.add(CtfTmfEventField
.parseField((IDefinition
) structFields
.getDefinition(fn
), fn
));
240 /* Add context information as CtfTmfEventField */
241 ICompositeDefinition structContext
= eventDef
.getContext();
242 if (structContext
!= null) {
243 for (String contextName
: structContext
.getFieldNames()) {
244 /* Prefix field name */
245 String curContextName
= CtfConstants
.CONTEXT_FIELD_PREFIX
+ contextName
;
246 fields
.add(CtfTmfEventField
.parseField((IDefinition
) structContext
.getDefinition(contextName
), curContextName
));
250 return checkNotNull(fields
.toArray(new CtfTmfEventField
[fields
.size()]));
253 // ------------------------------------------------------------------------
254 // ITmfCustomAttributes
255 // ------------------------------------------------------------------------
258 public Set
<String
> listCustomAttributes() {
259 IEventDeclaration declaration
= fEventDeclaration
;
260 if (declaration
== null) {
261 return new HashSet
<>();
263 return checkNotNull(declaration
.getCustomAttributes());
267 public @Nullable String
getCustomAttribute(@Nullable String name
) {
268 IEventDeclaration declaration
= fEventDeclaration
;
269 if (declaration
== null) {
272 return declaration
.getCustomAttribute(name
);
275 // ------------------------------------------------------------------------
277 // ------------------------------------------------------------------------
280 * Get the call site for this event.
282 * @return the call site information, or null if there is none
285 public @Nullable CtfTmfCallsite
getCallsite() {
286 CtfTmfCallsite callsite
= null;
288 ITmfEventField ipField
= getContent().getField(CtfConstants
.CONTEXT_FIELD_PREFIX
+ CtfConstants
.IP_KEY
);
289 if (ipField
!= null && ipField
.getValue() instanceof Long
) {
290 long ip
= (Long
) ipField
.getValue();
291 callsite
= getTrace().getCallsite(fEventName
, ip
);
294 if (callsite
== null) {
295 callsite
= getTrace().getCallsite(fEventName
);
300 // ------------------------------------------------------------------------
302 // ------------------------------------------------------------------------
305 public @Nullable String
getModelUri() {
306 return getCustomAttribute(CtfConstants
.MODEL_URI_KEY
);
309 // ------------------------------------------------------------------------
311 // ------------------------------------------------------------------------
314 public int hashCode() {
315 final int prime
= 31;
316 int result
= super.hashCode();
317 result
= prime
* result
+ getCpu();
318 result
= prime
* result
+ getChannel().hashCode();
323 public boolean equals(@Nullable Object obj
) {
324 if (!super.equals(obj
)) {
327 /* super.equals() checks that the classes are the same */
328 CtfTmfEvent other
= checkNotNull((CtfTmfEvent
) obj
);
329 if (getCpu() != other
.getCpu()) {
332 if (!getChannel().equals(other
.getChannel())) {