package net.sourceforge.fenixedu.presentationTier.jsf.components; import java.io.IOException; import java.text.DateFormatSymbols; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.List; import java.util.Locale; import javax.faces.component.NamingContainer; import javax.faces.component.UIInput; import javax.faces.context.FacesContext; import javax.faces.context.ResponseWriter; import net.sourceforge.fenixedu.presentationTier.jsf.components.util.CalendarLink; import net.sourceforge.fenixedu.presentationTier.servlets.filters.ContentInjectionRewriter; import pt.utl.ist.fenix.tools.util.DateFormatUtil; public class UIFenixCalendar extends UIInput { public static final String COMPONENT_TYPE = "net.sourceforge.fenixedu.presentationTier.jsf.components.UIFenixCalendar"; public static final String COMPONENT_FAMILY = "net.sourceforge.fenixedu.presentationTier.jsf.components.UIFenixCalendar"; public UIFenixCalendar() { super(); this.setRendererType(null); } public String getFamily() { return UIFenixCalendar.COMPONENT_FAMILY; } public void encodeBegin(FacesContext context) throws IOException { if (!isRendered()) { return; } ResponseWriter writer = context.getResponseWriter(); Calendar begin = getDateArgument("begin"); Calendar end = getDateArgument("end"); if (begin == null || end == null) { writer.write(""); } else if (end.before(begin)) { writer.write(""); } else { if (begin.get(Calendar.MONTH) == end.get(Calendar.MONTH)) { encodeMonthTable(writer, context, "MONTH" + begin.get(Calendar.MONTH), begin, end); } else { boolean isFirst = true; for (; begin.before(end); setToFirstDayOfNextMonth(begin)) { Calendar endPeriod = Calendar.getInstance(); endPeriod.setTime(begin.getTime()); endPeriod.set(Calendar.DAY_OF_MONTH, begin.getActualMaximum(Calendar.DAY_OF_MONTH)); if (endPeriod.after(end)) { endPeriod.setTime(end.getTime()); } if (isFirst) { isFirst = false; } else { writer.append("
"); } encodeMonthTable(writer, context, "MONTH" + begin.get(Calendar.MONTH), begin, endPeriod); } } } } private Calendar getDateArgument(String argumentName) { final Object object = this.getAttributes().get(argumentName); if (object instanceof Calendar) { return (Calendar) object; } else if (object instanceof Date && object != null) { final Calendar calendar = Calendar.getInstance(); calendar.setTime((Date) object); return calendar; } else { return null; } } private static void setToFirstDayOfNextMonth(Calendar date) { if (date.get(Calendar.MONTH) < 11) { date.roll(Calendar.MONTH, true); } else { date.roll(Calendar.MONTH, true); date.roll(Calendar.YEAR, true); } date.set(Calendar.DAY_OF_MONTH, 1); } private void encodeMonthTable(ResponseWriter writer, FacesContext context, String key, Calendar begin, Calendar end) throws IOException { writer.startElement("table", this); writer.writeAttribute("class", "fenixCalendar", null); // writer.writeAttribute("class", "fenixCalendar breakafter", null); // writer.writeAttribute("name", getFieldKey(context, key), null); encodeMonthRow(writer, begin, context.getViewRoot().getLocale()); encodeDaysOfWeek(writer, context.getViewRoot().getLocale()); encodeWeeks(writer, begin, end); writer.endElement("table"); writer.startElement("br", this); writer.endElement("br"); } private String getFieldKey(FacesContext context, String key) { return new String(this.getClientId(context) + NamingContainer.SEPARATOR_CHAR + key); } private void encodeMonthRow(ResponseWriter writer, Calendar date, Locale locale) throws IOException { // writer.startElement("tr", this); // writer.startElement("td", this); writer.startElement("caption", this); writer.writeAttribute("class", "fenixCalendar_monthRow", null); // writer.writeAttribute("colspan", 6, null); SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm", locale); DateFormatSymbols dfs = sdf.getDateFormatSymbols(); writer.write((dfs.getMonths())[date.get(Calendar.MONTH)]); writer.endElement("caption"); // writer.endElement("td"); // writer.endElement("tr"); } private void encodeDaysOfWeek(ResponseWriter writer, Locale locale) throws IOException { writer.startElement("tr", this); writer.writeAttribute("class", "fenixCalendar_daysOfWeek", null); SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm", locale); DateFormatSymbols dfs = sdf.getDateFormatSymbols(); encodeDayOfWeek(writer, (dfs.getWeekdays())[Calendar.MONDAY]); encodeDayOfWeek(writer, (dfs.getWeekdays())[Calendar.TUESDAY]); encodeDayOfWeek(writer, (dfs.getWeekdays())[Calendar.WEDNESDAY]); encodeDayOfWeek(writer, (dfs.getWeekdays())[Calendar.THURSDAY]); encodeDayOfWeek(writer, (dfs.getWeekdays())[Calendar.FRIDAY]); encodeDayOfWeek(writer, (dfs.getWeekdays())[Calendar.SATURDAY]); writer.endElement("tr"); } private void encodeDayOfWeek(ResponseWriter writer, String dayLabel) throws IOException { writer.startElement("th", this); writer.write(dayLabel); writer.endElement("th"); } private void encodeWeeks(ResponseWriter writer, Calendar begin, Calendar end) throws IOException { String createLink = (String) this.getAttributes().get("createLink"); String editLinkPage = (String) this.getAttributes().get("editLinkPage"); List editLinkParameters = (List) this.getAttributes().get("editLinkParameters"); Calendar now = Calendar.getInstance(); Calendar iter = Calendar.getInstance(); iter.setTime(begin.getTime()); for (int beginWeek = begin.get(Calendar.WEEK_OF_MONTH); beginWeek <= end.get(Calendar.WEEK_OF_MONTH); beginWeek++) { writer.startElement("tr", this); writer.writeAttribute("class", "fenixCalendar_weekRow", null); for (int beginDayOfWeek = Calendar.MONDAY; beginDayOfWeek <= Calendar.SATURDAY; beginDayOfWeek++) { if (iter.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) { doMonthAwareRoll(iter); } if (iter.after(end)) { writer.startElement("td", this); appendExtraLines(writer); writer.endElement("td"); } else if (iter.get(Calendar.DAY_OF_WEEK) == beginDayOfWeek) { writer.startElement("td", this); List toDisplay = objectsToDisplayOnThisDay(iter, editLinkParameters); if (toDisplay != null && !toDisplay.isEmpty()) { writer.writeAttribute("class", "fenixCalendar_dayWithObjectOccurence", null); encodeDay(writer, createLink, now, iter); for (CalendarLink calendarLink : toDisplay) { writer.startElement("br", this); writer.endElement("br"); if (calendarLink.isAsLink()) { writer.append(ContentInjectionRewriter.HAS_CONTEXT_PREFIX); writer.startElement("a", this); writer.writeAttribute("style", "text-decoration:none", null); writer.writeAttribute("href", calendarLink.giveLink(editLinkPage), null); } writer.write(calendarLink.getObjectLinkLabel()); if (calendarLink.isAsLink()) { writer.endElement("a"); } } } else { writer.writeAttribute("class", "fenixCalendar_defaultDay", null); encodeDay(writer, createLink, now, iter); } appendExtraLines(writer); writer.endElement("td"); doMonthAwareRoll(iter); } else { writer.startElement("td", this); appendExtraLines(writer); writer.endElement("td"); } } writer.endElement("tr"); } } private void appendExtraLines(final ResponseWriter writer) throws IOException { final String extraLines = (String) this.getAttributes().get("extraLines"); if (extraLines != null && extraLines.length() > 0 && Boolean.valueOf(extraLines).equals(Boolean.TRUE)) { writer.startElement("br", this); writer.endElement("br"); writer.startElement("br", this); writer.endElement("br"); writer.startElement("br", this); writer.endElement("br"); writer.startElement("br", this); writer.endElement("br"); writer.startElement("br", this); writer.endElement("br"); writer.startElement("br", this); writer.endElement("br"); } } private void encodeDay(ResponseWriter writer, String createLink, Calendar now, Calendar iter) throws IOException { if (createLink == null || iter.before(now)) { writer.write(Integer.valueOf(iter.get(Calendar.DAY_OF_MONTH)).toString()); } else { writer.append(ContentInjectionRewriter.HAS_CONTEXT_PREFIX); writer.startElement("a", this); writer.writeAttribute("style", "text-decoration:none", null); writer.writeAttribute("href", createLink + dateLink(iter), null); writer.write(Integer.valueOf(iter.get(Calendar.DAY_OF_MONTH)).toString()); writer.endElement("a"); } } private List objectsToDisplayOnThisDay(Calendar iter, List editLinkParameters) { List result = new ArrayList(); for (CalendarLink calendarLink : editLinkParameters) { if (calendarLink.getObjectOccurrence().get(Calendar.DAY_OF_MONTH) == iter.get(Calendar.DAY_OF_MONTH) && calendarLink.getObjectOccurrence().get(Calendar.MONTH) == iter.get(Calendar.MONTH) && calendarLink.getObjectOccurrence().get(Calendar.YEAR) == iter.get(Calendar.YEAR)) { result.add(calendarLink); } } return result; } private void doMonthAwareRoll(Calendar date) { if (date.get(Calendar.DAY_OF_MONTH) < date.getActualMaximum(Calendar.DAY_OF_MONTH)) { date.roll(Calendar.DAY_OF_MONTH, true); } else { date.roll(Calendar.DAY_OF_MONTH, true); date.roll(Calendar.MONTH, true); } } private String dateLink(Calendar date) { final StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append("&day="); stringBuilder.append(date.get(Calendar.DAY_OF_MONTH)); stringBuilder.append("&month="); stringBuilder.append((date.get(Calendar.MONTH) + 1)); stringBuilder.append("&year="); stringBuilder.append(date.get(Calendar.YEAR)); stringBuilder.append("&selectedDate="); stringBuilder.append(DateFormatUtil.format("dd/MM/yyyy", date.getTime())); return stringBuilder.toString(); } }