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