Commit | Line | Data |
---|---|---|
a3fc8213 | 1 | /******************************************************************************* |
ed902a2b | 2 | * Copyright (c) 2011, 2015 Ericsson |
a3fc8213 AM |
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 | * | |
58f3bc52 AM |
9 | * Contributors: |
10 | * Alexandre Montplaisir - Initial API and implementation | |
f47ed727 | 11 | * Bernd Hufmann - Updated for source and model lookup interfaces |
a3fc8213 AM |
12 | *******************************************************************************/ |
13 | ||
9722e5d7 | 14 | package org.eclipse.tracecompass.tmf.ctf.core.event; |
a3fc8213 | 15 | |
fafdd006 AM |
16 | import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull; |
17 | ||
a4fa4e36 | 18 | import java.util.ArrayList; |
8e964be1 | 19 | import java.util.HashSet; |
a4fa4e36 | 20 | import java.util.List; |
8e964be1 | 21 | import java.util.Set; |
a3fc8213 | 22 | |
367e2932 | 23 | import org.eclipse.jdt.annotation.NonNull; |
ed8c3fb6 AM |
24 | import org.eclipse.jdt.annotation.NonNullByDefault; |
25 | import org.eclipse.jdt.annotation.Nullable; | |
f357bcd4 AM |
26 | import org.eclipse.tracecompass.ctf.core.event.EventDefinition; |
27 | import org.eclipse.tracecompass.ctf.core.event.IEventDeclaration; | |
28 | import org.eclipse.tracecompass.ctf.core.event.types.ICompositeDefinition; | |
29 | import org.eclipse.tracecompass.ctf.core.event.types.IDefinition; | |
2bdf0193 AM |
30 | import org.eclipse.tracecompass.tmf.core.event.ITmfCustomAttributes; |
31 | import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; | |
32 | import org.eclipse.tracecompass.tmf.core.event.ITmfEventType; | |
33 | import org.eclipse.tracecompass.tmf.core.event.TmfEvent; | |
34 | import org.eclipse.tracecompass.tmf.core.event.TmfEventField; | |
35 | import org.eclipse.tracecompass.tmf.core.event.lookup.ITmfModelLookup; | |
da707390 | 36 | import org.eclipse.tracecompass.tmf.core.timestamp.TmfNanoTimestamp; |
2bdf0193 | 37 | import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; |
9722e5d7 | 38 | import org.eclipse.tracecompass.tmf.ctf.core.CtfConstants; |
9722e5d7 | 39 | import org.eclipse.tracecompass.tmf.ctf.core.trace.CtfTmfTrace; |
a3fc8213 AM |
40 | |
41 | /** | |
f332660b MK |
42 | * A wrapper class around CTF's Event Definition/Declaration that maps all types |
43 | * of Declaration to native Java types. | |
6256d8ad | 44 | * |
d09f973b | 45 | * @author Alexandre Montplaisir |
a3fc8213 | 46 | */ |
ed8c3fb6 | 47 | @NonNullByDefault |
c26d0fe0 | 48 | public class CtfTmfEvent extends TmfEvent |
73511e67 | 49 | implements ITmfModelLookup, ITmfCustomAttributes { |
a3fc8213 AM |
50 | |
51 | // ------------------------------------------------------------------------ | |
52 | // Constants | |
53 | // ------------------------------------------------------------------------ | |
54 | ||
a3fc8213 | 55 | private static final String EMPTY_CTF_EVENT_NAME = "Empty CTF event"; //$NON-NLS-1$ |
aa572e22 | 56 | |
ed8c3fb6 AM |
57 | // ------------------------------------------------------------------------ |
58 | // Support attributes | |
59 | // Not part of this event's "definition", but used to populate lazy-loaded | |
60 | // fields. | |
61 | // ------------------------------------------------------------------------ | |
62 | ||
63 | private final @Nullable IEventDeclaration fEventDeclaration; | |
64 | private final EventDefinition fEvent; | |
65 | ||
a3fc8213 AM |
66 | // ------------------------------------------------------------------------ |
67 | // Attributes | |
68 | // ------------------------------------------------------------------------ | |
69 | ||
ed8c3fb6 AM |
70 | /* Fields that are introduced by and part of this event's definition. */ |
71 | private final int fSourceCpu; | |
72 | private final String fChannel; | |
73 | ||
74 | /** Field to override {@link TmfEvent#getName()}, to bypass the type-getting */ | |
ed6baa55 | 75 | private final String fEventName; |
e1de2fd4 AM |
76 | |
77 | /** Lazy-loaded field containing the event's payload */ | |
ed8c3fb6 | 78 | private transient @Nullable ITmfEventField fContent; |
a3fc8213 | 79 | |
ed8c3fb6 AM |
80 | /** Lazy-loaded field for the type, overriding TmfEvent's field */ |
81 | private transient @Nullable CtfTmfEventType fEventType; | |
7903ea35 | 82 | |
a3fc8213 AM |
83 | // ------------------------------------------------------------------------ |
84 | // Constructors | |
85 | // ------------------------------------------------------------------------ | |
86 | ||
87 | /** | |
8e376474 AM |
88 | * Constructor, used by {@link CtfTmfEventFactory#createEvent}. |
89 | * | |
90 | * Only subclasses should call this. It is imperative that the subclass also | |
91 | * has a constructor with the EXACT same parameter signature, because the | |
92 | * factory will look for a constructor with the same arguments. | |
93 | * | |
94 | * @param trace | |
95 | * The trace to which this event belongs | |
96 | * @param rank | |
97 | * The rank of the event | |
98 | * @param timestamp | |
99 | * The timestamp | |
100 | * @param channel | |
101 | * The CTF channel of this event | |
102 | * @param cpu | |
103 | * The event's CPU | |
104 | * @param declaration | |
105 | * The event declaration | |
106 | * @param eventDefinition | |
107 | * The event definition | |
108 | * @since 2.0 | |
a3fc8213 | 109 | */ |
8e376474 AM |
110 | protected CtfTmfEvent(CtfTmfTrace trace, |
111 | long rank, | |
112 | TmfNanoTimestamp timestamp, | |
113 | String channel, | |
114 | int cpu, | |
115 | IEventDeclaration declaration, | |
116 | EventDefinition eventDefinition) { | |
6cfa0200 AM |
117 | super(trace, |
118 | rank, | |
119 | timestamp, | |
e1de2fd4 AM |
120 | /* |
121 | * Event type. We don't use TmfEvent's field here, we | |
122 | * re-implement getType(). | |
123 | */ | |
124 | null, | |
125 | /* | |
126 | * Content handled with a lazy-loaded field re-implemented in | |
127 | * getContent(). | |
128 | */ | |
7903ea35 | 129 | null); |
6cfa0200 | 130 | |
a4fa4e36 | 131 | fEventDeclaration = declaration; |
ed8c3fb6 AM |
132 | fSourceCpu = cpu; |
133 | fEventName = checkNotNull(declaration.getName()); | |
a4fa4e36 | 134 | fEvent = eventDefinition; |
ed8c3fb6 | 135 | fChannel = channel; |
a3fc8213 AM |
136 | } |
137 | ||
138 | /** | |
b8a6e46d | 139 | * Inner constructor to create "null" events. Don't use this directly in |
ca5b04ad GB |
140 | * normal usage, use {@link CtfTmfEventFactory#getNullEvent(CtfTmfTrace)} to |
141 | * get an instance of an empty event. | |
c26afeaf | 142 | * |
ca5b04ad GB |
143 | * There is no need to give higher visibility to this method than package |
144 | * visible. | |
145 | * | |
146 | * @param trace | |
147 | * The trace associated with this event | |
a3fc8213 | 148 | */ |
ca5b04ad GB |
149 | CtfTmfEvent(CtfTmfTrace trace) { |
150 | super(trace, | |
6cfa0200 | 151 | ITmfContext.UNKNOWN_RANK, |
da707390 | 152 | new TmfNanoTimestamp(-1), |
6cfa0200 | 153 | null, |
e1de2fd4 | 154 | new TmfEventField("", null, new CtfTmfEventField[0])); //$NON-NLS-1$ |
ed8c3fb6 | 155 | fSourceCpu = -1; |
ed6baa55 | 156 | fEventName = EMPTY_CTF_EVENT_NAME; |
a4fa4e36 MK |
157 | fEventDeclaration = null; |
158 | fEvent = EventDefinition.NULL_EVENT; | |
ed8c3fb6 | 159 | fChannel = ""; //$NON-NLS-1$ |
a3fc8213 AM |
160 | } |
161 | ||
ca5b04ad GB |
162 | /** |
163 | * Default constructor. Do not use directly, but it needs to be present | |
164 | * because it's used in extension points, and the framework will use this | |
165 | * constructor to get the class type. | |
ed8c3fb6 AM |
166 | * |
167 | * @deprecated Should not be called by normal code | |
ca5b04ad | 168 | */ |
ed8c3fb6 | 169 | @Deprecated |
ca5b04ad | 170 | public CtfTmfEvent() { |
ed8c3fb6 AM |
171 | super(); |
172 | fSourceCpu = -1; | |
173 | fEventName = EMPTY_CTF_EVENT_NAME; | |
174 | fEventDeclaration = null; | |
175 | fEvent = EventDefinition.NULL_EVENT; | |
176 | fChannel = ""; //$NON-NLS-1$ | |
ca5b04ad GB |
177 | } |
178 | ||
a3fc8213 AM |
179 | // ------------------------------------------------------------------------ |
180 | // Getters/Setters/Predicates | |
181 | // ------------------------------------------------------------------------ | |
182 | ||
a3fc8213 AM |
183 | /** |
184 | * Gets the cpu core the event was recorded on. | |
185 | * | |
58f3bc52 AM |
186 | * @return The cpu id for a given source. In lttng it's from CPUINFO |
187 | */ | |
b0c7c92d | 188 | public int getCPU() { |
ed8c3fb6 | 189 | return fSourceCpu; |
a3fc8213 AM |
190 | } |
191 | ||
192 | /** | |
ed8c3fb6 | 193 | * Return the CTF trace's channel from which this event originates. |
a3fc8213 | 194 | * |
ed8c3fb6 AM |
195 | * @return The event's channel |
196 | * @since 2.0 | |
58f3bc52 | 197 | */ |
ed8c3fb6 AM |
198 | public String getChannel() { |
199 | return fChannel; | |
a3fc8213 AM |
200 | } |
201 | ||
b0c7c92d AM |
202 | /** |
203 | * Return this event's reference. | |
204 | * | |
205 | * @return The event's reference | |
206 | * @deprecated This method was replaced by {@link #getChannel()}. | |
207 | */ | |
208 | @Deprecated | |
209 | public String getReference() { | |
210 | return getChannel(); | |
211 | } | |
212 | ||
ed8c3fb6 AM |
213 | // ------------------------------------------------------------------------ |
214 | // TmfEvent | |
215 | // ------------------------------------------------------------------------ | |
e1de2fd4 | 216 | |
a3fc8213 AM |
217 | @Override |
218 | public CtfTmfTrace getTrace() { | |
f332660b MK |
219 | /* |
220 | * Should be of the right type, since we take a CtfTmfTrace at the | |
221 | * constructor | |
222 | */ | |
6cfa0200 | 223 | return (CtfTmfTrace) super.getTrace(); |
a3fc8213 AM |
224 | } |
225 | ||
226 | @Override | |
ed8c3fb6 AM |
227 | public synchronized ITmfEventType getType() { |
228 | CtfTmfEventType type = fEventType; | |
229 | if (type == null) { | |
230 | type = new CtfTmfEventType(fEventName, getContent()); | |
7903ea35 MK |
231 | |
232 | /* | |
233 | * Register the event type in the owning trace, but only if there is | |
234 | * one | |
235 | */ | |
ed8c3fb6 AM |
236 | getTrace().registerEventType(type); |
237 | fEventType = type; | |
7903ea35 | 238 | } |
ed8c3fb6 | 239 | return type; |
a3fc8213 AM |
240 | } |
241 | ||
5c3d072d MK |
242 | @Override |
243 | public String getName() { | |
244 | return fEventName; | |
245 | } | |
246 | ||
ed8c3fb6 AM |
247 | @Override |
248 | public synchronized ITmfEventField getContent() { | |
249 | ITmfEventField content = fContent; | |
250 | if (content == null) { | |
251 | content = new TmfEventField( | |
252 | ITmfEventField.ROOT_FIELD_ID, null, parseFields(fEvent)); | |
253 | fContent = content; | |
254 | } | |
255 | return content; | |
256 | } | |
257 | ||
258 | /** | |
259 | * Extract the field information from the structDefinition haze-inducing | |
260 | * mess, and put them into something ITmfEventField can cope with. | |
261 | */ | |
262 | private static CtfTmfEventField[] parseFields(EventDefinition eventDef) { | |
263 | List<CtfTmfEventField> fields = new ArrayList<>(); | |
264 | ||
265 | ICompositeDefinition structFields = eventDef.getFields(); | |
266 | if (structFields != null) { | |
267 | if (structFields.getFieldNames() != null) { | |
268 | for (String curFieldName : structFields.getFieldNames()) { | |
269 | String fn = checkNotNull(curFieldName); | |
270 | fields.add(CtfTmfEventField.parseField((IDefinition) structFields.getDefinition(fn), fn)); | |
271 | } | |
272 | } | |
273 | } | |
274 | /* Add context information as CtfTmfEventField */ | |
275 | ICompositeDefinition structContext = eventDef.getContext(); | |
276 | if (structContext != null) { | |
277 | for (String contextName : structContext.getFieldNames()) { | |
278 | /* Prefix field name */ | |
279 | String curContextName = CtfConstants.CONTEXT_FIELD_PREFIX + contextName; | |
280 | fields.add(CtfTmfEventField.parseField((IDefinition) structContext.getDefinition(contextName), curContextName)); | |
281 | } | |
282 | } | |
283 | ||
367e2932 | 284 | return checkNotNull(fields.toArray(new @NonNull CtfTmfEventField[fields.size()])); |
ed8c3fb6 AM |
285 | } |
286 | ||
287 | // ------------------------------------------------------------------------ | |
288 | // ITmfCustomAttributes | |
289 | // ------------------------------------------------------------------------ | |
290 | ||
860b76d4 | 291 | @Override |
8e964be1 | 292 | public Set<String> listCustomAttributes() { |
ed8c3fb6 AM |
293 | IEventDeclaration declaration = fEventDeclaration; |
294 | if (declaration == null) { | |
a4524c1b | 295 | return new HashSet<>(); |
8e964be1 | 296 | } |
aa353506 | 297 | return declaration.getCustomAttributes(); |
8e964be1 MK |
298 | } |
299 | ||
860b76d4 | 300 | @Override |
ed8c3fb6 AM |
301 | public @Nullable String getCustomAttribute(@Nullable String name) { |
302 | IEventDeclaration declaration = fEventDeclaration; | |
303 | if (declaration == null) { | |
8e964be1 MK |
304 | return null; |
305 | } | |
ed8c3fb6 | 306 | return declaration.getCustomAttribute(name); |
8e964be1 MK |
307 | } |
308 | ||
f47ed727 | 309 | @Override |
ed8c3fb6 | 310 | public @Nullable String getModelUri() { |
f47ed727 BH |
311 | return getCustomAttribute(CtfConstants.MODEL_URI_KEY); |
312 | } | |
313 | ||
ed8c3fb6 AM |
314 | // ------------------------------------------------------------------------ |
315 | // Object | |
316 | // ------------------------------------------------------------------------ | |
317 | ||
a4fa4e36 | 318 | @Override |
ed8c3fb6 AM |
319 | public int hashCode() { |
320 | final int prime = 31; | |
321 | int result = super.hashCode(); | |
b0c7c92d | 322 | result = prime * result + getCPU(); |
ed8c3fb6 AM |
323 | result = prime * result + getChannel().hashCode(); |
324 | return result; | |
a4fa4e36 MK |
325 | } |
326 | ||
ed8c3fb6 AM |
327 | @Override |
328 | public boolean equals(@Nullable Object obj) { | |
329 | if (!super.equals(obj)) { | |
330 | return false; | |
a4fa4e36 | 331 | } |
ed8c3fb6 AM |
332 | /* super.equals() checks that the classes are the same */ |
333 | CtfTmfEvent other = checkNotNull((CtfTmfEvent) obj); | |
b0c7c92d | 334 | if (getCPU() != other.getCPU()) { |
ed8c3fb6 | 335 | return false; |
a4fa4e36 | 336 | } |
ed8c3fb6 AM |
337 | if (!getChannel().equals(other.getChannel())) { |
338 | return false; | |
339 | } | |
340 | return true; | |
a4fa4e36 MK |
341 | } |
342 | ||
a3fc8213 | 343 | } |