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
.List
;
18 import org
.eclipse
.jdt
.annotation
.NonNull
;
19 import org
.eclipse
.tracecompass
.ctf
.core
.event
.scope
.IDefinitionScope
;
20 import org
.eclipse
.tracecompass
.ctf
.core
.event
.scope
.ILexicalScope
;
21 import org
.eclipse
.tracecompass
.ctf
.core
.event
.scope
.LexicalScope
;
22 import org
.eclipse
.tracecompass
.ctf
.core
.event
.types
.Definition
;
23 import org
.eclipse
.tracecompass
.ctf
.core
.event
.types
.ICompositeDefinition
;
24 import org
.eclipse
.tracecompass
.ctf
.core
.event
.types
.IDefinition
;
25 import org
.eclipse
.tracecompass
.ctf
.core
.event
.types
.StructDeclaration
;
26 import org
.eclipse
.tracecompass
.ctf
.core
.event
.types
.StructDefinition
;
27 import org
.eclipse
.tracecompass
.internal
.ctf
.core
.event
.EventDeclaration
;
30 * Representation of a particular instance of an event.
32 public final class EventDefinition
implements IDefinitionScope
{
34 // ------------------------------------------------------------------------
36 // ------------------------------------------------------------------------
39 * Value representing an unknown cpu number.
43 public static final int UNKNOWN_CPU
= -1;
46 * A null event, can be used for testing or poison pilling
48 public static final @NonNull EventDefinition NULL_EVENT
= new EventDefinition(new EventDeclaration(), UNKNOWN_CPU
, -1L, null, null, null, null, null);
51 * The corresponding event declaration.
53 private final IEventDeclaration fDeclaration
;
56 * The timestamp of the current event.
58 private final long fTimestamp
;
60 private final ICompositeDefinition fEventHeaderDefinition
;
63 * The event context structure definition.
65 private final ICompositeDefinition fEventContext
;
67 private final ICompositeDefinition fStreamContext
;
69 private final ICompositeDefinition fPacketContext
;
72 * The event fields structure definition.
74 private final ICompositeDefinition fFields
;
77 * The current cpu, could be @link {@link IPacketHeader#UNKNOWN_CPU}
79 private final int fCpu
;
81 // ------------------------------------------------------------------------
83 // ------------------------------------------------------------------------
86 * Constructs an event definition.
89 * The corresponding event declaration
91 * The cpu source of the event. You can use UNKNOWN_CPU if it is
95 * @param eventHeaderDefinition
96 * The event header definition, can be null if there is no header
100 * @param packetContext
101 * the packet context (the one with content size, not magic number)
102 * @param streamContext
108 public EventDefinition(IEventDeclaration declaration
,
111 ICompositeDefinition eventHeaderDefinition
,
112 ICompositeDefinition streamContext
,
113 ICompositeDefinition eventContext
,
114 ICompositeDefinition packetContext
,
115 ICompositeDefinition fields
) {
116 fDeclaration
= declaration
;
117 fEventHeaderDefinition
= eventHeaderDefinition
;
119 fTimestamp
= timestamp
;
121 fEventContext
= eventContext
;
122 fPacketContext
= packetContext
;
123 fStreamContext
= streamContext
;
126 // ------------------------------------------------------------------------
127 // Getters/Setters/Predicates
128 // ------------------------------------------------------------------------
134 public ILexicalScope
getScopePath() {
135 String eventName
= fDeclaration
.getName();
136 if (eventName
== null) {
139 ILexicalScope myScope
= ILexicalScope
.EVENT
.getChild(eventName
);
140 if (myScope
== null) {
141 myScope
= new LexicalScope(ILexicalScope
.EVENT
, eventName
);
147 * Gets the declaration (the form) of the data
149 * @return the event declaration
151 public IEventDeclaration
getDeclaration() {
156 * Get the event header
158 * @return the event header
161 public ICompositeDefinition
getEventHeader() {
162 return fEventHeaderDefinition
;
166 * Gets the fields of a definition
168 * @return the fields of a definition in struct form. Can be null.
171 public ICompositeDefinition
getFields() {
176 * Gets the context of this event without the context of the stream
178 * @return the context in struct form
181 public ICompositeDefinition
getEventContext() {
182 return fEventContext
;
186 * Gets the context of this event within a stream
188 * @return the context in struct form
191 public ICompositeDefinition
getContext() {
193 /* Most common case so far */
194 if (fStreamContext
== null) {
195 return fEventContext
;
198 /* streamContext is not null, but the context of the event is null */
199 if (fEventContext
== null) {
200 return fStreamContext
;
203 // TODO: cache if this is a performance issue
205 /* The stream context and event context are assigned. */
206 StructDeclaration mergedDeclaration
= new StructDeclaration(1);
208 List
<Definition
> fieldValues
= new ArrayList
<>();
210 /* Add fields from the stream */
211 List
<@NonNull String
> fieldNames
= fStreamContext
.getFieldNames();
212 for (String fieldName
: fieldNames
) {
213 Definition definition
= fStreamContext
.getDefinition(fieldName
);
214 mergedDeclaration
.addField(fieldName
, definition
.getDeclaration());
215 fieldValues
.add(definition
);
219 * Add fields from the event context, overwrite the stream ones if
222 for (String fieldName
: fEventContext
.getFieldNames()) {
223 Definition definition
= fEventContext
.getDefinition(fieldName
);
224 mergedDeclaration
.addField(fieldName
, definition
.getDeclaration());
225 if (fieldNames
.contains(fieldName
)) {
226 fieldValues
.set((fieldNames
.indexOf(fieldName
)), definition
);
228 fieldValues
.add(definition
);
231 return new StructDefinition(mergedDeclaration
, this, "context", //$NON-NLS-1$
232 fieldValues
.toArray(new Definition
[fieldValues
.size()]));
236 * Gets the context of packet the event is in.
238 * @return the packet context
241 public ICompositeDefinition
getPacketContext() {
242 return fPacketContext
;
246 * gets the CPU the event was generated by. Slightly LTTng specific
248 * @return The CPU the event was generated by
250 public int getCPU() {
255 * @return the timestamp
257 public long getTimestamp() {
261 // ------------------------------------------------------------------------
263 // ------------------------------------------------------------------------
269 public IDefinition
lookupDefinition(String lookupPath
) {
270 if (lookupPath
.equals("context")) { //$NON-NLS-1$
271 return fEventContext
;
272 } else if (lookupPath
.equals("fields")) { //$NON-NLS-1$
280 public String
toString() {
281 Iterable
<String
> list
;
282 StringBuilder retString
= new StringBuilder();
283 final String cr
= System
.getProperty("line.separator");//$NON-NLS-1$
285 retString
.append("Event type: ").append(fDeclaration
.getName()).append(cr
); //$NON-NLS-1$
286 retString
.append("Timestamp: ").append(Long
.toString(fTimestamp
)).append(cr
); //$NON-NLS-1$
288 if (fEventContext
!= null) {
289 list
= fEventContext
.getFieldNames();
291 for (String field
: list
) {
292 retString
.append(field
).append(" : ").append(fEventContext
.getDefinition(field
).toString()).append(cr
); //$NON-NLS-1$
296 if (fFields
!= null) {
297 list
= fFields
.getFieldNames();
299 for (String field
: list
) {
300 retString
.append(field
).append(" : ").append(fFields
.getDefinition(field
).toString()).append(cr
); //$NON-NLS-1$
304 return retString
.toString();