package org.beanfabrics.samples.timespan; import java.util.Date; import java.util.GregorianCalendar; import org.beanfabrics.model.AbstractPM; import org.beanfabrics.model.ConversionException; import org.beanfabrics.model.DatePM; import org.beanfabrics.model.IntegerPM; import org.beanfabrics.model.PMManager; import org.beanfabrics.support.OnChange; import org.beanfabrics.support.Validation; /** * The TimeSpanPM is a presentation model for editing a period of time. The * start date must be before or equal the end date. */ public class TimeSpanPM extends AbstractPM { private static final long MS_PER_DAY = 1000 * 60 * 60 * 24; public final DatePM start = new DatePM(); public final DatePM end = new DatePM(); public final IntegerPM days = new IntegerPM(); public TimeSpanPM() { PMManager.setup(this); start.setMandatory(true); end.setMandatory(true); days.setEditable(false); } public TimeSpanPM(Date startDate, Date endDate) { this(); start.setDate(startDate); end.setDate(endDate); } /** * Validates start date and end date if their time span is a positive * period. * * @return <code>true</code>, if the time span is a positive period */ @Validation(path = { "start", "end" }, message = "This is not a valid time span") public boolean isPositivePeriod() { try { Date startDate = start.getDate(); Date endDate = end.getDate(); if (startDate == null || endDate == null) { // open periods are 'positive' return true; } return startDate.before(endDate) || startDate.equals(endDate); } catch (ConversionException ex) { // at least one of the date fields can't be converted to a Date object return false; } } /** * Calculates the number of days between start and end date, and updates the * "days" field with this value. This method is called automatically when * any of the date fields change. */ @OnChange(path = { "start", "end" }) public void updateDays() { if (!isValid()) { days.setText(""); } else { GregorianCalendar startCal = new GregorianCalendar(); startCal.setTime(start.getDate()); GregorianCalendar endCal = new GregorianCalendar(); endCal.setTime(end.getDate()); days.setLong((endCal.getTimeInMillis() - startCal.getTimeInMillis()) / MS_PER_DAY); } } public Date getStartDate() { return start.getDate(); } public void setStartDate(Date startDate) { this.start.setDate(startDate); } public Date getEndDate() { return end.getDate(); } public void setEndDate(Date endDate) { this.end.setDate(endDate); } }