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 | |
a4fa4e36 | 16 | import java.util.ArrayList; |
8e964be1 | 17 | import java.util.HashSet; |
a4fa4e36 | 18 | import java.util.List; |
8e964be1 | 19 | import java.util.Set; |
a3fc8213 | 20 | |
a4fa4e36 | 21 | import org.eclipse.jdt.annotation.NonNull; |
f357bcd4 AM |
22 | import org.eclipse.tracecompass.ctf.core.event.CTFCallsite; |
23 | import org.eclipse.tracecompass.ctf.core.event.EventDefinition; | |
24 | import org.eclipse.tracecompass.ctf.core.event.IEventDeclaration; | |
25 | import org.eclipse.tracecompass.ctf.core.event.types.ICompositeDefinition; | |
26 | import org.eclipse.tracecompass.ctf.core.event.types.IDefinition; | |
27 | import org.eclipse.tracecompass.ctf.core.trace.CTFTrace; | |
2bdf0193 AM |
28 | import org.eclipse.tracecompass.tmf.core.event.ITmfCustomAttributes; |
29 | import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; | |
30 | import org.eclipse.tracecompass.tmf.core.event.ITmfEventType; | |
31 | import org.eclipse.tracecompass.tmf.core.event.TmfEvent; | |
32 | import org.eclipse.tracecompass.tmf.core.event.TmfEventField; | |
33 | import org.eclipse.tracecompass.tmf.core.event.lookup.ITmfModelLookup; | |
34 | import org.eclipse.tracecompass.tmf.core.event.lookup.ITmfSourceLookup; | |
35 | import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; | |
9722e5d7 AM |
36 | import org.eclipse.tracecompass.tmf.ctf.core.CtfConstants; |
37 | import org.eclipse.tracecompass.tmf.ctf.core.event.lookup.CtfTmfCallsite; | |
38 | import org.eclipse.tracecompass.tmf.ctf.core.timestamp.CtfTmfTimestamp; | |
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 FC |
45 | * @version 1.0 |
46 | * @author Alexandre Montplaisir | |
93bfd50a | 47 | * @since 2.0 |
a3fc8213 | 48 | */ |
c26d0fe0 | 49 | public class CtfTmfEvent extends TmfEvent |
860b76d4 | 50 | implements ITmfSourceLookup, ITmfModelLookup, ITmfCustomAttributes { |
a3fc8213 AM |
51 | |
52 | // ------------------------------------------------------------------------ | |
53 | // Constants | |
54 | // ------------------------------------------------------------------------ | |
55 | ||
a3fc8213 | 56 | private static final String EMPTY_CTF_EVENT_NAME = "Empty CTF event"; //$NON-NLS-1$ |
aa572e22 | 57 | |
a3fc8213 AM |
58 | // ------------------------------------------------------------------------ |
59 | // Attributes | |
60 | // ------------------------------------------------------------------------ | |
61 | ||
ed6baa55 MK |
62 | private final int fSourceCPU; |
63 | private final long fTypeId; | |
64 | private final String fEventName; | |
a4fa4e36 | 65 | private final IEventDeclaration fEventDeclaration; |
e1de2fd4 | 66 | private final @NonNull EventDefinition fEvent; |
e1de2fd4 AM |
67 | private final String fReference; |
68 | ||
69 | /** Lazy-loaded field containing the event's payload */ | |
a4fa4e36 | 70 | private ITmfEventField fContent; |
a3fc8213 | 71 | |
7903ea35 MK |
72 | private CtfTmfEventType fCtfTmfEventType; |
73 | ||
a3fc8213 AM |
74 | // ------------------------------------------------------------------------ |
75 | // Constructors | |
76 | // ------------------------------------------------------------------------ | |
77 | ||
78 | /** | |
6cfa0200 | 79 | * Constructor used by {@link CtfTmfEventFactory#createEvent} |
a3fc8213 | 80 | */ |
6cfa0200 | 81 | CtfTmfEvent(CtfTmfTrace trace, long rank, CtfTmfTimestamp timestamp, |
a4fa4e36 | 82 | String fileName, int cpu, IEventDeclaration declaration, @NonNull EventDefinition eventDefinition) { |
6cfa0200 AM |
83 | super(trace, |
84 | rank, | |
85 | timestamp, | |
e1de2fd4 AM |
86 | /* |
87 | * Event type. We don't use TmfEvent's field here, we | |
88 | * re-implement getType(). | |
89 | */ | |
90 | null, | |
91 | /* | |
92 | * Content handled with a lazy-loaded field re-implemented in | |
93 | * getContent(). | |
94 | */ | |
7903ea35 | 95 | null); |
6cfa0200 | 96 | |
a4fa4e36 | 97 | fEventDeclaration = declaration; |
ed6baa55 | 98 | fSourceCPU = cpu; |
5f715709 | 99 | fTypeId = declaration.getId().longValue(); |
ed6baa55 | 100 | fEventName = declaration.getName(); |
a4fa4e36 | 101 | fEvent = eventDefinition; |
e1de2fd4 | 102 | fReference = fileName; |
a3fc8213 AM |
103 | } |
104 | ||
105 | /** | |
b8a6e46d | 106 | * Inner constructor to create "null" events. Don't use this directly in |
ca5b04ad GB |
107 | * normal usage, use {@link CtfTmfEventFactory#getNullEvent(CtfTmfTrace)} to |
108 | * get an instance of an empty event. | |
c26afeaf | 109 | * |
ca5b04ad GB |
110 | * There is no need to give higher visibility to this method than package |
111 | * visible. | |
112 | * | |
113 | * @param trace | |
114 | * The trace associated with this event | |
a3fc8213 | 115 | */ |
ca5b04ad GB |
116 | CtfTmfEvent(CtfTmfTrace trace) { |
117 | super(trace, | |
6cfa0200 AM |
118 | ITmfContext.UNKNOWN_RANK, |
119 | new CtfTmfTimestamp(-1), | |
120 | null, | |
e1de2fd4 | 121 | new TmfEventField("", null, new CtfTmfEventField[0])); //$NON-NLS-1$ |
ed6baa55 MK |
122 | fSourceCPU = -1; |
123 | fTypeId = -1; | |
124 | fEventName = EMPTY_CTF_EVENT_NAME; | |
a4fa4e36 MK |
125 | fEventDeclaration = null; |
126 | fEvent = EventDefinition.NULL_EVENT; | |
e1de2fd4 | 127 | fReference = null; |
a3fc8213 AM |
128 | } |
129 | ||
ca5b04ad GB |
130 | /** |
131 | * Default constructor. Do not use directly, but it needs to be present | |
132 | * because it's used in extension points, and the framework will use this | |
133 | * constructor to get the class type. | |
134 | */ | |
135 | public CtfTmfEvent() { | |
136 | this(null); | |
137 | } | |
138 | ||
a3fc8213 AM |
139 | // ------------------------------------------------------------------------ |
140 | // Getters/Setters/Predicates | |
141 | // ------------------------------------------------------------------------ | |
142 | ||
a3fc8213 AM |
143 | /** |
144 | * Gets the cpu core the event was recorded on. | |
145 | * | |
58f3bc52 AM |
146 | * @return The cpu id for a given source. In lttng it's from CPUINFO |
147 | */ | |
a3fc8213 | 148 | public int getCPU() { |
ed6baa55 | 149 | return fSourceCPU; |
a3fc8213 AM |
150 | } |
151 | ||
152 | /** | |
58f3bc52 | 153 | * Return this event's ID, according to the trace's metadata. |
a3fc8213 | 154 | * |
58f3bc52 AM |
155 | * Watch out, this ID is not constant from one trace to another for the same |
156 | * event types! Use "getEventName()" for a constant reference. | |
157 | * | |
158 | * @return The event ID | |
159 | */ | |
a3fc8213 | 160 | public long getID() { |
ed6baa55 | 161 | return fTypeId; |
a3fc8213 AM |
162 | } |
163 | ||
e1de2fd4 AM |
164 | /** |
165 | * Return this event's reference | |
166 | * | |
167 | * @return The event's reference | |
168 | */ | |
169 | public String getReference() { | |
170 | return fReference; | |
171 | } | |
172 | ||
a3fc8213 AM |
173 | @Override |
174 | public CtfTmfTrace getTrace() { | |
f332660b MK |
175 | /* |
176 | * Should be of the right type, since we take a CtfTmfTrace at the | |
177 | * constructor | |
178 | */ | |
6cfa0200 | 179 | return (CtfTmfTrace) super.getTrace(); |
a3fc8213 AM |
180 | } |
181 | ||
182 | @Override | |
183 | public ITmfEventType getType() { | |
7903ea35 MK |
184 | if (fCtfTmfEventType == null) { |
185 | fCtfTmfEventType = new CtfTmfEventType(fEventName, getContent()); | |
186 | ||
187 | /* | |
188 | * Register the event type in the owning trace, but only if there is | |
189 | * one | |
190 | */ | |
191 | getTrace().registerEventType(fCtfTmfEventType); | |
192 | } | |
193 | return fCtfTmfEventType; | |
a3fc8213 AM |
194 | } |
195 | ||
8e964be1 | 196 | /** |
8e964be1 MK |
197 | * @since 2.0 |
198 | */ | |
860b76d4 | 199 | @Override |
8e964be1 | 200 | public Set<String> listCustomAttributes() { |
a4fa4e36 | 201 | if (fEventDeclaration == null) { |
a4524c1b | 202 | return new HashSet<>(); |
8e964be1 | 203 | } |
a4fa4e36 | 204 | return fEventDeclaration.getCustomAttributes(); |
8e964be1 MK |
205 | } |
206 | ||
207 | /** | |
8e964be1 MK |
208 | * @since 2.0 |
209 | */ | |
860b76d4 | 210 | @Override |
8e964be1 | 211 | public String getCustomAttribute(String name) { |
a4fa4e36 | 212 | if (fEventDeclaration == null) { |
8e964be1 MK |
213 | return null; |
214 | } | |
a4fa4e36 | 215 | return fEventDeclaration.getCustomAttribute(name); |
8e964be1 MK |
216 | } |
217 | ||
60fb38b8 | 218 | /** |
f47ed727 | 219 | * Get the call site for this event. |
60fb38b8 | 220 | * |
f47ed727 | 221 | * @return the call site information, or null if there is none |
60fb38b8 PT |
222 | * @since 2.0 |
223 | */ | |
f47ed727 | 224 | @Override |
60fb38b8 PT |
225 | public CtfTmfCallsite getCallsite() { |
226 | CTFCallsite callsite = null; | |
f332660b | 227 | CtfTmfTrace trace = getTrace(); |
f332660b MK |
228 | CTFTrace ctfTrace = trace.getCTFTrace(); |
229 | /* Should not happen, but it is a good check */ | |
230 | if (ctfTrace == null) { | |
60fb38b8 PT |
231 | return null; |
232 | } | |
233 | if (getContent() != null) { | |
234 | ITmfEventField ipField = getContent().getField(CtfConstants.CONTEXT_FIELD_PREFIX + CtfConstants.IP_KEY); | |
235 | if (ipField != null && ipField.getValue() instanceof Long) { | |
236 | long ip = (Long) ipField.getValue(); | |
ed6baa55 | 237 | callsite = ctfTrace.getCallsite(fEventName, ip); |
60fb38b8 PT |
238 | } |
239 | } | |
240 | if (callsite == null) { | |
ed6baa55 | 241 | callsite = ctfTrace.getCallsite(fEventName); |
60fb38b8 PT |
242 | } |
243 | if (callsite != null) { | |
244 | return new CtfTmfCallsite(callsite); | |
245 | } | |
246 | return null; | |
247 | } | |
248 | ||
f47ed727 BH |
249 | /** |
250 | * @since 2.0 | |
251 | */ | |
252 | @Override | |
253 | public String getModelUri() { | |
254 | return getCustomAttribute(CtfConstants.MODEL_URI_KEY); | |
255 | } | |
256 | ||
a4fa4e36 MK |
257 | @Override |
258 | public synchronized ITmfEventField getContent() { | |
259 | if (fContent == null) { | |
260 | fContent = new TmfEventField( | |
261 | ITmfEventField.ROOT_FIELD_ID, null, parseFields(fEvent)); | |
262 | } | |
263 | return fContent; | |
264 | } | |
265 | ||
266 | /** | |
267 | * Extract the field information from the structDefinition haze-inducing | |
268 | * mess, and put them into something ITmfEventField can cope with. | |
269 | */ | |
270 | private static CtfTmfEventField[] parseFields(@NonNull EventDefinition eventDef) { | |
271 | List<CtfTmfEventField> fields = new ArrayList<>(); | |
272 | ||
009883d7 | 273 | ICompositeDefinition structFields = eventDef.getFields(); |
a4fa4e36 MK |
274 | if (structFields != null) { |
275 | if (structFields.getFieldNames() != null) { | |
276 | for (String curFieldName : structFields.getFieldNames()) { | |
5f715709 | 277 | fields.add(CtfTmfEventField.parseField((IDefinition) structFields.getDefinition(curFieldName), curFieldName)); |
a4fa4e36 MK |
278 | } |
279 | } | |
280 | } | |
281 | /* Add context information as CtfTmfEventField */ | |
009883d7 | 282 | ICompositeDefinition structContext = eventDef.getContext(); |
a4fa4e36 MK |
283 | if (structContext != null) { |
284 | for (String contextName : structContext.getFieldNames()) { | |
285 | /* Prefix field name */ | |
286 | String curContextName = CtfConstants.CONTEXT_FIELD_PREFIX + contextName; | |
5f715709 | 287 | fields.add(CtfTmfEventField.parseField((IDefinition) structContext.getDefinition(contextName), curContextName)); |
a4fa4e36 MK |
288 | } |
289 | } | |
290 | ||
291 | return fields.toArray(new CtfTmfEventField[fields.size()]); | |
292 | } | |
293 | ||
a3fc8213 | 294 | } |