1 /*******************************************************************************
2 * Copyright (c) 2011-2013 Ericsson
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
10 * Alexandre Montplaisir - Initial API and implementation
11 *******************************************************************************/
13 package org
.eclipse
.linuxtools
.tmf
.core
.ctfadaptor
;
15 import java
.util
.ArrayList
;
16 import java
.util
.HashMap
;
17 import java
.util
.HashSet
;
18 import java
.util
.Iterator
;
19 import java
.util
.List
;
20 import java
.util
.Map
.Entry
;
23 import org
.eclipse
.core
.runtime
.IAdaptable
;
24 import org
.eclipse
.linuxtools
.ctf
.core
.event
.CTFCallsite
;
25 import org
.eclipse
.linuxtools
.ctf
.core
.event
.EventDefinition
;
26 import org
.eclipse
.linuxtools
.ctf
.core
.event
.IEventDeclaration
;
27 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.Definition
;
28 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.IntegerDefinition
;
29 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.StructDefinition
;
30 import org
.eclipse
.linuxtools
.tmf
.core
.event
.ITmfEvent
;
31 import org
.eclipse
.linuxtools
.tmf
.core
.event
.ITmfEventField
;
32 import org
.eclipse
.linuxtools
.tmf
.core
.event
.ITmfEventType
;
33 import org
.eclipse
.linuxtools
.tmf
.core
.event
.ITmfTimestamp
;
34 import org
.eclipse
.linuxtools
.tmf
.core
.event
.TmfEventField
;
35 import org
.eclipse
.linuxtools
.tmf
.core
.event
.TmfEventPropertySource
;
36 import org
.eclipse
.ui
.views
.properties
.IPropertySource
;
39 * A wrapper class around CTF's Event Definition/Declaration that maps all
40 * types of Declaration to native Java types.
43 * @author Alexandre Montplaisir
46 public final class CtfTmfEvent
implements ITmfEvent
, IAdaptable
, Cloneable
{
48 // ------------------------------------------------------------------------
50 // ------------------------------------------------------------------------
52 private static final String NO_STREAM
= "No stream"; //$NON-NLS-1$
53 private static final String EMPTY_CTF_EVENT_NAME
= "Empty CTF event"; //$NON-NLS-1$
55 /** Prefix for Context information stored as CtfTmfEventfield */
56 private static final String CONTEXT_FIELD_PREFIX
= "context."; //$NON-NLS-1$
58 // ------------------------------------------------------------------------
60 // ------------------------------------------------------------------------
62 private final CtfTmfTrace fTrace
;
63 private final ITmfTimestamp fTimestamp
;
64 private final int sourceCPU
;
65 private final long typeId
;
66 private final String eventName
;
67 private final String fileName
;
69 private final TmfEventField fContent
;
70 private final IEventDeclaration fDeclaration
;
72 // ------------------------------------------------------------------------
74 // ------------------------------------------------------------------------
77 * Usual CTFEvent constructor, where we read an event from the trace (via
78 * the StreamInputReader).
81 * CTF EventDefinition object corresponding to this trace event
83 * The path to the trace file
85 * The trace from which this event originates
87 public CtfTmfEvent(EventDefinition eventDef
, String fileName
,
88 CtfTmfTrace originTrace
) {
89 this.fTrace
= originTrace
;
91 if (eventDef
== null) {
92 this.fTimestamp
= new CtfTmfTimestamp(-1);
95 this.fileName
= NO_STREAM
;
96 this.eventName
= EMPTY_CTF_EVENT_NAME
;
98 this.fDeclaration
= null;
102 /* Read the base event info */
103 long ts
= this.getTrace().getCTFTrace().timestampCyclesToNanos(eventDef
.getTimestamp());
104 this.fTimestamp
= new CtfTmfTimestamp(ts
);
105 this.sourceCPU
= eventDef
.getCPU();
106 this.typeId
= eventDef
.getDeclaration().getId();
107 this.eventName
= eventDef
.getDeclaration().getName();
108 this.fileName
= fileName
;
110 /* Read the fields */
111 this.fContent
= new TmfEventField(ITmfEventField
.ROOT_FIELD_ID
, parseFields(eventDef
));
113 /* Keep a reference to this event's CTF declaration */
114 this.fDeclaration
= eventDef
.getDeclaration();
118 * Extract the field information from the structDefinition haze-inducing
119 * mess, and put them into something ITmfEventField can cope with.
121 private CtfTmfEventField
[] parseFields(EventDefinition eventDef
) {
122 List
<CtfTmfEventField
> fields
= new ArrayList
<CtfTmfEventField
>();
124 StructDefinition structFields
= eventDef
.getFields();
125 HashMap
<String
, Definition
> definitions
= structFields
.getDefinitions();
126 String curFieldName
= null;
127 Definition curFieldDef
;
128 CtfTmfEventField curField
;
129 Iterator
<Entry
<String
, Definition
>> it
= definitions
.entrySet().iterator();
130 while(it
.hasNext()) {
131 Entry
<String
, Definition
> entry
= it
.next();
132 curFieldName
= entry
.getKey();
133 curFieldDef
= entry
.getValue();
134 curField
= CtfTmfEventField
.parseField(curFieldDef
, curFieldName
);
135 fields
.add(curField
);
138 /* Add context information as CtfTmfEventField */
140 StructDefinition structContext
= eventDef
.getContext();
141 if (structContext
!= null) {
142 definitions
= structContext
.getDefinitions();
143 String curContextName
;
144 Definition curContextDef
;
145 CtfTmfEventField curContext
;
146 it
= definitions
.entrySet().iterator();
147 while(it
.hasNext()) {
148 Entry
<String
, Definition
> entry
= it
.next();
149 /* This is to get the instruction pointer if available */
150 if (entry
.getKey().equals("_ip") && //$NON-NLS-1$
151 (entry
.getValue() instanceof IntegerDefinition
)) {
152 ip
= ((IntegerDefinition
) entry
.getValue()).getValue();
154 /* Prefix field name to */
155 curContextName
= CONTEXT_FIELD_PREFIX
+ entry
.getKey();
156 curContextDef
= entry
.getValue();
157 curContext
= CtfTmfEventField
.parseField(curContextDef
, curContextName
);
158 fields
.add(curContext
);
162 final String name
= eventDef
.getDeclaration().getName();
163 List
<CTFCallsite
> eventList
= fTrace
.getCTFTrace().getCallsiteCandidates(name
);
164 if (!eventList
.isEmpty()) {
165 final String callsite
= "callsite"; //$NON-NLS-1$
166 if (eventList
.size() == 1 || ip
== -1) {
167 CTFCallsite cs
= eventList
.get(0);
168 fields
.add(new CTFStringField(cs
.toString(), callsite
));
170 fields
.add(new CTFStringField(
171 fTrace
.getCTFTrace().getCallsite(name
, ip
).toString(),
176 return fields
.toArray(new CtfTmfEventField
[fields
.size()]);
183 * CtfTmfEvent to copy
185 public CtfTmfEvent(CtfTmfEvent other
) {
186 /* There is only one reference to the trace, so we can shallow-copy it */
187 this.fTrace
= other
.getTrace();
191 * FIXME This can be switched to a shallow-copy once timestamps are
194 this.fTimestamp
= new CtfTmfTimestamp(other
.fTimestamp
.getValue());
196 /* Primitives, those will be copied by value */
197 this.sourceCPU
= other
.sourceCPU
;
198 this.typeId
= other
.typeId
;
200 /* Strings are immutable, it's safe to shallow-copy them */
201 this.eventName
= other
.eventName
;
202 this.fileName
= other
.fileName
;
204 /* Copy the fields over */
205 this.fContent
= other
.fContent
.clone();
208 * Copy the reference to the custom attributes (should be the same
209 * object for all events of this type)
211 this.fDeclaration
= other
.fDeclaration
;
215 * Inner constructor to create "null" events. Don't use this directly in
216 * normal usage, use CtfTmfEvent.getNullEvent() to get an instance of an
219 * This needs to be public however because it's used in extension points,
220 * and the framework will use this constructor to get the class type.
222 public CtfTmfEvent() {
224 this.fTimestamp
= new CtfTmfTimestamp(-1);
227 this.fileName
= NO_STREAM
;
228 this.eventName
= EMPTY_CTF_EVENT_NAME
;
229 this.fContent
= new TmfEventField("", new CtfTmfEventField
[0]); //$NON-NLS-1$
230 this.fDeclaration
= null;
233 // ------------------------------------------------------------------------
234 // Getters/Setters/Predicates
235 // ------------------------------------------------------------------------
237 private static CtfTmfEvent nullEvent
= new CtfTmfEvent();
242 * @return An empty event.
244 public static CtfTmfEvent
getNullEvent() {
249 * Gets the cpu core the event was recorded on.
251 * @return The cpu id for a given source. In lttng it's from CPUINFO
253 public int getCPU() {
254 return this.sourceCPU
;
258 * Return this event's ID, according to the trace's metadata.
260 * Watch out, this ID is not constant from one trace to another for the same
261 * event types! Use "getEventName()" for a constant reference.
263 * @return The event ID
265 public long getID() {
270 * Gets the name of a current event.
272 * @return The event name
274 public String
getEventName() {
279 * Gets the channel name of a field.
281 * @return The channel name.
283 public String
getChannelName() {
284 return this.fileName
;
288 public CtfTmfTrace
getTrace() {
293 public long getRank() {
294 // TODO Auto-generated method stub
299 public ITmfTimestamp
getTimestamp() {
304 public String
getSource() {
305 // TODO Returns CPU for now
306 return Integer
.toString(getCPU());
310 public ITmfEventType
getType() {
311 CtfTmfEventType ctfTmfEventType
= CtfTmfEventType
.get(eventName
);
312 if( ctfTmfEventType
== null ){
313 ctfTmfEventType
= new CtfTmfEventType( this.getEventName(), this.getContent());
315 return ctfTmfEventType
;
319 public ITmfEventField
getContent() {
324 public String
getReference() {
325 return getChannelName();
329 * List the custom CTF attributes for events of this type.
331 * @return The list of custom attribute names. Should not be null, but could
335 public Set
<String
> listCustomAttributes() {
336 if (fDeclaration
== null) {
337 return new HashSet
<String
>();
339 return fDeclaration
.getCustomAttributes();
343 * Get the value of a custom CTF attributes for this event's type.
346 * Name of the the custom attribute
347 * @return Value of this attribute, or null if there is no attribute with
351 public String
getCustomAttribute(String name
) {
352 if (fDeclaration
== null) {
355 return fDeclaration
.getCustomAttribute(name
);
359 public CtfTmfEvent
clone() {
360 return new CtfTmfEvent(this);
367 public Object
getAdapter(Class adapter
) {
368 if (adapter
== IPropertySource
.class) {
369 return new TmfEventPropertySource(this);