/*******************************************************************************
- * Copyright (c) 2011 Ericsson
+ * Copyright (c) 2011, 2014 Ericsson
*
* All rights reserved. This program and the accompanying materials are made
* available under the terms of the Eclipse Public License v1.0 which
* accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
- * Contributors: Alexandre Montplaisir - Initial API and implementation
+ * Contributors:
+ * Alexandre Montplaisir - Initial API and implementation
+ * Bernd Hufmann - Updated for source and model lookup interfaces
*******************************************************************************/
package org.eclipse.linuxtools.tmf.core.ctfadaptor;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map.Entry;
+import java.util.HashSet;
+import java.util.Set;
import org.eclipse.linuxtools.ctf.core.event.CTFCallsite;
-import org.eclipse.linuxtools.ctf.core.event.EventDefinition;
-import org.eclipse.linuxtools.ctf.core.event.types.Definition;
-import org.eclipse.linuxtools.ctf.core.event.types.IntegerDefinition;
-import org.eclipse.linuxtools.ctf.core.event.types.StructDefinition;
-import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
+import org.eclipse.linuxtools.ctf.core.event.IEventDeclaration;
+import org.eclipse.linuxtools.ctf.core.trace.CTFTrace;
+import org.eclipse.linuxtools.tmf.core.event.ITmfCustomAttributes;
import org.eclipse.linuxtools.tmf.core.event.ITmfEventField;
import org.eclipse.linuxtools.tmf.core.event.ITmfEventType;
-import org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp;
+import org.eclipse.linuxtools.tmf.core.event.TmfEvent;
+import org.eclipse.linuxtools.tmf.core.event.TmfEventField;
+import org.eclipse.linuxtools.tmf.core.event.lookup.ITmfModelLookup;
+import org.eclipse.linuxtools.tmf.core.event.lookup.ITmfSourceLookup;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfContext;
/**
- * A wrapper class around CTF's Event Definition/Declaration that maps all
- * types of Declaration to native Java types.
+ * A wrapper class around CTF's Event Definition/Declaration that maps all types
+ * of Declaration to native Java types.
*
* @version 1.0
* @author Alexandre Montplaisir
+ * @since 2.0
*/
-public final class CtfTmfEvent implements ITmfEvent, Cloneable {
+public class CtfTmfEvent extends TmfEvent
+ implements ITmfSourceLookup, ITmfModelLookup, ITmfCustomAttributes {
// ------------------------------------------------------------------------
// Constants
// ------------------------------------------------------------------------
- private static final String NO_STREAM = "No stream"; //$NON-NLS-1$
+ static final String NO_STREAM = "No stream"; //$NON-NLS-1$
private static final String EMPTY_CTF_EVENT_NAME = "Empty CTF event"; //$NON-NLS-1$
- /** Prefix for Context information stored as CtfTmfEventfield */
- private static final String CONTEXT_FIELD_PREFIX = "context."; //$NON-NLS-1$
-
// ------------------------------------------------------------------------
// Attributes
// ------------------------------------------------------------------------
- private final CtfTmfTrace fTrace;
- private final long timestamp;
- private final int sourceCPU;
- private final long typeId;
- private final String eventName;
- private final String fileName;
-
- private final CtfTmfContent fContent;
+ private final int fSourceCPU;
+ private final long fTypeId;
+ private final String fEventName;
+ private final IEventDeclaration fDeclaration;
// ------------------------------------------------------------------------
// Constructors
// ------------------------------------------------------------------------
/**
- * Usual CTFEvent constructor, where we read an event from the trace (via
- * the StreamInputReader).
- *
- * @param eventDef
- * CTF EventDefinition object corresponding to this trace event
- * @param fileName
- * The path to the trace file
- * @param originTrace
- * The trace from which this event originates
+ * Constructor used by {@link CtfTmfEventFactory#createEvent}
*/
- public CtfTmfEvent(EventDefinition eventDef, String fileName,
- CtfTmfTrace originTrace) {
- this.fTrace = originTrace;
-
- if (eventDef == null) {
- this.timestamp = -1;
- this.sourceCPU = -1;
- this.typeId = -1;
- this.fileName = NO_STREAM;
- this.eventName = EMPTY_CTF_EVENT_NAME;
- this.fContent = null;
- return;
- }
+ CtfTmfEvent(CtfTmfTrace trace, long rank, CtfTmfTimestamp timestamp,
+ ITmfEventField content, String fileName, int cpu,
+ IEventDeclaration declaration) {
+ super(trace,
+ rank,
+ timestamp,
+ String.valueOf(cpu), // Source
+ null, // Event type. We don't use TmfEvent's field here, we re-implement getType()
+ content,
+ fileName // Reference
+ );
- /* Read the base event info */
- Long offset = originTrace.getCTFTrace().getOffset();
- this.timestamp = eventDef.getTimestamp() + offset;
- this.sourceCPU = eventDef.getCPU();
- this.typeId = eventDef.getDeclaration().getId();
- this.eventName = eventDef.getDeclaration().getName();
- this.fileName = fileName;
+ fDeclaration = declaration;
+ fSourceCPU = cpu;
+ fTypeId = declaration.getId();
+ fEventName = declaration.getName();
- /* Read the fields */
- this.fContent = new CtfTmfContent(ITmfEventField.ROOT_FIELD_ID,
- parseFields(eventDef));
- }
-
- /**
- * Extract the field information from the structDefinition haze-inducing
- * mess, and put them into something ITmfEventField can cope with.
- *
- * @param eventDef
- * CTF EventDefinition to read
- * @return CtfTmfEventField[] The array of fields that were read
- */
- private CtfTmfEventField[] parseFields(EventDefinition eventDef) {
- List<CtfTmfEventField> fields = new ArrayList<CtfTmfEventField>();
-
- StructDefinition structFields = eventDef.getFields();
- HashMap<String, Definition> definitions = structFields.getDefinitions();
- String curFieldName = null;
- Definition curFieldDef;
- CtfTmfEventField curField;
- Iterator<Entry<String, Definition>> it = definitions.entrySet().iterator();
- while(it.hasNext()) {
- Entry<String, Definition> entry = it.next();
- curFieldName = entry.getKey();
- curFieldDef = entry.getValue();
- curField = CtfTmfEventField.parseField(curFieldDef, curFieldName);
- fields.add(curField);
- }
-
- /* Add context information as CtfTmfEventField */
- long ip = -1;
- StructDefinition structContext = eventDef.getContext();
- if (structContext != null) {
- definitions = structContext.getDefinitions();
- String curContextName;
- Definition curContextDef;
- CtfTmfEventField curContext;
- it = definitions.entrySet().iterator();
- while(it.hasNext()) {
- Entry<String, Definition> entry = it.next();
- /* This is to get the instruction pointer if available */
- if (entry.getKey().equals("_ip") && //$NON-NLS-1$
- (entry.getValue() instanceof IntegerDefinition)) {
- ip = ((IntegerDefinition) entry.getValue()).getValue();
- }
- /* Prefix field name to */
- curContextName = CONTEXT_FIELD_PREFIX + entry.getKey();
- curContextDef = entry.getValue();
- curContext = CtfTmfEventField.parseField(curContextDef, curContextName);
- fields.add(curContext);
- }
- }
- /* Add callsite */
- final String name = eventDef.getDeclaration().getName();
- List<CTFCallsite> eventList = fTrace.getCTFTrace().getCallsiteCandidates(name);
- if (eventList != null) {
- final String callsite = "callsite"; //$NON-NLS-1$
- if (eventList.size() == 1 || ip == -1) {
- CTFCallsite cs = eventList.get(0);
- fields.add(new CTFStringField(cs.toString(), callsite));
- } else {
- fields.add(new CTFStringField(
- fTrace.getCTFTrace().getCallsite(name, ip).toString(),
- callsite));
- }
- }
-
- return fields.toArray(new CtfTmfEventField[fields.size()]);
- }
-
- /**
- * Copy constructor
- *
- * @param other
- * CtfTmfEvent to copy
- */
- public CtfTmfEvent(CtfTmfEvent other) {
- this.fTrace = other.getTrace();
- /* Primitives, those will be copied by value */
- this.timestamp = other.timestamp;
- this.sourceCPU = other.sourceCPU;
- this.typeId = other.typeId;
-
- /* Strings are immutable, it's safe to shallow-copy them */
- this.eventName = other.eventName;
- this.fileName = other.fileName;
-
- /* Copy the fields over */
- this.fContent = (CtfTmfContent) other.fContent.clone();
}
/**
* Inner constructor to create "null" events. Don't use this directly in
- * normal usage, use CtfTmfEvent.getNullEvent() to get an instance of an
- * empty event.
+ * normal usage, use {@link CtfTmfEventFactory#getNullEvent()} to get an
+ * instance of an empty event.
*
* This needs to be public however because it's used in extension points,
* and the framework will use this constructor to get the class type.
*/
public CtfTmfEvent() {
- this.fTrace = null;
- this.timestamp = -1;
- this.sourceCPU = -1;
- this.typeId = -1;
- this.fileName = NO_STREAM;
- this.eventName = EMPTY_CTF_EVENT_NAME;
- this.fContent = new CtfTmfContent("", new CtfTmfEventField[0]); //$NON-NLS-1$
+ super(null,
+ ITmfContext.UNKNOWN_RANK,
+ new CtfTmfTimestamp(-1),
+ null,
+ null,
+ new TmfEventField("", null, new CtfTmfEventField[0]), //$NON-NLS-1$
+ NO_STREAM);
+ fSourceCPU = -1;
+ fTypeId = -1;
+ fEventName = EMPTY_CTF_EVENT_NAME;
+ fDeclaration = null;
}
// ------------------------------------------------------------------------
// Getters/Setters/Predicates
// ------------------------------------------------------------------------
- private static CtfTmfEvent nullEvent = null;
-
- /**
- * Get a null event
- *
- * @return an empty event. */
- public static CtfTmfEvent getNullEvent() {
- if (nullEvent == null) {
- nullEvent = new CtfTmfEvent();
- }
- return nullEvent;
- }
-
- /**
- * Gets the current timestamp of the event
- *
- * @return the current timestamp (long) */
- public long getTimestampValue() {
- return this.timestamp;
- }
-
/**
* Gets the cpu core the event was recorded on.
*
- * @return the cpu id for a given source. In lttng it's from CPUINFO */
+ * @return The cpu id for a given source. In lttng it's from CPUINFO
+ */
public int getCPU() {
- return this.sourceCPU;
+ return fSourceCPU;
}
/**
- * Return this event's ID, according to the trace's metadata. Watch out,
- * this ID is not constant from one trace to another for the same event
- * types! Use "getEventName()" for a constant reference.
+ * Return this event's ID, according to the trace's metadata.
*
-
- * @return the event ID */
- public long getID() {
- return this.typeId;
- }
-
- /**
- * Gets the name of a current event.
+ * Watch out, this ID is not constant from one trace to another for the same
+ * event types! Use "getEventName()" for a constant reference.
*
- * @return the event name */
- public String getEventName() {
- return eventName;
- }
-
- /**
- * Gets the channel name of a field.
- *
- * @return the channel name. */
- public String getChannelName() {
- return this.fileName;
- }
-
- /**
- * Method getTrace.
- * @return CtfTmfTrace
- * @see org.eclipse.linuxtools.tmf.core.event.ITmfEvent#getTrace()
+ * @return The event ID
*/
- @Override
- public CtfTmfTrace getTrace() {
- return fTrace;
+ public long getID() {
+ return fTypeId;
}
- /**
- * Method getRank.
- * @return long
- * @see org.eclipse.linuxtools.tmf.core.event.ITmfEvent#getRank()
- */
@Override
- public long getRank() {
- // TODO Auto-generated method stub
- return 0;
+ public CtfTmfTrace getTrace() {
+ /*
+ * Should be of the right type, since we take a CtfTmfTrace at the
+ * constructor
+ */
+ return (CtfTmfTrace) super.getTrace();
}
- private ITmfTimestamp fTimestamp = null;
-
- // TODO Benchmark if the singleton approach is faster than just
- // instantiating a final fTimestramp right away at creation time
- /**
- * Method getTimestamp.
- * @return ITmfTimestamp
- * @see org.eclipse.linuxtools.tmf.core.event.ITmfEvent#getTimestamp()
- */
@Override
- public ITmfTimestamp getTimestamp() {
- if (fTimestamp == null) {
- fTimestamp = new CtfTmfTimestamp(timestamp);
+ public ITmfEventType getType() {
+ CtfTmfEventType ctfTmfEventType = CtfTmfEventType.get(getTrace(), fEventName);
+ if (ctfTmfEventType == null) {
+ /* Should only return null the first time */
+ ctfTmfEventType = new CtfTmfEventType(fEventName, getTrace(), getContent());
}
- return fTimestamp;
+ return ctfTmfEventType;
}
- String fSource = null;
/**
- * Method getSource.
- * @return String
- * @see org.eclipse.linuxtools.tmf.core.event.ITmfEvent#getSource()
+ * @since 2.0
*/
@Override
- public String getSource() {
- // TODO Returns CPU for now
- if(fSource == null) {
- fSource= Integer.toString(getCPU());
+ public Set<String> listCustomAttributes() {
+ if (fDeclaration == null) {
+ return new HashSet<>();
}
- return fSource;
+ return fDeclaration.getCustomAttributes();
}
/**
- * Method getType.
- * @return ITmfEventType
- * @see org.eclipse.linuxtools.tmf.core.event.ITmfEvent#getType()
+ * @since 2.0
*/
@Override
- public ITmfEventType getType() {
- CtfTmfEventType ctfTmfEventType = CtfTmfEventType.get(eventName);
- if( ctfTmfEventType == null ){
- ctfTmfEventType = new CtfTmfEventType( this.getEventName(), this.getContent());
+ public String getCustomAttribute(String name) {
+ if (fDeclaration == null) {
+ return null;
}
- return ctfTmfEventType;
- }
-
- /**
- * Method getContent.
- * @return ITmfEventField
- * @see org.eclipse.linuxtools.tmf.core.event.ITmfEvent#getContent()
- */
- @Override
- public ITmfEventField getContent() {
- return fContent;
+ return fDeclaration.getCustomAttribute(name);
}
- String fReference = null;
/**
- * Method getReference.
- * @return String
- * @see org.eclipse.linuxtools.tmf.core.event.ITmfEvent#getReference()
+ * Get the call site for this event.
+ *
+ * @return the call site information, or null if there is none
+ * @since 2.0
*/
@Override
- public String getReference() {
- if( fReference == null){
- fReference = getChannelName();
+ public CtfTmfCallsite getCallsite() {
+ CTFCallsite callsite = null;
+ CtfTmfTrace trace = getTrace();
+ if (trace == null) {
+ return null;
}
- return fReference;
+ CTFTrace ctfTrace = trace.getCTFTrace();
+ /* Should not happen, but it is a good check */
+ if (ctfTrace == null) {
+ return null;
+ }
+ if (getContent() != null) {
+ ITmfEventField ipField = getContent().getField(CtfConstants.CONTEXT_FIELD_PREFIX + CtfConstants.IP_KEY);
+ if (ipField != null && ipField.getValue() instanceof Long) {
+ long ip = (Long) ipField.getValue();
+ callsite = ctfTrace.getCallsite(fEventName, ip);
+ }
+ }
+ if (callsite == null) {
+ callsite = ctfTrace.getCallsite(fEventName);
+ }
+ if (callsite != null) {
+ return new CtfTmfCallsite(callsite);
+ }
+ return null;
}
/**
- * Method clone.
- * @return CtfTmfEvent
- * @see org.eclipse.linuxtools.tmf.core.event.ITmfEvent#clone()
+ * @since 2.0
*/
@Override
- public CtfTmfEvent clone() {
- return new CtfTmfEvent(this);
+ public String getModelUri() {
+ return getCustomAttribute(CtfConstants.MODEL_URI_KEY);
}
+
}