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 }