001 package org.hackystat.projectbrowser.page.validator; 002 003 import java.util.Date; 004 import java.util.List; 005 006 import javax.xml.datatype.XMLGregorianCalendar; 007 008 import org.apache.wicket.markup.html.form.Form; 009 import org.apache.wicket.markup.html.form.FormComponent; 010 import org.apache.wicket.markup.html.form.ListMultipleChoice; 011 import org.apache.wicket.markup.html.form.validation.AbstractFormValidator; 012 import org.apache.wicket.extensions.markup.html.form.DateTextField; 013 import org.hackystat.sensorbase.resource.projects.ProjectUtils; 014 import org.hackystat.sensorbase.resource.projects.jaxb.Project; 015 import org.hackystat.utilities.tstamp.Tstamp; 016 017 /** 018 * Provides a project date validator. This validator will work with forms that have 019 * a multiple selection menu for Projects, plus either one or two date fields. 020 * It provides two constructors: one for forms with a Project menu and one date, 021 * and one for forms with a Project menu and two dates. 022 * @author Philip Johnson 023 */ 024 public class ProjectDateValidator extends AbstractFormValidator { 025 026 /** For serialization. */ 027 private static final long serialVersionUID = 1L; 028 029 /** 030 * Form components to be checked. The first must be the projectMenu (a ListMultipleChoice), 031 * the second must be a date (a DateTextField), and the third (if present) is another 032 * DateTextField. This enables the validator to be used with either forms with a single date 033 * (such as DPDs) as well as forms with a start and end date (such as Telmetry). 034 */ 035 private final FormComponent[] components; 036 037 /** 038 * Takes a Project menu and a single Date field. 039 * @param projectMenu The project menu component. 040 * @param dateField The Date field component. 041 */ 042 public ProjectDateValidator(FormComponent projectMenu, FormComponent dateField) { 043 if (projectMenu == null) { 044 throw new IllegalArgumentException("projectMenu cannot be null"); 045 } 046 if (dateField == null) { 047 throw new IllegalArgumentException("dateField cannot be null"); 048 } 049 if (!(projectMenu instanceof ListMultipleChoice)) { 050 throw new IllegalArgumentException("ProjectDateValidator not given a ListMultipleChoice"); 051 } 052 if (!(dateField instanceof DateTextField)) { 053 throw new IllegalArgumentException("ProjectDateValidator not given a DateTextField"); 054 } 055 components = new FormComponent[] { projectMenu, dateField }; 056 } 057 058 /** 059 * Takes a Project menu (ListMultipleChoice) and two Date fields (DateTextField). 060 * @param projectMenu The project menu component. 061 * @param startDateField The Date field component. 062 * @param endDateField The Date field component. 063 */ 064 public ProjectDateValidator(FormComponent projectMenu, FormComponent startDateField, 065 FormComponent endDateField) { 066 if (projectMenu == null) { 067 throw new IllegalArgumentException("projectMenu cannot be null"); 068 } 069 if (startDateField == null) { 070 throw new IllegalArgumentException("startDateField cannot be null"); 071 } 072 if (!(projectMenu instanceof ListMultipleChoice)) { 073 throw new IllegalArgumentException("ProjectDateValidator not given a ListMultipleChoice"); 074 } 075 if (!(startDateField instanceof DateTextField)) { 076 throw new IllegalArgumentException("ProjectDateValidator not given a DateTextField"); 077 } 078 if (!(endDateField instanceof DateTextField)) { 079 throw new IllegalArgumentException("ProjectDateValidator not given a DateTextField"); 080 } 081 components = new FormComponent[] { projectMenu, startDateField, endDateField }; 082 } 083 084 /** 085 * Returns the form components. 086 * @return The form components. 087 */ 088 public FormComponent[] getDependentFormComponents() { 089 return components.clone(); 090 } 091 092 /** 093 * Performs the validation. 094 * Note that this validation must handle a projectMenu plus a single date, or a 095 * projectMenu plus two dates (start and end date). 096 * This method is ran if all components returned by getDependentFormComponents() are valid. 097 * @param projectDateForm The form to validate. 098 */ 099 @SuppressWarnings("unchecked") 100 public void validate(Form projectDateForm) { 101 ListMultipleChoice projectMenu = (ListMultipleChoice)components[0]; 102 DateTextField startDateField = (DateTextField)components[1]; 103 DateTextField endDateField = null; 104 if (components.length == 3) { 105 endDateField = (DateTextField)components[2]; 106 } 107 List<Project> projects = (List<Project>)projectMenu.getConvertedInput(); 108 Date date1 = (Date)startDateField.getConvertedInput(); 109 XMLGregorianCalendar tomorrow = Tstamp.incrementDays(Tstamp.makeTimestamp(), 1); 110 Date date2 = null; 111 if (endDateField != null) { 112 date2 = (Date)endDateField.getConvertedInput(); 113 } 114 115 for (Project project : projects) { 116 XMLGregorianCalendar startTime = Tstamp.makeTimestamp(date1.getTime()); 117 if (!ProjectUtils.isValidStartTime(project, startTime)) { //NOPMD 118 error(startDateField, "DateBeforeProjectStartTime"); 119 } 120 else if (!ProjectUtils.isValidEndTime(project, startTime)) { //NOPMD 121 error(startDateField, "DateAfterProjectEndTime"); 122 } 123 else if (Tstamp.greaterThan(startTime, tomorrow)) { 124 error(startDateField, "DateInFuture"); 125 } 126 // Only check the end date if this form actually contained an end date. 127 if (date2 != null) { 128 XMLGregorianCalendar endTime = Tstamp.makeTimestamp(date2.getTime()); 129 if (!ProjectUtils.isValidStartTime(project, endTime)) { //NOPMD 130 error(endDateField, "DateBeforeProjectStartTime"); 131 } 132 else if (!ProjectUtils.isValidEndTime(project, endTime)) { //NOPMD 133 error(endDateField, "DateAfterProjectEndTime"); 134 } 135 else if (Tstamp.greaterThan(endTime, tomorrow)) { 136 error(endDateField, "DateInFuture"); 137 } 138 } 139 } 140 } 141 }