/** * Copyright © 2002 Instituto Superior Técnico * * 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.servlet.taglib.sop.v3; import java.io.IOException; import java.util.ArrayList; import java.util.Calendar; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Locale; import javax.servlet.jsp.JspException; import javax.servlet.jsp.JspWriter; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.tagext.TagSupport; import org.apache.struts.Globals; import org.apache.struts.util.MessageResources; import org.apache.struts.util.RequestUtils; import org.fenixedu.academic.dto.InfoCurricularYear; import org.fenixedu.academic.dto.InfoExecutionDegree; import org.fenixedu.academic.dto.InfoLesson; import org.fenixedu.academic.dto.InfoLessonInstance; import org.fenixedu.academic.dto.InfoLessonInstanceAggregation; import org.fenixedu.academic.dto.InfoShowOccupation; import org.fenixedu.academic.servlet.taglib.sop.v3.colorPickers.ClassTimeTableColorPicker; import org.fenixedu.academic.servlet.taglib.sop.v3.colorPickers.ExecutionCourseTimeTableColorPicker; import org.fenixedu.academic.servlet.taglib.sop.v3.colorPickers.RoomTimeTableColorPicker; import org.fenixedu.academic.servlet.taglib.sop.v3.renderers.ClassTimeTableLessonContentRenderer; import org.fenixedu.academic.servlet.taglib.sop.v3.renderers.ClassTimeTableWithoutLinksLessonContentRenderer; import org.fenixedu.academic.servlet.taglib.sop.v3.renderers.ExecutionCourseTimeTableLessonContentRenderer; import org.fenixedu.academic.servlet.taglib.sop.v3.renderers.RoomTimeTableLessonContentRenderer; import org.fenixedu.academic.servlet.taglib.sop.v3.renderers.ShiftEnrollmentTimeTableLessonContentRenderer; import org.fenixedu.academic.servlet.taglib.sop.v3.renderers.ShiftTimeTableLessonContentRenderer; import org.fenixedu.academic.servlet.taglib.sop.v3.renderers.SopClassRoomTimeTableLessonContentRenderer; import org.fenixedu.academic.servlet.taglib.sop.v3.renderers.SopClassTimeTableLessonContentRenderer; import org.fenixedu.academic.servlet.taglib.sop.v3.renderers.SopRoomTimeTableLessonContentRenderer; import org.fenixedu.academic.servlet.taglib.sop.v3.renderers.SpaceManagerRoomTimeTableLessonContentRenderer; import org.fenixedu.academic.ui.struts.action.resourceAllocationManager.utils.PresentationConstants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public final class RenderTimeTableTag extends TagSupport { private static final Integer DEFAULT_END_TIME = 0; private static final Logger logger = LoggerFactory.getLogger(RenderTimeTableTag.class); private LessonSlotContentRenderer lessonSlotContentRenderer = null; private int type = 1; private String application = ""; private String studentID = ""; private String classID = ""; private String executionCourseID = ""; private String executionSemesterID = ""; private String action = ""; private String endTime = ""; private Integer endTimeTableHour = new Integer(24); private final Integer slotSizeMinutes = new Integer(30); private boolean definedWidth = true; private ColorPicker colorPicker; // Nome do atributo que cont�m a lista de aulas. private String name; // Mensagens de erro. protected static MessageResources messages = MessageResources.getMessageResources("PublicDegreeInformation"); private InfoCurricularYear infoCurricularYear = null; private InfoExecutionDegree infoExecutionDegree = null; public String getName() { return (this.name); } public void setName(String name) { this.name = name; } @Override public int doStartTag() throws JspException { try { infoCurricularYear = (InfoCurricularYear) pageContext.findAttribute(PresentationConstants.CURRICULAR_YEAR); infoExecutionDegree = (InfoExecutionDegree) pageContext.findAttribute(PresentationConstants.EXECUTION_DEGREE); } catch (ClassCastException e) { infoCurricularYear = null; infoExecutionDegree = null; } setLessonSlotRendererAndColorPicker(); Integer startTimeTableHour = Integer.MAX_VALUE; this.endTimeTableHour = DEFAULT_END_TIME; List<InfoShowOccupation> infoLessonList = null; try { infoLessonList = (List<InfoShowOccupation>) pageContext.findAttribute(name); if (infoLessonList.size() > 0) { for (InfoShowOccupation occupation : infoLessonList) { // Calculate start hour based on earliest event if (occupation.getFirstHourOfDay() < startTimeTableHour) { startTimeTableHour = occupation.getFirstHourOfDay(); } // Calculate end hour based on latest event if (occupation.getLastHourOfDay() > this.endTimeTableHour) { this.endTimeTableHour = occupation.getLastHourOfDay(); } } } else { startTimeTableHour = DEFAULT_END_TIME; this.endTimeTableHour = DEFAULT_END_TIME + 1; } } catch (ClassCastException e) { logger.error(e.getMessage(), e); infoLessonList = null; } if (infoLessonList == null) { throw new JspException(messages.getMessage("gerarHorario.listaAulas.naoExiste", name)); } // Gera o hor�rio a partir da lista de aulas. Locale locale = (Locale) pageContext.findAttribute(Globals.LOCALE_KEY); JspWriter writer = pageContext.getOut(); TimeTable timeTable = generateTimeTable(infoLessonList, locale, pageContext, startTimeTableHour); TimeTableRenderer renderer = new TimeTableRenderer(timeTable, lessonSlotContentRenderer, this.slotSizeMinutes, startTimeTableHour, this.endTimeTableHour, colorPicker); try { writer.print(renderer.render(locale, pageContext, getDefinedWidth())); writer.print(legenda(infoLessonList, locale)); } catch (IOException e) { throw new JspException(messages.getMessage("gerarHorario.io", e.toString())); } return (SKIP_BODY); } private boolean hasLessonBefore8(final List<InfoShowOccupation> infoLessonList) { for (final InfoShowOccupation infoShowOccupation : infoLessonList) { if (infoShowOccupation.getFirstHourOfDay() < 8) { return true; } } return false; } /** * Method generateTimeTable. * * @param startTimeTableHour * * @param listaAulas * @return TimeTable */ private TimeTable generateTimeTable(List lessonList, Locale locale, PageContext pageContext, Integer startTimeTableHour) { Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.HOUR_OF_DAY, startTimeTableHour.intValue()); calendar.set(Calendar.MINUTE, 0); Integer numberOfDays = new Integer(6); Integer numberOfHours = new Integer((endTimeTableHour.intValue() - startTimeTableHour.intValue()) * (60 / slotSizeMinutes.intValue())); TimeTable timeTable = new TimeTable(numberOfHours, numberOfDays, calendar, slotSizeMinutes, locale, pageContext); Iterator lessonIterator = lessonList.iterator(); while (lessonIterator.hasNext()) { InfoShowOccupation infoShowOccupation = (InfoShowOccupation) lessonIterator.next(); timeTable.addLesson(infoShowOccupation); } return timeTable; } @Override public int doEndTag() { return (EVAL_PAGE); } @Override public void release() { super.release(); this.application = null; this.studentID = null; this.classID = null; this.executionCourseID = null; this.executionSemesterID = null; this.action = null; this.endTime = null; } private String getMessageResource(PageContext pageContext, String key) { try { return RequestUtils.message(pageContext, "PUBLIC_DEGREE_INFORMATION", Globals.LOCALE_KEY, key); } catch (JspException e) { return "???" + key + "???"; } } private StringBuilder legenda(List listaAulas, Locale locale) { StringBuilder result = new StringBuilder(""); List<SubtitleEntry> listaAuxiliar = new ArrayList<SubtitleEntry>(); Iterator<InfoShowOccupation> iterator = listaAulas.iterator(); while (iterator.hasNext()) { InfoShowOccupation elem = iterator.next(); if (elem instanceof InfoLesson || elem instanceof InfoLessonInstance || elem instanceof InfoLessonInstanceAggregation) { SubtitleEntry subtitleEntry = new SubtitleEntry(elem.getInfoShift().getInfoDisciplinaExecucao().getSigla(), elem.getInfoShift() .getInfoDisciplinaExecucao().getNome()); if (!listaAuxiliar.contains(subtitleEntry)) { listaAuxiliar.add(subtitleEntry); } } } if (listaAuxiliar.size() > 1) { Collections.sort(listaAuxiliar); result.append("<br/><b>"); result.append(getMessageResource(pageContext, "public.degree.information.label.legend")); result.append("</b><br /><br /><table cellpadding='0' cellspacing='0' style='margin-left:5px'>"); for (int i = 0; i < listaAuxiliar.size(); i++) { SubtitleEntry elem = listaAuxiliar.get(i); boolean oddElement = (i % 2 == 1); if (!oddElement) { result.append("<tr>\r\n"); } result.append("<td width='60'><b>"); result.append(elem.getKey()); result.append("</b></td><td style='vertical-align:top'>-</td><td>"); result.append(elem.getValue()); result.append("</td>"); if (oddElement) { result.append("</tr>\r\n"); } } if (listaAuxiliar.size() % 2 == 1) { result.append("<td colspan='3'> </td></tr>"); } // TODO(rspl): Will it stay like this the interface for showing // the legend of a quinzenal lesson? result.append("<tr><td style='vertical-align:top'><b>[Q]</b></td>"); result.append("<td style='vertical-align:top'>-</td>"); result.append("<td>"); result.append(getMessageResource(pageContext, "public.degree.information.label.biweekly")); result.append("</td></tr>"); result.append("</table>"); } return result; } /** * Returns the type. * * @return int */ public int getType() { return type; } /** * Sets the type. * * @param timeTableType * The type to set */ public void setType(int timeTableType) { this.type = timeTableType; setLessonSlotRendererAndColorPicker(); } private void setLessonSlotRendererAndColorPicker() { switch (this.type) { case TimeTableType.SHIFT_TIMETABLE: this.lessonSlotContentRenderer = new ShiftTimeTableLessonContentRenderer(); this.colorPicker = new ClassTimeTableColorPicker(); break; case TimeTableType.EXECUTION_COURSE_TIMETABLE: this.lessonSlotContentRenderer = new ExecutionCourseTimeTableLessonContentRenderer(); this.colorPicker = new ExecutionCourseTimeTableColorPicker(); break; case TimeTableType.ROOM_TIMETABLE: this.lessonSlotContentRenderer = new RoomTimeTableLessonContentRenderer(); this.colorPicker = new RoomTimeTableColorPicker(); break; case TimeTableType.SOP_CLASS_TIMETABLE: this.lessonSlotContentRenderer = new SopClassTimeTableLessonContentRenderer(infoExecutionDegree, infoCurricularYear); this.colorPicker = new ClassTimeTableColorPicker(); break; case TimeTableType.SOP_ROOM_TIMETABLE: this.lessonSlotContentRenderer = new SopRoomTimeTableLessonContentRenderer(); this.colorPicker = new ClassTimeTableColorPicker(); break; case TimeTableType.SPACE_MANAGER_TIMETABLE: this.lessonSlotContentRenderer = new SpaceManagerRoomTimeTableLessonContentRenderer(); this.colorPicker = new ClassTimeTableColorPicker(); break; case TimeTableType.SOP_CLASS_ROOM_TIMETABLE: this.lessonSlotContentRenderer = new SopClassRoomTimeTableLessonContentRenderer(); this.colorPicker = new ClassTimeTableColorPicker(); break; case TimeTableType.CLASS_TIMETABLE_WITHOUT_LINKS: this.lessonSlotContentRenderer = new ClassTimeTableWithoutLinksLessonContentRenderer(); this.colorPicker = new ClassTimeTableColorPicker(); break; case TimeTableType.CLASS_TIMETABLE: this.lessonSlotContentRenderer = new ClassTimeTableWithLinksLessonContentRenderer(getApplication()); this.colorPicker = new ClassTimeTableColorPicker(); break; case TimeTableType.SHIFT_ENROLLMENT_TIMETABLE: this.lessonSlotContentRenderer = new ShiftEnrollmentTimeTableLessonContentRenderer(getStudentID(), getApplication(), getClassID(), getExecutionCourseID(), getExecutionSemesterID(), getAction()); this.colorPicker = new ClassTimeTableColorPicker(); Integer defaultTime = new Integer(19); Integer endTime = defaultTime; if (!getEndTime().equals("")) { endTime = new Integer(getEndTime()); if (endTime < defaultTime) { endTime = defaultTime; } } this.endTimeTableHour = endTime; break; default: this.lessonSlotContentRenderer = new ClassTimeTableLessonContentRenderer(); this.colorPicker = new ClassTimeTableColorPicker(); break; } } /** * @return Returns the application. */ public String getApplication() { return application; } /** * @param application * The application to set. */ public void setApplication(String application) { this.application = application; } public String getStudentID() { return studentID; } public void setStudentID(String studentID) { this.studentID = studentID; } public String getAction() { return action; } public void setAction(String action) { this.action = action; } public String getClassID() { return classID; } public void setClassID(String classID) { this.classID = classID; } public String getExecutionCourseID() { return executionCourseID; } public void setExecutionCourseID(String executionCourseID) { this.executionCourseID = executionCourseID; } public String getExecutionSemesterID() { return executionSemesterID; } public void setExecutionSemesterID(String executionSemesterID) { this.executionSemesterID = executionSemesterID; } public String getEndTime() { return endTime; } public void setEndTime(String endTime) { this.endTime = endTime; } public boolean getDefinedWidth() { return definedWidth; } public void setDefinedWidth(boolean definedWidth) { this.definedWidth = definedWidth; } }