Java tutorial
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package dk.teachus.frontend.components.calendar; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import org.apache.wicket.AttributeModifier; import org.apache.wicket.Component; import org.apache.wicket.ajax.AjaxEventBehavior; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.markup.html.list.ListItem; import org.apache.wicket.model.AbstractReadOnlyModel; import org.apache.wicket.model.IModel; import org.apache.wicket.model.LoadableDetachableModel; import org.apache.wicket.util.string.Strings; import org.joda.time.DateMidnight; import org.joda.time.DateTime; import org.joda.time.DateTimeConstants; import org.joda.time.LocalTime; import org.joda.time.PeriodType; import dk.teachus.backend.dao.BookingDAO; import dk.teachus.backend.domain.Booking; import dk.teachus.backend.domain.Bookings; import dk.teachus.backend.domain.DatePeriod; import dk.teachus.backend.domain.Period; import dk.teachus.backend.domain.Periods; import dk.teachus.backend.domain.Teacher; import dk.teachus.backend.domain.impl.CalendarNarrowTimesTeacherAttribute; import dk.teachus.frontend.TeachUsApplication; import dk.teachus.frontend.TeachUsSession; import dk.teachus.frontend.components.calendar.PeriodsCalendarPanel.PeriodBookingTimeSlotPayload; import dk.teachus.frontend.utils.Formatters; public abstract class PeriodsCalendarPanel extends CalendarPanel<PeriodBookingTimeSlotPayload> { private static final long serialVersionUID = 1L; public static class PeriodBookingTimeSlotPayload implements Serializable { private static final long serialVersionUID = 1L; private Period period; private Booking booking; public Period getPeriod() { return period; } public void setPeriod(Period period) { this.period = period; } public Booking getBooking() { return booking; } public void setBooking(Booking booking) { this.booking = booking; } } private class DefaultPeriodsModel extends LoadableDetachableModel<Periods> { private static final long serialVersionUID = 1L; @Override protected Periods load() { return TeachUsApplication.get().getPeriodDAO().getPeriods(getTeacher(), true); } } private IModel<List<DatePeriod>> datePeriodsModel; private IModel<Bookings> bookingsModel; public PeriodsCalendarPanel(String id, IModel<DateMidnight> weekDateModel) { this(id, weekDateModel, null); } public PeriodsCalendarPanel(String id, IModel<DateMidnight> weekDateModel, IModel<Periods> periodsModel) { super(id, weekDateModel); final IModel<Periods> thePeriodsModel; if (periodsModel == null) { thePeriodsModel = new DefaultPeriodsModel(); } else { thePeriodsModel = periodsModel; } this.datePeriodsModel = new LoadableDetachableModel<List<DatePeriod>>() { private static final long serialVersionUID = 1L; @Override protected List<DatePeriod> load() { Periods periods = thePeriodsModel.getObject(); return periods.generateDatesForWeek(PeriodsCalendarPanel.this.getModelObject()); } protected void onDetach() { thePeriodsModel.detach(); } }; bookingsModel = new LoadableDetachableModel<Bookings>() { private static final long serialVersionUID = 1L; @Override protected Bookings load() { BookingDAO bookingDAO = TeachUsApplication.get().getBookingDAO(); Bookings bookings = bookingDAO.getBookings(getTeacher(), getFromDate(), getToDate()); return bookings; } }; } @Override protected LocalTime getCalendarStartTime() { LocalTime calendarStartTime = super.getCalendarStartTime(); CalendarNarrowTimesTeacherAttribute narrowTimes = TeachUsSession.get() .getTeacherAttribute(CalendarNarrowTimesTeacherAttribute.class); if (narrowTimes != null && narrowTimes.getBooleanValue()) { LocalTime earliestStart = new LocalTime(23, 59, 59, 999); List<DatePeriod> periods = datePeriodsModel.getObject(); for (DatePeriod datePeriod : periods) { List<Period> periodList = datePeriod.getPeriods(); for (Period period : periodList) { LocalTime periodStartTime = period.getStartTime(); if (periodStartTime.isBefore(earliestStart)) { earliestStart = periodStartTime; } } } calendarStartTime = earliestStart; } return calendarStartTime; } @Override protected LocalTime getCalendarEndTime() { LocalTime calendarEndTime = super.getCalendarEndTime(); CalendarNarrowTimesTeacherAttribute narrowTimes = TeachUsSession.get() .getTeacherAttribute(CalendarNarrowTimesTeacherAttribute.class); if (narrowTimes != null && narrowTimes.getBooleanValue()) { LocalTime latestEnd = new LocalTime(0, 0, 0, 0); List<DatePeriod> periods = datePeriodsModel.getObject(); for (DatePeriod datePeriod : periods) { List<Period> periodList = datePeriod.getPeriods(); for (Period period : periodList) { LocalTime periodEndTime = period.getEndTime(); if (periodEndTime.isAfter(latestEnd)) { latestEnd = periodEndTime; } } } calendarEndTime = latestEnd; } return calendarEndTime; } private DateMidnight getFromDate() { return getModelObject().withDayOfWeek(DateTimeConstants.MONDAY); } private DateMidnight getToDate() { return getModelObject().withDayOfWeek(DateTimeConstants.SUNDAY); } @Override protected IModel<List<TimeSlot<PeriodBookingTimeSlotPayload>>> getTimeSlotModel(final DateMidnight date) { return new AbstractReadOnlyModel<List<TimeSlot<PeriodBookingTimeSlotPayload>>>() { private static final long serialVersionUID = 1L; @Override public List<TimeSlot<PeriodBookingTimeSlotPayload>> getObject() { List<TimeSlot<PeriodBookingTimeSlotPayload>> timeSlots = new ArrayList<TimeSlot<PeriodBookingTimeSlotPayload>>(); List<DatePeriod> periods = datePeriodsModel.getObject(); DatePeriod currentDatePeriod = null; for (DatePeriod datePeriod : periods) { if (datePeriod.getDate().equals(date)) { currentDatePeriod = datePeriod; break; } } if (currentDatePeriod != null) { List<Period> periodsList = currentDatePeriod.getPeriods(); for (Period period : periodsList) { DateTime startTime = period.getStartTime().toDateTime(date); DateTime endTime = period.getEndTime().toDateTime(date); DateTime time = startTime; while (time.isBefore(endTime)) { /* * Booking */ Bookings bookings = bookingsModel.getObject(); Booking booking = bookings.getBooking(period, time); PeriodBookingTimeSlotPayload payload = new PeriodBookingTimeSlotPayload(); payload.setPeriod(period); payload.setBooking(booking); timeSlots.add(new TimeSlot<PeriodBookingTimeSlotPayload>(time.toLocalTime(), time.toLocalTime().plusMinutes(period.getLessonDuration()), payload)); time = time.plusMinutes(period.getIntervalBetweenLessonStart()); } } } return timeSlots; } @Override public void detach() { datePeriodsModel.detach(); bookingsModel.detach(); } }; } @Override protected final List<String> getTimeSlotContent(final DateMidnight date, final TimeSlot<PeriodBookingTimeSlotPayload> timeSlot, final ListItem<TimeSlot<PeriodBookingTimeSlotPayload>> timeSlotItem) { // Click action timeSlotItem.add(new AjaxEventBehavior("onclick") { //$NON-NLS-1$ private static final long serialVersionUID = 1L; @Override protected void onEvent(AjaxRequestTarget target) { onTimeSlotClicked(timeSlot, timeSlot.getStartTime().toDateTime(date), target); target.add(timeSlotItem); } @Override public boolean isEnabled(Component component) { return isTimeSlotBookable(timeSlot); } }); timeSlotItem.add(AttributeModifier.append("class", new AbstractReadOnlyModel<String>() { //$NON-NLS-1$ private static final long serialVersionUID = 1L; @Override public String getObject() { return getTimeSlotClass(timeSlot); } })); List<String> contentLines = new ArrayList<String>(); Period period = timeSlot.getPayload().getPeriod(); // Time line DateTime startTime = timeSlot.getStartTime().toDateTime(date); DateTime endTime = timeSlot.getEndTime().toDateTime(date); org.joda.time.Period minutesDuration = new org.joda.time.Period(startTime, endTime, PeriodType.minutes()); String timePriceLine = TIME_FORMAT.print(startTime) + "-" + TIME_FORMAT.print(endTime) + " - " //$NON-NLS-1$//$NON-NLS-2$ + Math.round(minutesDuration.getMinutes()) + "m"; //$NON-NLS-1$ if (period.getPrice() > 0) { timePriceLine += " - " + Formatters.getFormatCurrency().format(period.getPrice()); //$NON-NLS-1$ } contentLines.add(timePriceLine); // Period if (Strings.isEmpty(period.getLocation()) == false) { contentLines.add(period.getLocation()); } appendToTimeSlotContent(contentLines, timeSlot); return contentLines; } protected abstract Teacher getTeacher(); protected abstract boolean isTimeSlotBookable(TimeSlot<PeriodBookingTimeSlotPayload> timeSlot); protected void appendToTimeSlotContent(List<String> contentLines, TimeSlot<PeriodBookingTimeSlotPayload> timeSlot) { } /** * @param timeSlot * @return CSS class or classes (separated by space), which is added to the timeslot UI item for additional UI */ protected String getTimeSlotClass(TimeSlot<PeriodBookingTimeSlotPayload> timeSlot) { return null; } protected void onTimeSlotClicked(TimeSlot<PeriodBookingTimeSlotPayload> timeSlot, DateTime date, AjaxRequestTarget target) { } }