001 package org.apache.fulcrum.intake.model; 002 003 /* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022 import java.text.DateFormat; 023 import java.text.ParseException; 024 025 import java.util.Date; 026 027 import org.apache.commons.lang.StringUtils; 028 029 import org.apache.fulcrum.intake.IntakeException; 030 import org.apache.fulcrum.intake.IntakeRuntimeException; 031 import org.apache.fulcrum.intake.validator.DateStringValidator; 032 import org.apache.fulcrum.intake.xmlmodel.XmlField; 033 034 035 /** 036 * Field for date inputs as free form text. The parsing of date strings 037 * is dependent on any rules that are defined, so this field will expect that 038 * any validator will be (or extend) DateStringValidator. 039 * 040 * @author <a href="mailto:jmcnally@collab.net">John McNally</a> 041 * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a> 042 * @author <a href="mailto:quintonm@bellsouth.net">Quinton McCombs</a> 043 * @version $Id: DateStringField.java 535465 2007-05-05 06:58:06Z tv $ 044 */ 045 public class DateStringField 046 extends Field 047 { 048 /** date format */ 049 private DateFormat df = null; 050 051 /** 052 * Constructor. 053 * 054 * @param field xml field definition object 055 * @param group xml group definition object 056 * @throws IntakeException thrown by superclass 057 */ 058 public DateStringField(XmlField field, Group group) 059 throws IntakeException 060 { 061 super(field, group); 062 063 if (validator == null || !(validator instanceof DateStringValidator)) 064 { 065 df = DateFormat.getInstance(); 066 df.setLenient(true); 067 } 068 } 069 070 /** 071 * Sets the default value for a DateString field 072 * 073 * @param prop Parameter for the default values 074 */ 075 public void setDefaultValue(String prop) 076 { 077 defaultValue = null; 078 079 if (prop == null) 080 { 081 return; 082 } 083 084 try 085 { 086 defaultValue = getDate(prop); 087 } 088 catch (ParseException e) 089 { 090 throw new IntakeRuntimeException("Could not parse " + prop 091 + " into a valid Date for the default value", e); 092 } 093 } 094 095 /** 096 * Set the empty Value. This value is used if Intake 097 * maps a field to a parameter returned by the user and 098 * the corresponding field is either empty (empty string) 099 * or non-existant. 100 * 101 * @param prop The value to use if the field is empty. 102 */ 103 public void setEmptyValue(String prop) 104 { 105 emptyValue = null; 106 107 if (prop == null) 108 { 109 return; 110 } 111 112 try 113 { 114 emptyValue = getDate(prop); 115 } 116 catch (ParseException e) 117 { 118 throw new IntakeRuntimeException("Could not parse " + prop 119 + " into a valid Date for the empty value", e); 120 } 121 } 122 123 /** 124 * A suitable validator. 125 * 126 * @return "DateStringValidator" 127 */ 128 protected String getDefaultValidator() 129 { 130 return DateStringValidator.class.getName(); 131 } 132 133 /** 134 * Sets the value of the field from data in the parser. 135 */ 136 protected void doSetValue() 137 { 138 if (isMultiValued) 139 { 140 String[] inputs = parser.getStrings(getKey()); 141 Date[] values = new Date[inputs.length]; 142 for (int i = 0; i < inputs.length; i++) 143 { 144 try 145 { 146 values[i] = StringUtils.isNotEmpty(inputs[i]) 147 ? getDate(inputs[i]) : (Date) getEmptyValue(); 148 } 149 catch (ParseException e) 150 { 151 values[i] = null; 152 } 153 } 154 setTestValue(values); 155 } 156 else 157 { 158 String val = parser.getString(getKey()); 159 try 160 { 161 setTestValue(StringUtils.isNotEmpty(val) ? getDate(val) : (Date) getEmptyValue()); 162 } 163 catch (ParseException e) 164 { 165 setTestValue(null); 166 } 167 } 168 } 169 170 /** 171 * Parses a test date string using the Validator if is exists and 172 * is an instance of DateStringValidator. Otherwise, DateFormat.parse() 173 * is used. 174 * 175 * @param dateString The string date to parse 176 * @return A <code>Date</code> object 177 * @throws ParseException The date could not be parsed. 178 */ 179 private Date getDate(String dateString) 180 throws ParseException 181 { 182 Date date = null; 183 // FIXME: Canonicalize user-entered date strings. 184 if (validator != null && validator instanceof DateStringValidator) 185 { 186 date = ((DateStringValidator) validator).parse(dateString); 187 } 188 else 189 { 190 date = df.parse(dateString); 191 } 192 return date; 193 } 194 195 /** 196 * returns a String representation 197 * 198 * @return a String representation 199 */ 200 public String toString() 201 { 202 String s = null; 203 Object value = getValue(); 204 if (value == null) 205 { 206 s = ""; 207 } 208 else if (value instanceof String) 209 { 210 s = (String) value; 211 } 212 else if (validator != null && validator instanceof DateStringValidator) 213 { 214 s = ((DateStringValidator) validator).format((Date) value); 215 } 216 else 217 { 218 s = df.format((Date) value); 219 } 220 return s; 221 } 222 }