instead of re-implementing the interface.
Part of bug 387929.
For clarity's sake, moved all the instantiation-related code
into a new CtfTmfEventFactory.
Change-Id: Icb3d122acc3a23de3134d8209aa0be5ed4f705f0
Signed-off-by: Alexandre Montplaisir <alexmonthy@voxpopuli.im>
Reviewed-on: https://git.eclipse.org/r/10053
Reviewed-by: Patrick Tasse <patrick.tasse@gmail.com>
IP-Clean: Patrick Tasse <patrick.tasse@gmail.com>
Tested-by: Hudson CI
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
import java.util.Set;
import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfIterator;
import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfTmfEvent;
+import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfTmfEventFactory;
import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfTmfTrace;
import org.eclipse.linuxtools.tmf.core.event.ITmfEventField;
import org.eclipse.linuxtools.tmf.core.event.ITmfEventType;
import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfContext;
import org.junit.Before;
+import org.junit.BeforeClass;
import org.junit.Test;
/**
*/
public class CtfTmfEventTest {
+ private static CtfTmfEvent nullEvent;
private CtfTmfEvent fixture;
+ /**
+ * Test class initialization
+ */
+ @BeforeClass
+ public static void initialize() {
+ nullEvent = CtfTmfEventFactory.getNullEvent();
+ }
+
/**
* Perform pre-test initialization.
*
*/
@Test
public void testGetCPU() {
- CtfTmfEvent nullEvent = CtfTmfEvent.getNullEvent();
int result = nullEvent.getCPU();
-
assertEquals(-1, result);
}
- /**
- * Run the String getChannelName() method test.
- */
- @Test
- public void testGetChannelName() {
- CtfTmfEvent nullEvent = CtfTmfEvent.getNullEvent();
- String result = nullEvent.getChannelName();
-
- assertEquals("No stream", result); //$NON-NLS-1$
- }
-
/**
* Run the String getEventName() method test.
*/
@Test
public void testGetEventName() {
- CtfTmfEvent nullEvent = CtfTmfEvent.getNullEvent();
String result = nullEvent.getEventName();
-
assertEquals("Empty CTF event", result); //$NON-NLS-1$
}
*/
@Test
public void testGetFields() {
- CtfTmfEvent nullEvent = CtfTmfEvent.getNullEvent();
ITmfEventField[] fields = nullEvent.getContent().getFields();
ITmfEventField[] fields2 = new ITmfEventField[0];
assertArrayEquals(fields2, fields);
*/
@Test
public void testGetID() {
- CtfTmfEvent nullEvent = CtfTmfEvent.getNullEvent();
long result = nullEvent.getID();
-
assertEquals(-1L, result);
}
- /**
- * Test the clone method
- */
- @Test
- public void testClone() {
- CtfTmfEvent other = CtfTmfEvent.getNullEvent().clone();
- assertNotNull(other);
- }
-
- /**
- * Run the CTFEvent getNullEvent() method test.
- */
- @Test
- public void testGetNullEvent() {
- CtfTmfEvent nullEvent = CtfTmfEvent.getNullEvent();
-
- assertNotNull(nullEvent);
- assertEquals(-1, nullEvent.getCPU());
- assertEquals("Empty CTF event", nullEvent.getEventName()); //$NON-NLS-1$
- assertEquals("No stream", nullEvent.getChannelName()); //$NON-NLS-1$
- assertArrayEquals(new ITmfEventField[0], nullEvent.getContent().getFields());
- assertEquals(-1L, nullEvent.getID());
- assertEquals(-1L, nullEvent.getTimestamp().getValue());
- }
-
/**
* Run the long getTimestamp() method test.
- *
*/
@Test
public void testGetTimestamp() {
- CtfTmfEvent nullEvent = CtfTmfEvent.getNullEvent();
long result = nullEvent.getTimestamp().getValue();
-
assertEquals(-1L, result);
}
/**
- * Test the getters for the channel name, reference, source and type.
+ * Test the getters for the reference, source and type.
*/
@Test
public void testGetters() {
long rank = fixture.getRank();
CtfTmfTrace trace = fixture.getTrace();
- String channelName = fixture.getChannelName();
String reference = fixture.getReference();
String source = fixture.getSource();
ITmfEventType type = fixture.getType();
- assertEquals(rank, 0);
+ assertEquals(rank, ITmfContext.UNKNOWN_RANK);
assertEquals(trace.getName(), "test"); //$NON-NLS-1$
- assertEquals(channelName, "channel0_1"); //$NON-NLS-1$
assertEquals(reference,"channel0_1"); //$NON-NLS-1$
assertEquals(source, "1"); //$NON-NLS-1$
assertEquals(type.toString(), "lttng_statedump_vm_map"); //$NON-NLS-1$
String s = fixture.getContent().toString();
assertEquals("pid=1922, inode=917738, flags=0x8000075, end=0xb73ec000, start=0xb73ea000, pgoff=0", s); //$NON-NLS-1$
}
+
+ /**
+ * Test the {@link CtfTmfEventFactory#getNullEvent()} method, and the
+ * nullEvent's values.
+ */
+ @Test
+ public void testNullEvent() {
+ CtfTmfEvent nullEvent2 = CtfTmfEventFactory.getNullEvent();
+ assertSame(nullEvent2, nullEvent);
+ assertNotNull(nullEvent);
+ assertEquals(-1, nullEvent.getCPU());
+ assertEquals("Empty CTF event", nullEvent.getEventName()); //$NON-NLS-1$
+ assertEquals("No stream", nullEvent.getReference()); //$NON-NLS-1$
+ assertArrayEquals(new ITmfEventField[0], nullEvent.getContent().getFields());
+ assertEquals(-1L, nullEvent.getID());
+ assertEquals(-1L, nullEvent.getTimestamp().getValue());
+ }
}
public CtfTmfEvent getCurrentEvent() {
final StreamInputReader top = super.prio.peek();
if (top != null) {
- return new CtfTmfEvent(top.getCurrentEvent(), top.getFilename(),
- ctfTmfTrace);
+ return CtfTmfEventFactory.createEvent(top.getCurrentEvent(),
+ top.getFilename(), ctfTmfTrace);
}
return null;
}
package org.eclipse.linuxtools.tmf.core.ctfadaptor;
-import java.util.ArrayList;
-import java.util.HashMap;
import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map.Entry;
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.IEventDeclaration;
-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.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.TmfEventPropertySource;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfContext;
import org.eclipse.ui.views.properties.IPropertySource;
/**
* @author Alexandre Montplaisir
* @since 2.0
*/
-public final class CtfTmfEvent implements ITmfEvent, Cloneable {
+public final class CtfTmfEvent extends TmfEvent {
// ------------------------------------------------------------------------
// 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 ITmfTimestamp fTimestamp;
private final int sourceCPU;
private final long typeId;
private final String eventName;
- private final String fileName;
-
- private final TmfEventField fContent;
private final IEventDeclaration fDeclaration;
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
/**
- * 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.fTimestamp = new CtfTmfTimestamp(-1);
- this.sourceCPU = -1;
- this.typeId = -1;
- this.fileName = NO_STREAM;
- this.eventName = EMPTY_CTF_EVENT_NAME;
- this.fContent = null;
- this.fDeclaration = null;
- return;
- }
-
- /* Read the base event info */
- long ts = this.getTrace().getCTFTrace().timestampCyclesToNanos(eventDef.getTimestamp());
- this.fTimestamp = new CtfTmfTimestamp(ts);
- this.sourceCPU = eventDef.getCPU();
- this.typeId = eventDef.getDeclaration().getId();
- this.eventName = eventDef.getDeclaration().getName();
- this.fileName = fileName;
-
- /* Read the fields */
- this.fContent = new TmfEventField(ITmfEventField.ROOT_FIELD_ID, parseFields(eventDef));
-
- /* Keep a reference to this event's CTF declaration */
- this.fDeclaration = eventDef.getDeclaration();
- }
-
- /**
- * Extract the field information from the structDefinition haze-inducing
- * mess, and put them into something ITmfEventField can cope with.
- */
- 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.isEmpty()) {
- 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) {
- /* There is only one reference to the trace, so we can shallow-copy it */
- this.fTrace = other.getTrace();
-
- /* Copy the timestamp (immutable) */
- this.fTimestamp = other.fTimestamp;
-
- /* Primitives, those will be copied by value */
- 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 (immutable) */
- this.fContent = other.fContent;
-
- /*
- * Copy the reference to the custom attributes (should be the same
- * object for all events of this type)
- */
- this.fDeclaration = other.fDeclaration;
+ 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
+ );
+
+ fDeclaration = declaration;
+ sourceCPU = cpu;
+ typeId = declaration.getId();
+ eventName = declaration.getName();
}
/**
* 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.fTimestamp = new CtfTmfTimestamp(-1);
+ super(null,
+ ITmfContext.UNKNOWN_RANK,
+ new CtfTmfTimestamp(-1),
+ null,
+ null,
+ new TmfEventField("", new CtfTmfEventField[0]), //$NON-NLS-1$
+ NO_STREAM);
this.sourceCPU = -1;
this.typeId = -1;
- this.fileName = NO_STREAM;
this.eventName = EMPTY_CTF_EVENT_NAME;
- this.fContent = new TmfEventField("", new CtfTmfEventField[0]); //$NON-NLS-1$
this.fDeclaration = null;
}
// Getters/Setters/Predicates
// ------------------------------------------------------------------------
- private static CtfTmfEvent nullEvent = new CtfTmfEvent();
-
- /**
- * Get a null event
- *
- * @return An empty event.
- */
- public static CtfTmfEvent getNullEvent() {
- return nullEvent;
- }
-
/**
* Gets the cpu core the event was recorded on.
*
return eventName;
}
- /**
- * Gets the channel name of a field.
- *
- * @return The channel name.
- */
- public String getChannelName() {
- return this.fileName;
- }
-
@Override
public CtfTmfTrace getTrace() {
- return fTrace;
- }
-
- @Override
- public long getRank() {
- // TODO Auto-generated method stub
- return 0;
- }
-
- @Override
- public ITmfTimestamp getTimestamp() {
- return fTimestamp;
- }
-
- @Override
- public String getSource() {
- // TODO Returns CPU for now
- return Integer.toString(getCPU());
+ /* Should be of the right type, since we take a CtfTmfTrace at the constructor */
+ return (CtfTmfTrace) super.getTrace();
}
@Override
public ITmfEventType getType() {
CtfTmfEventType ctfTmfEventType = CtfTmfEventType.get(eventName);
- if( ctfTmfEventType == null ){
- ctfTmfEventType = new CtfTmfEventType( this.getEventName(), this.getContent());
+ if (ctfTmfEventType == null) {
+ /* Should only return null the first time */
+ ctfTmfEventType = new CtfTmfEventType(this.getEventName(), this.getContent());
}
return ctfTmfEventType;
}
- @Override
- public ITmfEventField getContent() {
- return fContent;
- }
-
- @Override
- public String getReference() {
- return getChannelName();
- }
-
/**
* List the custom CTF attributes for events of this type.
*
return fDeclaration.getCustomAttribute(name);
}
- @Override
- public CtfTmfEvent clone() {
- return new CtfTmfEvent(this);
- }
-
/**
* @since 2.0
*/
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2013 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
+ *******************************************************************************/
+
+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 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.ITmfEventField;
+import org.eclipse.linuxtools.tmf.core.event.TmfEventField;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfContext;
+
+/**
+ * Factory for CtfTmfEvent's.
+ *
+ * This code was moved out of CtfTmfEvent to provide better separation between
+ * the parsing/instantiation of events, and the usual TMF API implementations.
+ *
+ * @author Alexandre Montplaisir
+ * @since 2.0
+ */
+public abstract class CtfTmfEventFactory {
+
+ /* Prefix for context information stored as CtfTmfEventfield's */
+ private static final String CONTEXT_FIELD_PREFIX = "context."; //$NON-NLS-1$
+
+ /**
+ * Factory method to instantiate new {@link CtfTmfEvent}'s.
+ *
+ * @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
+ * @return The newly-built CtfTmfEvent
+ */
+ public static CtfTmfEvent createEvent(EventDefinition eventDef,
+ String fileName, CtfTmfTrace originTrace) {
+
+ /* Prepare what to pass to CtfTmfEvent's constructor */
+ long ts = eventDef.getTimestamp();
+ CtfTmfTimestamp timestamp = new CtfTmfTimestamp(
+ originTrace.getCTFTrace().timestampCyclesToNanos(ts));
+
+ int sourceCPU = eventDef.getCPU();
+
+ ITmfEventField content = new TmfEventField(
+ ITmfEventField.ROOT_FIELD_ID, parseFields(originTrace, eventDef));
+
+ String reference = fileName == null ? CtfTmfEvent.NO_STREAM : fileName;
+
+ /* Construct and return the object */
+ CtfTmfEvent event = new CtfTmfEvent(
+ originTrace,
+ ITmfContext.UNKNOWN_RANK,
+ timestamp,
+ content,
+ reference,
+ sourceCPU,
+ eventDef.getDeclaration()
+ );
+ return event;
+ }
+
+ /* Singleton instance of a null event */
+ private static CtfTmfEvent nullEvent = null;
+
+ /**
+ * Get an instance of a null event.
+ *
+ * @return An empty event
+ */
+ public static CtfTmfEvent getNullEvent() {
+ if (nullEvent == null) {
+ nullEvent = new CtfTmfEvent();
+ }
+ return nullEvent;
+ }
+
+ /**
+ * Extract the field information from the structDefinition haze-inducing
+ * mess, and put them into something ITmfEventField can cope with.
+ */
+ private static CtfTmfEventField[] parseFields(CtfTmfTrace trace, 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 = trace.getCTFTrace().getCallsiteCandidates(name);
+ if (!eventList.isEmpty()) {
+ 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(
+ trace.getCTFTrace().getCallsite(name, ip).toString(),
+ callsite));
+ }
+ }
+ return fields.toArray(new CtfTmfEventField[fields.size()]);
+ }
+}
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
+import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfTmfEventFactory;
import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
import org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp;
import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException;
public void dispose() {
/* Insert a null event in the queue to stop the event handler's thread. */
try {
- eventsQueue.put(org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfTmfEvent.getNullEvent());
+ eventsQueue.put(CtfTmfEventFactory.getNullEvent());
eventHandlerThread.join();
} catch (InterruptedException e) {
e.printStackTrace();