001    package org.apache.commons.contract.constraints;
002    
003    import java.text.DateFormat;
004    import java.text.ParseException;
005    import java.text.SimpleDateFormat;
006    import java.util.ArrayList;
007    import java.util.Date;
008    import java.util.List;
009    
010    import org.apache.commons.contract.Context;
011    import org.apache.commons.i18n.bundles.ErrorBundle;
012    import org.apache.commons.i18n.bundles.TextBundle;
013    
014    public class DateConstraints implements Constraints {
015        public static final DateConstraints UNCONSTRAINED = new DateConstraints();
016    
017        protected boolean constrained;
018        protected List allowedValues = new ArrayList();
019        protected Date earliest, latest;
020        protected String formatPattern;
021    
022        public DateConstraints() {
023            this.constrained = false;
024        }
025    
026        public DateConstraints(String formatPattern) {
027            this.constrained = false;
028            this.formatPattern = formatPattern;
029        }
030    
031        public DateConstraints(Date earliest, Date latest) {
032            constrained = true;
033            this.earliest = earliest;
034            this.latest = latest;
035        }
036    
037        public boolean isConstrained() {
038            return constrained;
039        }
040    
041        public void setEarliest(Date earliest) {
042            this.earliest = earliest;
043        }
044    
045        public void setLatest(Date latest) {
046            this.latest = latest;
047        }
048    
049        public void setFormatPattern(String dateFormat) {
050            this.formatPattern = dateFormat;
051        }
052        
053        public Object cast(Object value, Context context) throws CastException {
054            Date date = null;
055            if ( value instanceof Date) {
056                return value;
057            } else {
058                    try {
059                            String valueAsString = (String)StringConstraints.UNCONSTRAINED.cast(value, null);
060                            try {
061                                    date = new Date(Long.valueOf(valueAsString).longValue());
062                            } catch ( NumberFormatException exception ) {
063                                    try {
064                                        if ( formatPattern == null ) {
065                                            date = DateFormat.getInstance().parse(valueAsString);
066                            } else {
067                                date = new SimpleDateFormat(formatPattern).parse(valueAsString);
068                            }
069                                    } catch (ParseException e) {
070                                        throw new CastException(new ErrorBundle("uncastableDateValue", new Object[] { value }), e);
071                                    }
072                            }
073                    } catch ( CastException exception ) {
074                            throw new CastException(new ErrorBundle("uncastableDateValue", new Object[] { value }), exception);
075                    }
076            }
077            return date;
078        }
079    
080        public void validate(Object value, Context context) throws ValidationException {
081            Date date = (Date)value;
082            if ( constrained && ( date.after(latest) || date.before(earliest) ) ) {
083                    throw new ValidationException(new ErrorBundle("invalidDate", new Object[] { date, earliest, latest }));
084            }
085        }
086        
087        public TextBundle verboseConstraints() {
088            if ( constrained ) {
089                return new TextBundle("constrainedDateRange", new Object[] { earliest, latest });
090            } 
091            return new TextBundle("unconstrainedDate");
092        }
093    }