org.fenixedu.academic.service.services.administrativeOffice.enrolment.MultiSemesterEnrolmentReporter.java Source code

Java tutorial

Introduction

Here is the source code for org.fenixedu.academic.service.services.administrativeOffice.enrolment.MultiSemesterEnrolmentReporter.java

Source

/**
 * Copyright  2002 Instituto Superior Tcnico
 *
 * This file is part of FenixEdu Academic.
 *
 * FenixEdu Academic is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * FenixEdu Academic is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with FenixEdu Academic.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.fenixedu.academic.service.services.administrativeOffice.enrolment;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;

import org.fenixedu.academic.domain.ExecutionSemester;
import org.fenixedu.academic.domain.log.CurriculumLineLog;
import org.fenixedu.academic.domain.log.EnrolmentLog;
import org.fenixedu.academic.domain.student.Registration;
import org.fenixedu.academic.util.EnrolmentAction;
import org.joda.time.DateTime;
import org.joda.time.Interval;

import com.google.gson.JsonArray;
import com.google.gson.JsonObject;

public class MultiSemesterEnrolmentReporter {

    private final int hoursToReport;
    private final int semesterToReport;

    public MultiSemesterEnrolmentReporter(final int hoursToReportFromStart, final int semesterToReport) {
        this.hoursToReport = hoursToReportFromStart;
        this.semesterToReport = semesterToReport;
    }

    public void report(final int year, final int month, final int day, final int hour) {
        final DateTime enrolmentStartTime = new DateTime(year, month, day, hour, 0, 0, 0);
        final ExecutionSemester semester = ExecutionSemester.readByDateTime(enrolmentStartTime);
        final DateTime endTimeToReport = enrolmentStartTime.plusHours(hoursToReport);

        if (semester.getSemester().intValue() == semesterToReport) {
            semester.getCurriculumLineLogsSet().stream()

                    .filter(l -> l instanceof EnrolmentLog)

                    .filter(l -> !l.getDateDateTime().isBefore(enrolmentStartTime)
                            && !l.getDateDateTime().isAfter(endTimeToReport))

                    .sorted((l1, l2) -> l1.getDateDateTime().compareTo(l2.getDateDateTime()))

                    .forEach(l -> process(semester, enrolmentStartTime, l));

            semester.getAssociatedExecutionCoursesSet().stream()

                    .flatMap(ec -> ec.getCourseLoadsSet().stream())

                    .flatMap(cl -> cl.getShiftsSet().stream())

                    .flatMap(s -> s.getShiftEnrolmentsSet().stream())

                    .map(se -> se.getCreatedOn())

                    .filter(dt -> !dt.isBefore(enrolmentStartTime) && !dt.isAfter(endTimeToReport))

                    .map(dt -> new Interval(enrolmentStartTime, dt).toDuration().getStandardSeconds())

                    .forEach(seconds -> add(semester, seconds, new int[] { 0, 0, 1 }));
        }
    }

    public JsonArray getStats() {
        return getStats("registrations", "enrolments", "shifts");
    }

    private final Map<ExecutionSemester, Set<Registration>> registrationsBySemester = new HashMap<>();
    private SortedMap<ExecutionSemester, SortedMap<Long, int[]>> stats = new TreeMap<>();

    protected void process(final ExecutionSemester semester, final DateTime enrolmentStartTime,
            final CurriculumLineLog log) {
        final Long seconds = new Interval(enrolmentStartTime, log.getDateDateTime()).toDuration()
                .getStandardSeconds();
        int regCount = countRegistration(semester, log.getStudent()) ? 1 : 0;
        int enrolCount = log.getAction().equals(EnrolmentAction.ENROL) ? 1 : -1;
        add(semester, seconds, new int[] { regCount, enrolCount, 0 });
    }

    private boolean countRegistration(final ExecutionSemester semester, final Registration registration) {
        final Set<Registration> registrations = getRegistrations(semester);
        if (registrations.contains(registration)) {
            return false;
        }
        registrations.add(registration);
        return true;
    }

    private Set<Registration> getRegistrations(final ExecutionSemester semester) {
        if (!registrationsBySemester.containsKey(semester)) {
            registrationsBySemester.put(semester, new HashSet<Registration>());
        }
        return registrationsBySemester.get(semester);
    }

    public void add(final ExecutionSemester semester, final Long seconds, final int[] counts) {
        final SortedMap<Long, int[]> values = get(stats, semester);
        if (!values.containsKey(seconds)) {
            values.put(seconds, new int[counts.length]);
        }
        int[] ia = values.get(seconds);
        for (int i = 0; i < counts.length; ia[i] += counts[i++])
            ;
    }

    private static SortedMap<Long, int[]> get(final SortedMap<ExecutionSemester, SortedMap<Long, int[]>> map,
            final ExecutionSemester semester) {
        if (!map.containsKey(semester)) {
            map.put(semester, new TreeMap<Long, int[]>());
        }
        return map.get(semester);
    }

    private JsonArray getStats(String... labels) {
        final JsonArray result = new JsonArray();
        for (final Entry<ExecutionSemester, SortedMap<Long, int[]>> e : stats.entrySet()) {
            final String semester = e.getKey().getQualifiedName();

            int[] accumulatedValues = new int[labels.length];

            for (final Entry<Long, int[]> v : e.getValue().entrySet()) {
                final Long second = v.getKey();
                final int[] values = v.getValue();
                final JsonObject obj = new JsonObject();
                obj.addProperty("label", semester);
                obj.addProperty("second", second);
                for (int i = 0; i < labels.length; i++) {
                    int a = accumulatedValues[i] += values[i];
                    obj.addProperty(labels[i], a);
                }
                result.add(obj);
            }
        }
        return result;
    }

}