TestRoots/watchdog

View on GitHub
core/src/nl/tudelft/watchdog/core/logic/event/EventStatistics.java

Summary

Maintainability
A
25 mins
Test Coverage
package nl.tudelft.watchdog.core.logic.event;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import nl.tudelft.watchdog.core.logic.event.eventtypes.EventBase;
import nl.tudelft.watchdog.core.logic.event.eventtypes.TrackingEventType;
import nl.tudelft.watchdog.core.logic.interval.intervaltypes.DebugInterval;
import nl.tudelft.watchdog.core.logic.storage.PersisterBase;
import nl.tudelft.watchdog.core.logic.storage.WatchDogItem;

import org.jfree.data.gantt.GanttCategoryDataset;
import org.jfree.data.gantt.Task;
import org.jfree.data.gantt.TaskSeries;
import org.jfree.data.gantt.TaskSeriesCollection;

/**
 * Contains basic functionality for selecting all events that occurred during a
 * certain debug interval. Dataset creation functionality should be implemented
 * by IDE-specific code in order to avoid IDE-specific dependencies in the core
 * project.
 */
public class EventStatistics {

    /**
     * The amount of time before a debug interval of which the events should be
     * included as well.
     */
    public static final int PRE_SESSION_TIME_TO_INCLUDE = 20 * 1000;

    /** Persister storing all events. */
    private final PersisterBase eventsStatisticsPersister;

    /** A list of the managed events. */
    protected final List<EventBase> events = new ArrayList<EventBase>();

    /** The debug interval that is currently selected. */
    private final DebugInterval selectedInterval;

    /** The timestamp from which the events should be added. */
    private Date startOfEventSelection;

    /** Constructor. */
    public EventStatistics(TrackingEventManager trackingEventManager, DebugInterval selectedInterval) {
        this.eventsStatisticsPersister = trackingEventManager.getEventStatisticsPersister();
        this.selectedInterval = selectedInterval;
        startOfEventSelection = new Date(selectedInterval.getStart().getTime() - PRE_SESSION_TIME_TO_INCLUDE);
        addAllEventsWithinSelectedInterval();
    }

    /** Fills the 'events' list with the correct events. */
    private void addAllEventsWithinSelectedInterval() {
        for (WatchDogItem item : eventsStatisticsPersister.readItems()) {
            if (item instanceof EventBase) {
                EventBase event = (EventBase) item;
                if (isWithinSelectedDebugInterval(event)) {
                    events.add(event);
                }
            }
        }
    }

    /**
     * @return true if and only if the event occurred within the selected debug
     *         interval or in the period right before it.
     */
    private boolean isWithinSelectedDebugInterval(EventBase event) {
        Date timestamp = event.getTimestamp();
        return startOfEventSelection.before(timestamp) && timestamp.before(selectedInterval.getEnd());
    }

    /**
     * Adds some time to make sure the end time of a task is later than its
     * start time.
     */
    protected Date addDeltaTo(Date timestamp) {
        Calendar newTimestamp = Calendar.getInstance();
        newTimestamp.setTime(timestamp);
        newTimestamp.add(Calendar.MILLISECOND, 500);
        return newTimestamp.getTime();
    }

    /**
     * Creates a dataset of all events that occurred during the selected debug
     * interval.
     */
    public GanttCategoryDataset createDebugEventGanttChartDataset() {
        // Create and add the tasks for each event type.
        TaskSeries allTasks = new TaskSeries("Debug Events");

        for (TrackingEventType type : TrackingEventType.values()) {
            final List<EventBase> filteredEventList = events.stream().filter(e -> e.getType() == type).collect(Collectors.toList());
            allTasks.add(createTaskForEventsWithName(filteredEventList, type.getTextualDescription()));
        }

        // Create collection of the overall tasks.
        TaskSeriesCollection collection = new TaskSeriesCollection();
        collection.add(allTasks);
        return collection;
    }

    /**
     * Creates the overall task for a particular event type and attaches each
     * individual event as a subtask.
     */
    private Task createTaskForEventsWithName(List<EventBase> events, String taskName) {
        if (events.isEmpty()) {
            return new Task(taskName, new Date(0), new Date(1));
        }
        Collections.sort(events);
        Task overallTask = new Task(taskName, events.get(0).getTimestamp(),
                addDeltaTo(events.get(events.size() - 1).getTimestamp()));

        // Add subtask for each event
        for (EventBase event : events) {
            final Task subtask = new Task(event.toString(), event.getTimestamp(),
                    addDeltaTo(event.getTimestamp()));
            overallTask.addSubtask(subtask);
        }
        return overallTask;
    }

}