ctf: Assign a CtfTmfEventFactory to each trace
authorAlexandre Montplaisir <alexmonthy@voxpopuli.im>
Fri, 4 Sep 2015 21:32:13 +0000 (17:32 -0400)
committerAlexandre Montplaisir <alexmonthy@voxpopuli.im>
Fri, 23 Oct 2015 20:09:01 +0000 (16:09 -0400)
A singleton factory means we cannot possibly extend CtfTmfEvent,
because the sole factory can only generate CtfTmfEvent objects.

To rectify this, we can turn the factory into a standard non-static
class, and have each trace take ownership of its event factory. This
means that sub-classes of CtfTmfTrace will be able to provide their
own extension of CtfTmfEventFactory if they want to generate other
event types.

Bug: 476679
Change-Id: I66e9cd49044edd2a77276d779d0f563a2e20d520
Signed-off-by: Alexandre Montplaisir <alexmonthy@voxpopuli.im>
Signed-off-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Reviewed-on: https://git.eclipse.org/r/56191
Reviewed-by: Hudson CI
ctf/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/event/CtfTmfEventTest.java
ctf/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/internal/tmf/ctf/core/trace/iterator/CtfIterator.java
ctf/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/event/CtfTmfEvent.java
ctf/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/event/CtfTmfEventFactory.java
ctf/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/trace/CtfTmfTrace.java

index 525dd9571db2302062cce4ecd5c1c4cc259259df..6b83b268f4b836ae283ec152d8bf155c6d55f593 100644 (file)
@@ -17,7 +17,6 @@ package org.eclipse.tracecompass.tmf.ctf.core.tests.event;
 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.Collection;
 import java.util.Set;
@@ -190,13 +189,13 @@ public class CtfTmfEventTest {
     }
 
     /**
-     * Test the {@link CtfTmfEventFactory#getNullEvent(CtfTmfTrace)} method, and
+     * Test the {@link CtfTmfEventFactory#getNullEvent()} method, and
      * the nullEvent's values.
      */
     @Test
     public void testNullEvent() {
         CtfTmfEvent nullEvent2 = CtfTmfEventFactory.getNullEvent(fixture.getTrace());
-        assertSame(nullEvent2, nullEvent);
+        assertEquals(nullEvent2, nullEvent);
         assertNotNull(nullEvent);
         assertEquals(-1, nullEvent.getCPU());
         assertEquals("Empty CTF event", nullEvent.getType().getName());
index 29d8d63c174732be2b06d3b373327c7cfbce0459..d621d5266f6c148927c212903d8190ce40dc9b33 100644 (file)
@@ -26,7 +26,6 @@ import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation;
 import org.eclipse.tracecompass.tmf.ctf.core.context.CtfLocation;
 import org.eclipse.tracecompass.tmf.ctf.core.context.CtfLocationInfo;
 import org.eclipse.tracecompass.tmf.ctf.core.event.CtfTmfEvent;
-import org.eclipse.tracecompass.tmf.ctf.core.event.CtfTmfEventFactory;
 import org.eclipse.tracecompass.tmf.ctf.core.trace.CtfTmfTrace;
 
 /**
@@ -146,8 +145,7 @@ public class CtfIterator extends CTFTraceReader
         if (top != null) {
             if (!fCurLocation.equals(fPreviousLocation)) {
                 fPreviousLocation = fCurLocation;
-                fPreviousEvent = CtfTmfEventFactory.createEvent(top.getCurrentEvent(),
-                        top.getFilename(), fTrace);
+                fPreviousEvent = fTrace.getEventFactory().createEvent(fTrace, top.getCurrentEvent(), top.getFilename());
             }
             return fPreviousEvent;
         }
index 9fb7548515ddb98a1bd24dc0e18146be37fed4bb..17ef0213ca92be4330b977a38dc093744b243390 100644 (file)
@@ -84,10 +84,35 @@ public class CtfTmfEvent extends TmfEvent
     // ------------------------------------------------------------------------
 
     /**
-     * Constructor used by {@link CtfTmfEventFactory#createEvent}
+     * Constructor, used by {@link CtfTmfEventFactory#createEvent}.
+     *
+     * Only subclasses should call this. It is imperative that the subclass also
+     * has a constructor with the EXACT same parameter signature, because the
+     * factory will look for a constructor with the same arguments.
+     *
+     * @param trace
+     *            The trace to which this event belongs
+     * @param rank
+     *            The rank of the event
+     * @param timestamp
+     *            The timestamp
+     * @param channel
+     *            The CTF channel of this event
+     * @param cpu
+     *            The event's CPU
+     * @param declaration
+     *            The event declaration
+     * @param eventDefinition
+     *            The event definition
+     * @since 2.0
      */
-    CtfTmfEvent(CtfTmfTrace trace, long rank, TmfNanoTimestamp timestamp,
-            String channel, int cpu, IEventDeclaration declaration, EventDefinition eventDefinition) {
+    protected CtfTmfEvent(CtfTmfTrace trace,
+            long rank,
+            TmfNanoTimestamp timestamp,
+            String channel,
+            int cpu,
+            IEventDeclaration declaration,
+            EventDefinition eventDefinition) {
         super(trace,
                 rank,
                 timestamp,
index 83fdf47093977fe311380f8bcfab4deac8e65991..d0632bb49ca172074dad5e234188e68b381e1ed4 100644 (file)
@@ -31,34 +31,55 @@ import org.eclipse.tracecompass.tmf.ctf.core.trace.CtfTmfTrace;
  *
  * @author Alexandre Montplaisir
  */
-public final class CtfTmfEventFactory {
+public class CtfTmfEventFactory {
 
-    private static final @NonNull String NO_STREAM = "No stream"; //$NON-NLS-1$
+    private static final @NonNull CtfTmfEventFactory INSTANCE = new CtfTmfEventFactory();
 
     /**
-     * Don't let anyone instantiate this class.
+     * The file name to use when none is specified.
+     *
+     * FIXME Externalize?
+     *
+     * @since 2.0
      */
-    private CtfTmfEventFactory() {}
+    protected static final @NonNull String NO_STREAM = "No stream"; //$NON-NLS-1$
 
     /**
-     * Factory method to instantiate new {@link CtfTmfEvent}'s.
+     * Protected constructor, only for use by sub-classes. Users should call
+     * the {@link #instance()} method instead.
      *
+     * @since 2.0
+     */
+    protected CtfTmfEventFactory() {}
+
+    /**
+     * Get the singleton factory instance
+     *
+     * @return The instance
+     * @since 2.0
+     */
+    public static @NonNull CtfTmfEventFactory instance() {
+        return INSTANCE;
+    }
+
+    /**
+     * Factory method to instantiate new CTF events.
+     *
+     * @param trace
+     *            The trace to which the new event will belong
      * @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
+     * @since 2.0
      */
-    public static CtfTmfEvent createEvent(EventDefinition eventDef,
-            String fileName, CtfTmfTrace originTrace) {
+    public CtfTmfEvent createEvent(CtfTmfTrace trace, EventDefinition eventDef, String fileName) {
 
         /* Prepare what to pass to CtfTmfEvent's constructor */
         final IEventDeclaration eventDecl = eventDef.getDeclaration();
         final long ts = eventDef.getTimestamp();
-        final TmfNanoTimestamp timestamp = originTrace.createTimestamp(
-                originTrace.timestampCyclesToNanos(ts));
+        final TmfNanoTimestamp timestamp = trace.createTimestamp(trace.timestampCyclesToNanos(ts));
 
         int sourceCPU = eventDef.getCPU();
 
@@ -66,59 +87,83 @@ public final class CtfTmfEventFactory {
 
         /* Handle the special case of lost events */
         if (eventDecl.getName().equals(CTFStrings.LOST_EVENT_NAME)) {
-            IDefinition nbLostEventsDef = eventDef.getFields().getDefinition(CTFStrings.LOST_EVENTS_FIELD);
-            IDefinition durationDef = eventDef.getFields().getDefinition(CTFStrings.LOST_EVENTS_DURATION);
-            if (!(nbLostEventsDef instanceof IntegerDefinition) || !(durationDef instanceof IntegerDefinition)) {
-                /*
-                 * One or both of these fields doesn't exist, or is not of the
-                 * right type. The event claims to be a "lost event", but is
-                 * malformed. Log it and return a null event instead.
-                 */
-                return getNullEvent(originTrace);
-            }
-            long nbLostEvents = ((IntegerDefinition) nbLostEventsDef).getValue();
-            long duration = ((IntegerDefinition) durationDef).getValue();
-            TmfNanoTimestamp timestampEnd = new TmfNanoTimestamp(
-                    originTrace.timestampCyclesToNanos(ts) + duration);
-
-            CtfTmfLostEvent lostEvent = new CtfTmfLostEvent(originTrace,
-                    ITmfContext.UNKNOWN_RANK,
-                    reference, // filename
-                    sourceCPU,
-                    eventDecl,
-                    new TmfTimeRange(timestamp, timestampEnd),
-                    nbLostEvents,
-                    eventDef);
-            return lostEvent;
+            return createLostEvent(trace, eventDef, eventDecl, ts, timestamp, sourceCPU, reference);
         }
 
         /* Handle standard event types */
-        CtfTmfEvent event = new CtfTmfEvent(
-                originTrace,
+        return new CtfTmfEvent(trace,
                 ITmfContext.UNKNOWN_RANK,
                 timestamp,
                 reference, // filename
                 sourceCPU,
                 eventDecl,
                 eventDef);
-        return event;
     }
 
-    /* Singleton instance of a null event */
-    private static CtfTmfEvent nullEvent = null;
+    /**
+     * Create a new CTF lost event.
+     *
+     * @param trace
+     *            The trace to which the new event will belong
+     * @param eventDef
+     *            The CTF event definition
+     * @param eventDecl
+     *            The CTF event declaration
+     * @param ts
+     *            The event's timestamp
+     * @param timestamp
+     *            The event's timestamp (FIXME again??)
+     * @param sourceCPU
+     *            The source CPU
+     * @param fileName
+     *            The file name
+     * @return The new lost event
+     * @since 2.0
+     */
+    protected static CtfTmfEvent createLostEvent(CtfTmfTrace trace,
+            EventDefinition eventDef,
+            final IEventDeclaration eventDecl,
+            final long ts,
+            final TmfNanoTimestamp timestamp,
+            int sourceCPU,
+            String fileName) {
+
+        IDefinition nbLostEventsDef = eventDef.getFields().getDefinition(CTFStrings.LOST_EVENTS_FIELD);
+        IDefinition durationDef = eventDef.getFields().getDefinition(CTFStrings.LOST_EVENTS_DURATION);
+        if (!(nbLostEventsDef instanceof IntegerDefinition) || !(durationDef instanceof IntegerDefinition)) {
+            /*
+             * One or both of these fields doesn't exist, or is not of the right
+             * type. The event claims to be a "lost event", but is malformed.
+             * Log it and return a null event instead.
+             */
+            return getNullEvent(trace);
+        }
+        long nbLostEvents = ((IntegerDefinition) nbLostEventsDef).getValue();
+        long duration = ((IntegerDefinition) durationDef).getValue();
+        TmfNanoTimestamp timestampEnd = new TmfNanoTimestamp(
+                trace.timestampCyclesToNanos(ts) + duration);
+
+        CtfTmfLostEvent lostEvent = new CtfTmfLostEvent(trace,
+                ITmfContext.UNKNOWN_RANK,
+                fileName,
+                sourceCPU,
+                eventDecl,
+                new TmfTimeRange(timestamp, timestampEnd),
+                nbLostEvents,
+                eventDef);
+        return lostEvent;
+    }
 
     /**
      * Get an instance of a null event.
      *
      * @param trace
-     *            A trace to associate with this null event
+     *            The trace to which the new null event will belong
      * @return An empty event
+     * @since 2.0
      */
-    public static CtfTmfEvent getNullEvent(@NonNull CtfTmfTrace trace) {
-        if (nullEvent == null) {
-            nullEvent = new CtfTmfEvent(trace);
-        }
-        return nullEvent;
+    public static CtfTmfEvent getNullEvent(CtfTmfTrace trace) {
+        return new CtfTmfEvent(trace);
     }
 
 
index 5328b5b293424fdfaced06611f015c7f39b0b2b6..b3cd9261ccc963b5d80a620d929c8065142b0c19 100644 (file)
@@ -66,6 +66,7 @@ import org.eclipse.tracecompass.tmf.ctf.core.context.CtfLocation;
 import org.eclipse.tracecompass.tmf.ctf.core.context.CtfLocationInfo;
 import org.eclipse.tracecompass.tmf.ctf.core.context.CtfTmfContext;
 import org.eclipse.tracecompass.tmf.ctf.core.event.CtfTmfEvent;
+import org.eclipse.tracecompass.tmf.ctf.core.event.CtfTmfEventFactory;
 import org.eclipse.tracecompass.tmf.ctf.core.event.CtfTmfEventType;
 import org.eclipse.tracecompass.tmf.ctf.core.event.aspect.CtfChannelAspect;
 import org.eclipse.tracecompass.tmf.ctf.core.event.aspect.CtfCpuAspect;
@@ -122,9 +123,37 @@ public class CtfTmfTrace extends TmfTrace
     private final CtfIteratorManager fIteratorManager =
             new CtfIteratorManager(this);
 
-    /* Reference to the CTF Trace */
+    private final @NonNull CtfTmfEventFactory fEventFactory;
+
+    /** Reference to the CTF Trace */
     private CTFTrace fTrace;
 
+    // -------------------------------------------
+    // Constructor
+    // -------------------------------------------
+
+    /**
+     * Default constructor
+     */
+    public CtfTmfTrace() {
+        super();
+
+        /* Use default event factory */
+        fEventFactory = CtfTmfEventFactory.instance();
+    }
+
+    /**
+     * Constructor for sub-classes to specify their own event factory.
+     *
+     * @param eventFactory
+     *            The event factory to use to generate trace events
+     * @since 2.0
+     */
+    protected CtfTmfTrace(@NonNull CtfTmfEventFactory eventFactory) {
+        super();
+        fEventFactory = eventFactory;
+    }
+
     // -------------------------------------------
     // TmfTrace Overrides
     // -------------------------------------------
@@ -495,6 +524,16 @@ public class CtfTmfTrace extends TmfTrace
     // CtfIterator factory methods
     // -------------------------------------------
 
+    /**
+     * Get the event factory for this trace to generate new events for it.
+     *
+     * @return The event factory
+     * @since 2.0
+     */
+    public @NonNull CtfTmfEventFactory getEventFactory() {
+        return fEventFactory;
+    }
+
     /**
      * Get an iterator to the trace
      *
This page took 0.030709 seconds and 5 git commands to generate.