net.sourceforge.fenixedu.presentationTier.Action.resourceAllocationManager.ViewAllRoomsSchedulesDA.java Source code

Java tutorial

Introduction

Here is the source code for net.sourceforge.fenixedu.presentationTier.Action.resourceAllocationManager.ViewAllRoomsSchedulesDA.java

Source

/**
 * Copyright  2002 Instituto Superior Tcnico
 *
 * This file is part of FenixEdu Core.
 *
 * FenixEdu Core 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 Core 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 Core.  If not, see <http://www.gnu.org/licenses/>.
 */
package net.sourceforge.fenixedu.presentationTier.Action.resourceAllocationManager;

import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.Set;
import java.util.TreeSet;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sourceforge.fenixedu.dataTransferObject.InfoLesson;
import net.sourceforge.fenixedu.domain.CourseLoad;
import net.sourceforge.fenixedu.domain.ExecutionCourse;
import net.sourceforge.fenixedu.domain.ExecutionDegree;
import net.sourceforge.fenixedu.domain.ExecutionInterval;
import net.sourceforge.fenixedu.domain.ExecutionSemester;
import net.sourceforge.fenixedu.domain.ExecutionYear;
import net.sourceforge.fenixedu.domain.Lesson;
import net.sourceforge.fenixedu.domain.LessonInstance;
import net.sourceforge.fenixedu.domain.Professorship;
import net.sourceforge.fenixedu.domain.SchoolClass;
import net.sourceforge.fenixedu.domain.Shift;
import net.sourceforge.fenixedu.domain.space.LessonSpaceOccupation;
import net.sourceforge.fenixedu.domain.space.SpaceUtils;
import net.sourceforge.fenixedu.domain.time.calendarStructure.AcademicInterval;
import net.sourceforge.fenixedu.domain.time.calendarStructure.AcademicPeriod;
import net.sourceforge.fenixedu.presentationTier.Action.base.FenixDispatchAction;
import net.sourceforge.fenixedu.presentationTier.Action.resourceAllocationManager.RAMApplication.RAMSchedulesApp;
import net.sourceforge.fenixedu.util.Bundle;
import org.fenixedu.bennu.core.i18n.BundleUtil;
import net.sourceforge.fenixedu.util.HourMinuteSecond;
import net.sourceforge.fenixedu.util.WeekDay;

import org.apache.commons.lang.StringUtils;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.fenixedu.bennu.portal.EntryPoint;
import org.fenixedu.bennu.portal.StrutsFunctionality;
import org.fenixedu.commons.i18n.I18N;
import org.fenixedu.spaces.domain.Space;
import org.fenixedu.spaces.domain.SpaceClassification;
import org.joda.time.DateTime;

import pt.ist.fenixWebFramework.renderers.utils.RenderUtils;
import pt.ist.fenixWebFramework.struts.annotations.Forward;
import pt.ist.fenixWebFramework.struts.annotations.Forwards;
import pt.ist.fenixWebFramework.struts.annotations.Mapping;
import pt.utl.ist.fenix.tools.util.excel.Spreadsheet;
import pt.utl.ist.fenix.tools.util.excel.Spreadsheet.Row;

import com.google.common.collect.Ordering;

/**
 * @author Luis Cruz e Sara Ribeiro
 */
@StrutsFunctionality(app = RAMSchedulesApp.class, path = "room-schedules", titleKey = "link.schedules.listAllByRoom")
@Mapping(path = "/viewAllRoomsSchedulesDA", module = "resourceAllocationManager")
@Forwards({ @Forward(name = "choose", path = "/resourceAllocationManager/choosePavillionsToViewRoomsSchedules.jsp"),
        @Forward(name = "list", path = "/resourceAllocationManager/viewAllRoomsSchedules.jsp") })
public class ViewAllRoomsSchedulesDA extends FenixDispatchAction {

    public static class ChooseBuildingBean implements Serializable {

        private static final long serialVersionUID = -663198492313971329L;

        private AcademicInterval academicInterval;
        private List<Space> selectedBuildings;

        public ChooseBuildingBean() {
            this.academicInterval = AcademicInterval.readDefaultAcademicInterval(AcademicPeriod.SEMESTER);
        }

        public AcademicInterval getAcademicInterval() {
            return academicInterval;
        }

        public void setAcademicInterval(AcademicInterval academicInterval) {
            this.academicInterval = academicInterval;
        }

        public List<Space> getAvailableBuildings() {
            return Ordering.from(SpaceUtils.COMPARATOR_BY_PRESENTATION_NAME).sortedCopy(SpaceUtils.buildings());
        }

        public List<AcademicInterval> getAvailableIntervals() {
            return Ordering.from(AcademicInterval.COMPARATOR_BY_BEGIN_DATE).reverse()
                    .sortedCopy(AcademicInterval.readAcademicIntervals(AcademicPeriod.SEMESTER));
        }

        public List<Space> getSelectedBuildings() {
            return selectedBuildings;
        }

        public void setSelectedBuildings(List<Space> selectedBuildings) {
            this.selectedBuildings = selectedBuildings;
        }
    }

    @EntryPoint
    public ActionForward choose(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        ChooseBuildingBean bean = getRenderedObject();
        if (bean == null) {
            bean = new ChooseBuildingBean();
        }
        RenderUtils.invalidateViewState();
        request.setAttribute("bean", bean);
        return mapping.findForward("choose");
    }

    public ActionForward list(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        ChooseBuildingBean bean = getRenderedObject();

        List<Space> rooms = new ArrayList<Space>();
        for (Space building : bean.getSelectedBuildings()) {
            rooms.addAll(SpaceUtils.getAllActiveSubRoomsForEducation(building));
        }

        final List<RoomLessonsBean> beans = new ArrayList<RoomLessonsBean>();
        for (final Space room : rooms) {
            if (!StringUtils.isEmpty(room.getName())) {
                final List<Lesson> lessons = SpaceUtils.getAssociatedLessons(room, bean.getAcademicInterval());
                final List<InfoLesson> infoLessons = new ArrayList<InfoLesson>(lessons.size());
                for (Lesson lesson : lessons) {
                    infoLessons.add(InfoLesson.newInfoFromDomain(lesson));
                }
                beans.add(new RoomLessonsBean(room, infoLessons));
            }
        }

        request.setAttribute("academicInterval", bean.getAcademicInterval());
        request.setAttribute("beans", beans);
        return mapping.findForward("list");
    }

    public static class RoomLessonsBean {
        private final Space room;
        private final List<InfoLesson> lessons;

        public RoomLessonsBean(Space room, List<InfoLesson> lessons) {
            super();
            this.room = room;
            this.lessons = lessons;
        }

        public Space getRoom() {
            return room;
        }

        public List<InfoLesson> getLessons() {
            return lessons;
        }

    }

    private static final int WEEKDAY_COUNT = 6;
    private static final int HOUR_COUNT = (24 - 8) * 2;

    private static class RoomMap extends HashMap<Space, boolean[][]> {

        @Override
        public boolean[][] get(final Object key) {
            boolean[][] value = super.get(key);
            if (value == null) {
                value = new boolean[WEEKDAY_COUNT][HOUR_COUNT];
                put((Space) key, value);
            }
            return value;
        }

        public void register(final Space allocatableSpace) {
            if (allocatableSpace != null) {
                get(allocatableSpace);
            }
        }

        public void register(final Lesson lesson) {
            final LessonSpaceOccupation lessonSpaceOccupation = lesson.getLessonSpaceOccupation();
            if (lessonSpaceOccupation != null) {
                final Space allocatableSpace = lessonSpaceOccupation.getRoom();
                if (allocatableSpace != null) {
                    final boolean[][] slots = get(allocatableSpace);
                    final int weekDayOffSet = lesson.getDiaSemana().getDiaSemana().intValue() - 2;
                    final int startOffSet = getHourOffSet(lesson.getBeginHourMinuteSecond());
                    final int endOffSet = getHourOffSet(lesson.getEndHourMinuteSecond());
                    for (int i = startOffSet; i < endOffSet; slots[weekDayOffSet][i++] = true) {
                        ;
                    }
                }
            }
            for (final LessonInstance lessonInstance : lesson.getLessonInstancesSet()) {
                final Space allocatableSpace = lessonInstance.getRoom();
                if (allocatableSpace != null) {
                    final boolean[][] slots = get(allocatableSpace);
                    final int weekDayOffSet = lessonInstance.getBeginDateTime().getDayOfWeek() - 1;
                    final int startOffSet = getHourOffSet(lessonInstance.getBeginDateTime());
                    final int endOffSet = getHourOffSet(lessonInstance.getEndDateTime());
                    for (int i = startOffSet; i < endOffSet; slots[weekDayOffSet][i++] = true) {
                        ;
                    }
                }
            }
        }

        private int getHourOffSet(final HourMinuteSecond hourMinuteSecond) {
            final int hour = hourMinuteSecond.getHour();
            final int minutes = hourMinuteSecond.getMinuteOfHour();
            final int minutesOffSet = minutes < 30 ? 0 : 1;
            return ((hour - 8) * 2) + minutesOffSet;
        }

        private int getHourOffSet(final DateTime dateTime) {
            final int hour = dateTime.getHourOfDay();
            final int minutes = dateTime.getMinuteOfHour();
            final int minutesOffSet = minutes < 30 ? 0 : 1;
            return ((hour - 8) * 2) + minutesOffSet;
        }

    }

    public ActionForward downloadRoomLessonOccupationInfo(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response) throws IOException {
        final ExecutionSemester executionSemester = getExecutionSemester(request);

        final ExecutionYear executionYear = executionSemester.getExecutionYear();

        response.setContentType("application/vnd.ms-excel");
        response.setHeader("Content-disposition", "attachment; filename=occupationMap"
                + executionYear.getYear().replace('/', '_') + "_" + executionSemester.getSemester() + ".xls");

        final RoomMap occupationMap = new RoomMap();

        Space.getSpaces().forEach(s -> occupationMap.register(s));

        for (final ExecutionCourse executionCourse : executionSemester.getAssociatedExecutionCoursesSet()) {
            for (final CourseLoad courseLoad : executionCourse.getCourseLoadsSet()) {
                for (final Shift shift : courseLoad.getShiftsSet()) {
                    for (final Lesson lesson : shift.getAssociatedLessonsSet()) {
                        occupationMap.register(lesson);
                    }
                }
            }
        }

        final Spreadsheet spreadsheet = new Spreadsheet("OccupationMap");
        spreadsheet.setHeader(BundleUtil.getString(Bundle.APPLICATION, "label.building"));
        spreadsheet.setHeader(BundleUtil.getString(Bundle.APPLICATION, "label.identification"));
        spreadsheet.setHeader(BundleUtil.getString(Bundle.APPLICATION, "label.blueprintNumber"));
        spreadsheet.setHeader(BundleUtil.getString(Bundle.APPLICATION, "label.doorNumber"));
        spreadsheet.setHeader(BundleUtil.getString(Bundle.APPLICATION, "label.description"));
        spreadsheet.setHeader(BundleUtil.getString(Bundle.APPLICATION, "label.classification"));
        final DateTime now = new DateTime();
        for (int weekDay = 0; weekDay < 6; weekDay++) {
            final DateTime dateTime = now.withDayOfWeek(weekDay + 1);
            final String weekDayString = dateTime.dayOfWeek().getAsText(I18N.getLocale());
            for (int hour = 0; hour < 16; hour++) {
                spreadsheet.setHeader(weekDayString + " " + (hour + 8) + ":00");
                spreadsheet.setHeader(weekDayString + " " + (hour + 8) + ":30");
            }
        }
        for (final Entry<Space, boolean[][]> entry : occupationMap.entrySet()) {
            final Space space = entry.getKey();
            final String identification = space.getName();
            final Space building = SpaceUtils.getSpaceBuilding(space);
            final String buildingName = building == null ? "" : building.getPresentationName();
            final boolean[][] slots = entry.getValue();

            final Row row = spreadsheet.addRow();
            row.setCell(buildingName);
            row.setCell(identification == null ? " " : identification);
            final String blueprintNumber = findClosestBlueprintNumber(space);
            row.setCell(blueprintNumber);
            if (SpaceUtils.isRoom(space)) {
                Optional<String> doorNumber = space.getMetadata("doorNumber");
                Optional<String> description = space.getMetadata("description");
                row.setCell(doorNumber.isPresent() ? doorNumber.get() : " ");
                row.setCell(description.isPresent() ? description.get() : " ");
            } else if (SpaceUtils.isRoomSubdivision(space)) {
                final Space room = findSurroundingRoom(space);
                if (room == null) {
                    row.setCell(" ");
                    row.setCell(" ");
                } else {
                    Optional<String> doorNumber = space.getMetadata("doorNumber");
                    Optional<String> description = space.getMetadata("description");
                    row.setCell(doorNumber.isPresent() ? doorNumber.get() : " ");
                    row.setCell(description.isPresent() ? description.get() : " ");
                }
            } else {
                row.setCell(" ");
                row.setCell(" ");
            }
            SpaceClassification classification = space.getClassification();
            if (classification == null) {
                row.setCell(" ");
            } else {
                row.setCell(classification.getAbsoluteCode() + " " + classification.getName().getContent());
            }

            for (int i = 0; i < WEEKDAY_COUNT; i++) {
                for (int j = 0; j < HOUR_COUNT; j++) {
                    row.setCell(Boolean.toString(slots[i][j]));
                }
            }
        }

        final ServletOutputStream writer = response.getOutputStream();
        spreadsheet.exportToXLSSheet(writer);
        writer.flush();
        response.flushBuffer();
        return null;
    }

    private ExecutionSemester getExecutionSemester(HttpServletRequest request) {
        String academicIntervalString = (String) getFromRequest(request, "academicIntervalString");
        AcademicInterval academicInterval = AcademicInterval.getAcademicIntervalFromString(academicIntervalString);
        final ExecutionSemester executionSemester = (ExecutionSemester) ExecutionInterval
                .getExecutionInterval(academicInterval);
        return executionSemester;
    }

    private String findClosestBlueprintNumber(final Space space) {
        if (space == null) {
            return null;
        }
        return space.getBlueprintNumber().isPresent() ? space.getBlueprintNumber().get()
                : findClosestBlueprintNumber(space.getParent());
    }

    private Space findSurroundingRoom(final Space space) {
        final Space suroundingSpace = space.getParent();
        return suroundingSpace == null ? null
                : SpaceUtils.isRoom(space) ? suroundingSpace : findSurroundingRoom(suroundingSpace);
    }

    public ActionForward downloadScheduleList(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            HttpServletResponse response) throws IOException {
        final ExecutionSemester executionSemester = getExecutionSemester(request);
        final Integer semester = executionSemester.getSemester();
        final String executionYear = executionSemester.getExecutionYear().getYear();

        final Spreadsheet spreadsheet = new Spreadsheet("ScheduleMap");
        spreadsheet.setHeader(BundleUtil.getString(Bundle.APPLICATION, "label.executionPeriod"));
        spreadsheet.setHeader(BundleUtil.getString(Bundle.APPLICATION, "label.executionYear"));
        spreadsheet.setHeader(BundleUtil.getString(Bundle.APPLICATION, "label.executionCourse"));
        spreadsheet.setHeader(BundleUtil.getString(Bundle.APPLICATION, "label.executionDegree"));
        spreadsheet.setHeader(BundleUtil.getString(Bundle.APPLICATION, "label.curricular.year"));
        spreadsheet.setHeader(BundleUtil.getString(Bundle.APPLICATION, "label.shift"));
        spreadsheet.setHeader(BundleUtil.getString(Bundle.APPLICATION, "label.shift.schedule"));
        spreadsheet.setHeader(BundleUtil.getString(Bundle.APPLICATION, "label.shift.schedule.hasAllocatedRooms"));
        spreadsheet.setHeader(BundleUtil.getString(Bundle.APPLICATION, "label.teacher.emails"));
        spreadsheet.setHeader(BundleUtil.getString(Bundle.APPLICATION, "label.comments"));

        for (final ExecutionCourse executionCourse : executionSemester.getAssociatedExecutionCoursesSet()) {
            final StringBuilder executionDegreeBuilder = new StringBuilder();
            for (final ExecutionDegree executionDegree : executionCourse.getExecutionDegrees()) {
                if (executionDegreeBuilder.length() > 0) {
                    executionDegreeBuilder.append("\n");
                }
                executionDegreeBuilder.append(executionDegree.getDegree().getSigla());
            }
            final StringBuilder emailBuilder = new StringBuilder();
            for (final Professorship professorship : executionCourse.getProfessorshipsSet()) {
                if (emailBuilder.length() > 0) {
                    emailBuilder.append("\n");
                }
                emailBuilder.append(professorship.getPerson().getEmailForSendingEmails());
            }

            for (final CourseLoad courseLoad : executionCourse.getCourseLoadsSet()) {
                for (final Shift shift : courseLoad.getShiftsSet()) {
                    final Set<Integer> curricularYears = new TreeSet<Integer>();
                    for (final SchoolClass schoolClass : shift.getAssociatedClassesSet()) {
                        curricularYears.add(schoolClass.getAnoCurricular());
                    }
                    final StringBuilder curricularYearBuilder = new StringBuilder();
                    for (final Integer curricularYear : curricularYears) {
                        if (curricularYearBuilder.length() > 0) {
                            curricularYearBuilder.append(", ");
                        }
                        curricularYearBuilder.append(curricularYear);
                    }

                    final Row row = spreadsheet.addRow();
                    row.setCell(semester);
                    row.setCell(executionYear);
                    row.setCell(executionCourse.getName());
                    row.setCell(executionDegreeBuilder.toString());
                    row.setCell(curricularYearBuilder.toString());
                    row.setCell(shift.getNome());
                    row.setCell(shift.getLessonPresentationString().replace(';', '\n'));
                    row.setCell(hasRoomsAttributed(shift));
                    row.setCell(emailBuilder.toString());
                    row.setCell(shift.getComment() == null ? "" : shift.getComment());
                }
            }
        }

        response.setContentType("application/vnd.ms-excel");
        response.setHeader("Content-disposition", "attachment; filename=scheduleMap"
                + executionYear.replace('/', '_') + "_" + executionSemester.getSemester() + ".xls");

        final ServletOutputStream writer = response.getOutputStream();
        spreadsheet.exportToXLSSheet(writer);
        writer.flush();
        response.flushBuffer();
        return null;
    }

    public ActionForward downloadShiftAttendence(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            HttpServletResponse response) throws IOException {
        final ExecutionSemester executionSemester = getExecutionSemester(request);
        final String executionYear = executionSemester.getExecutionYear().getYear();

        final Spreadsheet spreadsheet = new Spreadsheet("ShiftAttendenceMap");
        spreadsheet.setHeader(BundleUtil.getString(Bundle.APPLICATION, "label.shift"));
        spreadsheet.setHeader(BundleUtil.getString(Bundle.APPLICATION, "label.executionCourse"));
        spreadsheet.setHeader(BundleUtil.getString(Bundle.APPLICATION, "label.executionDegree"));
        spreadsheet.setHeader(BundleUtil.getString(Bundle.APPLICATION, "label.shift.schedule"));
        spreadsheet.setHeader(BundleUtil.getString(Bundle.APPLICATION, "label.lesson.room"));
        spreadsheet.setHeader(BundleUtil.getString(Bundle.APPLICATION, "label.number.students.enrolled"));

        for (final ExecutionCourse executionCourse : executionSemester.getAssociatedExecutionCoursesSet()) {
            final StringBuilder executionDegreeBuilder = new StringBuilder();
            for (final ExecutionDegree executionDegree : executionCourse.getExecutionDegrees()) {
                if (executionDegreeBuilder.length() > 0) {
                    executionDegreeBuilder.append("\n");
                }
                executionDegreeBuilder.append(executionDegree.getDegree().getSigla());
            }
            final StringBuilder emailBuilder = new StringBuilder();
            for (final Professorship professorship : executionCourse.getProfessorshipsSet()) {
                if (emailBuilder.length() > 0) {
                    emailBuilder.append("\n");
                }
                emailBuilder.append(professorship.getPerson().getEmailForSendingEmails());
            }

            for (final CourseLoad courseLoad : executionCourse.getCourseLoadsSet()) {
                for (final Shift shift : courseLoad.getShiftsSet()) {
                    final Row row = spreadsheet.addRow();
                    final StringBuilder roomBuilder = new StringBuilder();
                    final StringBuilder scheduleBuilder = new StringBuilder();
                    if (!shift.getAssociatedLessonsSet().isEmpty()) {
                        for (Iterator<Lesson> iterator = shift.getAssociatedLessonsSet().iterator(); iterator
                                .hasNext();) {
                            Lesson lesson = iterator.next();
                            scheduleBuilder.append(WeekDay.getWeekDay(lesson.getDiaSemana()).getLabelShort());
                            scheduleBuilder.append(" ");
                            scheduleBuilder.append(lesson.getBeginHourMinuteSecond().toString("HH:mm"));
                            scheduleBuilder.append(" - ");
                            scheduleBuilder.append(lesson.getEndHourMinuteSecond().toString("HH:mm"));
                            if (lesson.hasSala()) {
                                roomBuilder.append(lesson.getSala().getName());
                            }
                            if (iterator.hasNext()) {
                                scheduleBuilder.append(" ; ");
                                roomBuilder.append(" ; ");
                            }
                        }
                    }

                    row.setCell(shift.getNome());
                    row.setCell(executionCourse.getName());
                    row.setCell(executionDegreeBuilder.toString());
                    row.setCell(scheduleBuilder.toString().replace(';', '\n'));
                    row.setCell(roomBuilder.toString().replace(';', '\n'));
                    row.setCell(shift.getStudentsSet().size());
                }
            }
        }

        response.setContentType("application/vnd.ms-excel");
        response.setHeader("Content-disposition", "attachment; filename=shiftAttendenceMap"
                + executionYear.replace('/', '_') + "_" + executionSemester.getSemester() + ".xls");

        final ServletOutputStream writer = response.getOutputStream();
        spreadsheet.exportToXLSSheet(writer);
        writer.flush();
        response.flushBuffer();
        return null;
    }

    private String hasRoomsAttributed(final Shift shift) {
        if (shift.getAssociatedLessonsSet().isEmpty()) {
            return BundleUtil.getString(Bundle.APPLICATION, "label.no");
        }
        for (final Lesson lesson : shift.getAssociatedLessonsSet()) {
            if (!hasRoomsAttributed(lesson)) {
                return BundleUtil.getString(Bundle.APPLICATION, "label.no");
            }
        }
        return BundleUtil.getString(Bundle.APPLICATION, "label.yes");
    }

    private boolean hasRoomsAttributed(final Lesson lesson) {
        return lesson.getSala() != null;
    }

}