1 /*******************************************************************************
2 * Copyright (c) 2011-2014 Ericsson, Ecole Polytechnique de Montreal and others
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
9 * Contributors: Matthew Khouzam - Initial API and implementation
10 * Contributors: Simon Marchi - Initial API and implementation
11 *******************************************************************************/
13 package org
.eclipse
.tracecompass
.ctf
.core
.event
;
15 import java
.util
.ArrayList
;
16 import java
.util
.Collections
;
17 import java
.util
.List
;
20 import org
.eclipse
.jdt
.annotation
.NonNull
;
21 import org
.eclipse
.jdt
.annotation
.Nullable
;
22 import org
.eclipse
.tracecompass
.ctf
.core
.event
.scope
.IDefinitionScope
;
23 import org
.eclipse
.tracecompass
.ctf
.core
.event
.scope
.ILexicalScope
;
24 import org
.eclipse
.tracecompass
.ctf
.core
.event
.scope
.LexicalScope
;
25 import org
.eclipse
.tracecompass
.ctf
.core
.event
.types
.Definition
;
26 import org
.eclipse
.tracecompass
.ctf
.core
.event
.types
.ICompositeDefinition
;
27 import org
.eclipse
.tracecompass
.ctf
.core
.event
.types
.IDefinition
;
28 import org
.eclipse
.tracecompass
.ctf
.core
.event
.types
.StructDeclaration
;
29 import org
.eclipse
.tracecompass
.ctf
.core
.event
.types
.StructDefinition
;
30 import org
.eclipse
.tracecompass
.ctf
.core
.trace
.ICTFPacketDescriptor
;
31 import org
.eclipse
.tracecompass
.internal
.ctf
.core
.event
.EventDeclaration
;
34 * Representation of a particular instance of an event.
36 public final class EventDefinition
implements IDefinitionScope
{
38 // ------------------------------------------------------------------------
40 // ------------------------------------------------------------------------
43 * Value representing an unknown cpu number.
47 public static final int UNKNOWN_CPU
= -1;
50 * A null event, can be used for testing or poison pilling
52 public static final @NonNull EventDefinition NULL_EVENT
= new EventDefinition(new EventDeclaration(), UNKNOWN_CPU
, -1L, null, null, null, null, null, null);
55 * The corresponding event declaration.
57 private final IEventDeclaration fDeclaration
;
60 * The timestamp of the current event.
62 private final long fTimestamp
;
64 private final ICompositeDefinition fEventHeaderDefinition
;
67 * The event context structure definition.
69 private final ICompositeDefinition fEventContext
;
71 private final ICompositeDefinition fStreamContext
;
73 private final ICompositeDefinition fPacketContext
;
76 * The event fields structure definition.
78 private final ICompositeDefinition fFields
;
81 * The current cpu, could be @link {@link IPacketHeader#UNKNOWN_CPU}
83 private final int fCpu
;
85 private final @NonNull Map
<String
, Object
> fPacketAttributes
;
87 // ------------------------------------------------------------------------
89 // ------------------------------------------------------------------------
92 * Constructs an event definition.
95 * The corresponding event declaration
97 * The cpu source of the event. You can use UNKNOWN_CPU if it is
101 * @param eventHeaderDefinition
102 * The event header definition, can be null if there is no header
104 * @param eventContext
106 * @param packetContext
107 * the packet context (the one with content size, not magic
109 * @param streamContext
113 * @param packetDescriptor
114 * descriptor of the packet containing this event
117 public EventDefinition(IEventDeclaration declaration
,
120 ICompositeDefinition eventHeaderDefinition
,
121 ICompositeDefinition streamContext
,
122 ICompositeDefinition eventContext
,
123 ICompositeDefinition packetContext
,
124 ICompositeDefinition fields
,
125 @Nullable ICTFPacketDescriptor packetDescriptor
) {
126 fDeclaration
= declaration
;
127 fEventHeaderDefinition
= eventHeaderDefinition
;
129 fTimestamp
= timestamp
;
131 fEventContext
= eventContext
;
132 fPacketContext
= packetContext
;
133 fStreamContext
= streamContext
;
134 fPacketAttributes
= packetDescriptor
!= null ? packetDescriptor
.getAttributes() : Collections
.EMPTY_MAP
;
137 // ------------------------------------------------------------------------
138 // Getters/Setters/Predicates
139 // ------------------------------------------------------------------------
145 public ILexicalScope
getScopePath() {
146 String eventName
= fDeclaration
.getName();
147 if (eventName
== null) {
150 ILexicalScope myScope
= ILexicalScope
.EVENT
.getChild(eventName
);
151 if (myScope
== null) {
152 myScope
= new LexicalScope(ILexicalScope
.EVENT
, eventName
);
158 * Gets the declaration (the form) of the data
160 * @return the event declaration
162 public IEventDeclaration
getDeclaration() {
167 * Get the event header
169 * @return the event header
172 public ICompositeDefinition
getEventHeader() {
173 return fEventHeaderDefinition
;
177 * Gets the fields of a definition
179 * @return the fields of a definition in struct form. Can be null.
182 public ICompositeDefinition
getFields() {
187 * Gets the context of this event without the context of the stream
189 * @return the context in struct form
192 public ICompositeDefinition
getEventContext() {
193 return fEventContext
;
197 * Gets the context of this event within a stream
199 * @return the context in struct form
202 public ICompositeDefinition
getContext() {
204 /* Most common case so far */
205 if (fStreamContext
== null) {
206 return fEventContext
;
209 /* streamContext is not null, but the context of the event is null */
210 if (fEventContext
== null) {
211 return fStreamContext
;
214 // TODO: cache if this is a performance issue
216 /* The stream context and event context are assigned. */
217 StructDeclaration mergedDeclaration
= new StructDeclaration(1);
219 List
<Definition
> fieldValues
= new ArrayList
<>();
221 /* Add fields from the stream */
222 List
<@NonNull String
> fieldNames
= fStreamContext
.getFieldNames();
223 for (String fieldName
: fieldNames
) {
224 Definition definition
= fStreamContext
.getDefinition(fieldName
);
225 mergedDeclaration
.addField(fieldName
, definition
.getDeclaration());
226 fieldValues
.add(definition
);
230 * Add fields from the event context, overwrite the stream ones if
233 for (String fieldName
: fEventContext
.getFieldNames()) {
234 Definition definition
= fEventContext
.getDefinition(fieldName
);
235 mergedDeclaration
.addField(fieldName
, definition
.getDeclaration());
236 if (fieldNames
.contains(fieldName
)) {
237 fieldValues
.set((fieldNames
.indexOf(fieldName
)), definition
);
239 fieldValues
.add(definition
);
242 return new StructDefinition(mergedDeclaration
, this, "context", //$NON-NLS-1$
243 fieldValues
.toArray(new Definition
[fieldValues
.size()]));
247 * Gets the context of packet the event is in.
249 * @return the packet context
252 public ICompositeDefinition
getPacketContext() {
253 return fPacketContext
;
257 * gets the CPU the event was generated by. Slightly LTTng specific
259 * @return The CPU the event was generated by
261 public int getCPU() {
266 * @return the timestamp
268 public long getTimestamp() {
273 * Get the packet attributes.
275 * @return the packet attributes, such as "device" and "timestamp_begin"
278 public @NonNull Map
<String
, Object
> getPacketAttributes() {
279 return fPacketAttributes
;
281 // ------------------------------------------------------------------------
283 // ------------------------------------------------------------------------
289 public IDefinition
lookupDefinition(String lookupPath
) {
290 if (lookupPath
.equals("context")) { //$NON-NLS-1$
291 return fEventContext
;
292 } else if (lookupPath
.equals("fields")) { //$NON-NLS-1$
300 public String
toString() {
301 Iterable
<String
> list
;
302 StringBuilder retString
= new StringBuilder();
303 final String cr
= System
.getProperty("line.separator");//$NON-NLS-1$
305 retString
.append("Event type: ").append(fDeclaration
.getName()).append(cr
); //$NON-NLS-1$
306 retString
.append("Timestamp: ").append(Long
.toString(fTimestamp
)).append(cr
); //$NON-NLS-1$
308 if (fEventContext
!= null) {
309 list
= fEventContext
.getFieldNames();
311 for (String field
: list
) {
312 retString
.append(field
).append(" : ").append(fEventContext
.getDefinition(field
).toString()).append(cr
); //$NON-NLS-1$
316 if (fFields
!= null) {
317 list
= fFields
.getFieldNames();
319 for (String field
: list
) {
320 retString
.append(field
).append(" : ").append(fFields
.getDefinition(field
).toString()).append(cr
); //$NON-NLS-1$
324 return retString
.toString();