Commit | Line | Data |
---|---|---|
866e5b51 | 1 | /******************************************************************************* |
ed902a2b | 2 | * Copyright (c) 2011-2014 Ericsson, Ecole Polytechnique de Montreal and others |
866e5b51 FC |
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: Matthew Khouzam - Initial API and implementation | |
10 | * Contributors: Simon Marchi - Initial API and implementation | |
11 | *******************************************************************************/ | |
12 | ||
f357bcd4 | 13 | package org.eclipse.tracecompass.ctf.core.event; |
866e5b51 | 14 | |
a4fa4e36 | 15 | import java.util.ArrayList; |
6b8f960d | 16 | import java.util.Collections; |
866e5b51 | 17 | import java.util.List; |
6b8f960d | 18 | import java.util.Map; |
866e5b51 | 19 | |
a4fa4e36 | 20 | import org.eclipse.jdt.annotation.NonNull; |
6b8f960d | 21 | import org.eclipse.jdt.annotation.Nullable; |
f357bcd4 | 22 | import org.eclipse.tracecompass.ctf.core.event.scope.IDefinitionScope; |
fbe6fa6f | 23 | import org.eclipse.tracecompass.ctf.core.event.scope.ILexicalScope; |
f357bcd4 AM |
24 | import org.eclipse.tracecompass.ctf.core.event.scope.LexicalScope; |
25 | import org.eclipse.tracecompass.ctf.core.event.types.Definition; | |
778bce67 | 26 | import org.eclipse.tracecompass.ctf.core.event.types.ICompositeDefinition; |
fa533f33 | 27 | import org.eclipse.tracecompass.ctf.core.event.types.IDefinition; |
f357bcd4 AM |
28 | import org.eclipse.tracecompass.ctf.core.event.types.StructDeclaration; |
29 | import org.eclipse.tracecompass.ctf.core.event.types.StructDefinition; | |
6b8f960d | 30 | import org.eclipse.tracecompass.ctf.core.trace.ICTFPacketDescriptor; |
f357bcd4 | 31 | import org.eclipse.tracecompass.internal.ctf.core.event.EventDeclaration; |
a4fa4e36 | 32 | |
866e5b51 | 33 | /** |
be6df2d8 | 34 | * Representation of a particular instance of an event. |
866e5b51 | 35 | */ |
a4fa4e36 | 36 | public final class EventDefinition implements IDefinitionScope { |
866e5b51 FC |
37 | |
38 | // ------------------------------------------------------------------------ | |
39 | // Attributes | |
40 | // ------------------------------------------------------------------------ | |
41 | ||
408f954e MK |
42 | /** |
43 | * Value representing an unknown cpu number. | |
44 | * | |
45 | * @since 2.0 | |
46 | */ | |
47 | public static final int UNKNOWN_CPU = -1; | |
48 | ||
a4fa4e36 MK |
49 | /** |
50 | * A null event, can be used for testing or poison pilling | |
a4fa4e36 | 51 | */ |
6b8f960d | 52 | public static final @NonNull EventDefinition NULL_EVENT = new EventDefinition(new EventDeclaration(), UNKNOWN_CPU, -1L, null, null, null, null, null, null); |
a4fa4e36 | 53 | |
866e5b51 FC |
54 | /** |
55 | * The corresponding event declaration. | |
56 | */ | |
8e40ce4c | 57 | private final IEventDeclaration fDeclaration; |
866e5b51 FC |
58 | |
59 | /** | |
60 | * The timestamp of the current event. | |
61 | */ | |
a4fa4e36 | 62 | private final long fTimestamp; |
866e5b51 | 63 | |
94c255ef MK |
64 | private final ICompositeDefinition fEventHeaderDefinition; |
65 | ||
866e5b51 FC |
66 | /** |
67 | * The event context structure definition. | |
68 | */ | |
778bce67 | 69 | private final ICompositeDefinition fEventContext; |
a4fa4e36 | 70 | |
778bce67 | 71 | private final ICompositeDefinition fStreamContext; |
a4fa4e36 | 72 | |
778bce67 | 73 | private final ICompositeDefinition fPacketContext; |
866e5b51 FC |
74 | |
75 | /** | |
76 | * The event fields structure definition. | |
77 | */ | |
778bce67 | 78 | private final ICompositeDefinition fFields; |
866e5b51 FC |
79 | |
80 | /** | |
42f8feff | 81 | * The current cpu, could be @link {@link IPacketHeader#UNKNOWN_CPU} |
866e5b51 | 82 | */ |
408f954e | 83 | private final int fCpu; |
866e5b51 | 84 | |
6b8f960d MK |
85 | private final @NonNull Map<String, Object> fPacketAttributes; |
86 | ||
866e5b51 FC |
87 | // ------------------------------------------------------------------------ |
88 | // Constructors | |
89 | // ------------------------------------------------------------------------ | |
90 | ||
91 | /** | |
92 | * Constructs an event definition. | |
93 | * | |
94 | * @param declaration | |
be6df2d8 | 95 | * The corresponding event declaration |
408f954e MK |
96 | * @param cpu |
97 | * The cpu source of the event. You can use UNKNOWN_CPU if it is | |
98 | * not known. | |
94c255ef MK |
99 | * @param timestamp |
100 | * event timestamp | |
101 | * @param eventHeaderDefinition | |
408f954e MK |
102 | * The event header definition, can be null if there is no header |
103 | * definition | |
94c255ef MK |
104 | * @param eventContext |
105 | * The event context | |
106 | * @param packetContext | |
6b8f960d MK |
107 | * the packet context (the one with content size, not magic |
108 | * number) | |
94c255ef MK |
109 | * @param streamContext |
110 | * the stream context | |
111 | * @param fields | |
112 | * The event fields | |
6b8f960d MK |
113 | * @param packetDescriptor |
114 | * descriptor of the packet containing this event | |
6b6f22ef | 115 | * @since 2.0 |
94c255ef MK |
116 | */ |
117 | public EventDefinition(IEventDeclaration declaration, | |
408f954e | 118 | int cpu, |
94c255ef MK |
119 | long timestamp, |
120 | ICompositeDefinition eventHeaderDefinition, | |
121 | ICompositeDefinition streamContext, | |
122 | ICompositeDefinition eventContext, | |
123 | ICompositeDefinition packetContext, | |
6b8f960d MK |
124 | ICompositeDefinition fields, |
125 | @Nullable ICTFPacketDescriptor packetDescriptor) { | |
8e40ce4c | 126 | fDeclaration = declaration; |
94c255ef | 127 | fEventHeaderDefinition = eventHeaderDefinition; |
408f954e | 128 | fCpu = cpu; |
a4fa4e36 MK |
129 | fTimestamp = timestamp; |
130 | fFields = fields; | |
131 | fEventContext = eventContext; | |
132 | fPacketContext = packetContext; | |
133 | fStreamContext = streamContext; | |
6b8f960d | 134 | fPacketAttributes = packetDescriptor != null ? packetDescriptor.getAttributes() : Collections.EMPTY_MAP; |
866e5b51 FC |
135 | } |
136 | ||
137 | // ------------------------------------------------------------------------ | |
138 | // Getters/Setters/Predicates | |
139 | // ------------------------------------------------------------------------ | |
140 | ||
fbe6fa6f MK |
141 | /** |
142 | * @since 1.0 | |
143 | */ | |
866e5b51 | 144 | @Override |
fbe6fa6f | 145 | public ILexicalScope getScopePath() { |
a4fa4e36 MK |
146 | String eventName = fDeclaration.getName(); |
147 | if (eventName == null) { | |
148 | return null; | |
149 | } | |
fbe6fa6f | 150 | ILexicalScope myScope = ILexicalScope.EVENT.getChild(eventName); |
a4fa4e36 | 151 | if (myScope == null) { |
fbe6fa6f | 152 | myScope = new LexicalScope(ILexicalScope.EVENT, eventName); |
a4fa4e36 MK |
153 | } |
154 | return myScope; | |
866e5b51 FC |
155 | } |
156 | ||
9ac2eb62 MK |
157 | /** |
158 | * Gets the declaration (the form) of the data | |
159 | * | |
160 | * @return the event declaration | |
161 | */ | |
8e964be1 | 162 | public IEventDeclaration getDeclaration() { |
8e40ce4c | 163 | return fDeclaration; |
866e5b51 FC |
164 | } |
165 | ||
94c255ef MK |
166 | /** |
167 | * Get the event header | |
168 | * | |
169 | * @return the event header | |
0336f981 | 170 | * @since 1.1 |
94c255ef MK |
171 | */ |
172 | public ICompositeDefinition getEventHeader() { | |
173 | return fEventHeaderDefinition; | |
174 | } | |
175 | ||
9ac2eb62 MK |
176 | /** |
177 | * Gets the fields of a definition | |
178 | * | |
179 | * @return the fields of a definition in struct form. Can be null. | |
778bce67 | 180 | * @since 1.0 |
9ac2eb62 | 181 | */ |
778bce67 | 182 | public ICompositeDefinition getFields() { |
8e40ce4c | 183 | return fFields; |
866e5b51 FC |
184 | } |
185 | ||
9ac2eb62 | 186 | /** |
824b8985 | 187 | * Gets the context of this event without the context of the stream |
9ac2eb62 MK |
188 | * |
189 | * @return the context in struct form | |
778bce67 | 190 | * @since 1.0 |
9ac2eb62 | 191 | */ |
778bce67 | 192 | public ICompositeDefinition getEventContext() { |
a4fa4e36 | 193 | return fEventContext; |
866e5b51 FC |
194 | } |
195 | ||
824b8985 MK |
196 | /** |
197 | * Gets the context of this event within a stream | |
198 | * | |
199 | * @return the context in struct form | |
778bce67 | 200 | * @since 1.0 |
824b8985 | 201 | */ |
778bce67 | 202 | public ICompositeDefinition getContext() { |
824b8985 MK |
203 | |
204 | /* Most common case so far */ | |
a4fa4e36 MK |
205 | if (fStreamContext == null) { |
206 | return fEventContext; | |
824b8985 MK |
207 | } |
208 | ||
209 | /* streamContext is not null, but the context of the event is null */ | |
a4fa4e36 MK |
210 | if (fEventContext == null) { |
211 | return fStreamContext; | |
824b8985 MK |
212 | } |
213 | ||
a4fa4e36 MK |
214 | // TODO: cache if this is a performance issue |
215 | ||
824b8985 MK |
216 | /* The stream context and event context are assigned. */ |
217 | StructDeclaration mergedDeclaration = new StructDeclaration(1); | |
218 | ||
a4fa4e36 | 219 | List<Definition> fieldValues = new ArrayList<>(); |
824b8985 | 220 | |
a4fa4e36 | 221 | /* Add fields from the stream */ |
367e2932 | 222 | List<@NonNull String> fieldNames = fStreamContext.getFieldNames(); |
e18274f9 | 223 | for (String fieldName : fieldNames) { |
a4fa4e36 MK |
224 | Definition definition = fStreamContext.getDefinition(fieldName); |
225 | mergedDeclaration.addField(fieldName, definition.getDeclaration()); | |
a4fa4e36 | 226 | fieldValues.add(definition); |
824b8985 MK |
227 | } |
228 | ||
a4fa4e36 MK |
229 | /* |
230 | * Add fields from the event context, overwrite the stream ones if | |
231 | * needed. | |
232 | */ | |
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); | |
824b8985 | 238 | } else { |
a4fa4e36 | 239 | fieldValues.add(definition); |
824b8985 MK |
240 | } |
241 | } | |
e18274f9 | 242 | return new StructDefinition(mergedDeclaration, this, "context", //$NON-NLS-1$ |
a4fa4e36 | 243 | fieldValues.toArray(new Definition[fieldValues.size()])); |
824b8985 MK |
244 | } |
245 | ||
9ac2eb62 MK |
246 | /** |
247 | * Gets the context of packet the event is in. | |
248 | * | |
249 | * @return the packet context | |
778bce67 | 250 | * @since 1.0 |
9ac2eb62 | 251 | */ |
778bce67 | 252 | public ICompositeDefinition getPacketContext() { |
a4fa4e36 | 253 | return fPacketContext; |
866e5b51 FC |
254 | } |
255 | ||
9ac2eb62 MK |
256 | /** |
257 | * gets the CPU the event was generated by. Slightly LTTng specific | |
258 | * | |
259 | * @return The CPU the event was generated by | |
260 | */ | |
866e5b51 | 261 | public int getCPU() { |
408f954e | 262 | return fCpu; |
866e5b51 FC |
263 | } |
264 | ||
aa572e22 MK |
265 | /** |
266 | * @return the timestamp | |
267 | */ | |
268 | public long getTimestamp() { | |
8e40ce4c | 269 | return fTimestamp; |
aa572e22 MK |
270 | } |
271 | ||
6b8f960d MK |
272 | /** |
273 | * Get the packet attributes. | |
274 | * | |
275 | * @return the packet attributes, such as "device" and "timestamp_begin" | |
276 | * @since 2.0 | |
277 | */ | |
278 | public @NonNull Map<String, Object> getPacketAttributes() { | |
279 | return fPacketAttributes; | |
280 | } | |
866e5b51 FC |
281 | // ------------------------------------------------------------------------ |
282 | // Operations | |
283 | // ------------------------------------------------------------------------ | |
284 | ||
fa533f33 MK |
285 | /** |
286 | * @since 1.0 | |
287 | */ | |
866e5b51 | 288 | @Override |
fa533f33 | 289 | public IDefinition lookupDefinition(String lookupPath) { |
866e5b51 | 290 | if (lookupPath.equals("context")) { //$NON-NLS-1$ |
a4fa4e36 | 291 | return fEventContext; |
866e5b51 | 292 | } else if (lookupPath.equals("fields")) { //$NON-NLS-1$ |
8e40ce4c | 293 | return fFields; |
866e5b51 FC |
294 | } else { |
295 | return null; | |
296 | } | |
297 | } | |
298 | ||
299 | @Override | |
300 | public String toString() { | |
a4fa4e36 | 301 | Iterable<String> list; |
07002e0a MK |
302 | StringBuilder retString = new StringBuilder(); |
303 | final String cr = System.getProperty("line.separator");//$NON-NLS-1$ | |
866e5b51 | 304 | |
e18274f9 MK |
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$ | |
866e5b51 | 307 | |
a4fa4e36 | 308 | if (fEventContext != null) { |
8e0c9d81 | 309 | list = fEventContext.getFieldNames(); |
866e5b51 FC |
310 | |
311 | for (String field : list) { | |
e18274f9 | 312 | retString.append(field).append(" : ").append(fEventContext.getDefinition(field).toString()).append(cr); //$NON-NLS-1$ |
866e5b51 FC |
313 | } |
314 | } | |
315 | ||
8e40ce4c | 316 | if (fFields != null) { |
8e0c9d81 | 317 | list = fFields.getFieldNames(); |
866e5b51 FC |
318 | |
319 | for (String field : list) { | |
e18274f9 | 320 | retString.append(field).append(" : ").append(fFields.getDefinition(field).toString()).append(cr); //$NON-NLS-1$ |
866e5b51 FC |
321 | } |
322 | } | |
323 | ||
07002e0a | 324 | return retString.toString(); |
866e5b51 FC |
325 | } |
326 | ||
327 | } |