001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.wicket.extensions.markup.html.form;
018
019import java.text.DateFormat;
020import java.text.SimpleDateFormat;
021import java.util.Date;
022import java.util.Locale;
023
024import org.apache.wicket.Session;
025import org.apache.wicket.markup.html.form.AbstractTextComponent.ITextFormatProvider;
026import org.apache.wicket.markup.html.form.TextField;
027import org.apache.wicket.model.IModel;
028import org.apache.wicket.util.convert.IConverter;
029import org.apache.wicket.util.convert.converter.DateConverter;
030
031
032/**
033 * A TextField that is mapped to a <code>java.util.Date</code> object.
034 * 
035 * If no date pattern is explicitly specified, the default <code>DateFormat.SHORT</code> pattern for
036 * the current locale will be used.
037 * 
038 * @author Stefan Kanev
039 * @author Igor Vaynberg (ivaynberg)
040 * 
041 */
042public class DateTextField extends TextField<Date> implements ITextFormatProvider
043{
044
045        private static final long serialVersionUID = 1L;
046
047        private static final String DEFAULT_PATTERN = "MM/dd/yyyy";
048
049        /**
050         * The date pattern of the text field
051         */
052        private String datePattern = null;
053
054        /**
055         * The converter for the TextField
056         */
057        private final IConverter<Date> converter;
058
059        /**
060         * Creates a new DateTextField, without a specified pattern. This is the same as calling
061         * <code>new TextField(id, Date.class)</code>
062         * 
063         * @param id
064         *            The id of the text field
065         * 
066         * @see org.apache.wicket.markup.html.form.TextField
067         */
068        public DateTextField(final String id)
069        {
070                this(id, null, defaultDatePattern());
071        }
072
073        /**
074         * Creates a new DateTextField, without a specified pattern. This is the same as calling
075         * <code>new TextField(id, object, Date.class)</code>
076         * 
077         * @param id
078         *            The id of the text field
079         * @param model
080         *            The model
081         * 
082         * @see org.apache.wicket.markup.html.form.TextField
083         */
084        public DateTextField(final String id, final IModel<Date> model)
085        {
086                this(id, model, defaultDatePattern());
087        }
088
089        /**
090         * Creates a new DateTextField bound with a specific <code>SimpleDateFormat</code> pattern.
091         * 
092         * @param id
093         *            The id of the text field
094         * @param datePattern
095         *            A <code>SimpleDateFormat</code> pattern
096         * 
097         * @see org.apache.wicket.markup.html.form.TextField
098         */
099        public DateTextField(final String id, final String datePattern)
100        {
101                this(id, null, datePattern);
102        }
103
104        /**
105         * Creates a new DateTextField bound with a specific <code>SimpleDateFormat</code> pattern.
106         * 
107         * @param id
108         *            The id of the text field
109         * @param model
110         *            The model
111         * @param datePattern
112         *            A <code>SimpleDateFormat</code> pattern
113         * 
114         * @see org.apache.wicket.markup.html.form.TextField
115         */
116        public DateTextField(final String id, final IModel<Date> model, final String datePattern)
117        {
118                super(id, model, Date.class);
119                this.datePattern = datePattern;
120                converter = new DateConverter()
121                {
122                        private static final long serialVersionUID = 1L;
123
124                        /**
125                         * @see org.apache.wicket.util.convert.converter.DateConverter#getDateFormat(java.util.Locale)
126                         */
127                        @Override
128                        public DateFormat getDateFormat(Locale locale)
129                        {
130                                if (locale == null)
131                                {
132                                        locale = Locale.getDefault(Locale.Category.FORMAT);
133                                }
134                                return new SimpleDateFormat(DateTextField.this.datePattern, locale);
135                        }
136                };
137        }
138
139        /**
140         * Returns the default converter if created without pattern; otherwise it returns a
141         * pattern-specific converter.
142         * 
143         * @param type
144         *            The type for which the convertor should work
145         * 
146         * @return A pattern-specific converter
147         * 
148         * @see org.apache.wicket.markup.html.form.TextField
149         */
150        @Override
151        protected IConverter<?> createConverter(Class<?> type)
152        {
153                if (Date.class.isAssignableFrom(type))
154                {
155                        return converter;
156                }
157                return null;
158        }
159
160        /**
161         * Returns the date pattern.
162         * 
163         * @see org.apache.wicket.markup.html.form.AbstractTextComponent.ITextFormatProvider#getTextFormat()
164         */
165        @Override
166        public String getTextFormat()
167        {
168                return datePattern;
169        }
170
171        /**
172         * Try to get datePattern from user session locale. If it is not possible, it will return
173         * {@link #DEFAULT_PATTERN}
174         * 
175         * @return date pattern
176         */
177        private static String defaultDatePattern()
178        {
179                // It is possible to retrieve from session?
180                Locale locale = Session.get().getLocale();
181                if (locale != null)
182                {
183                        DateFormat format = DateFormat.getDateInstance(DateFormat.SHORT, locale);
184                        if (format instanceof SimpleDateFormat)
185                        {
186                                return ((SimpleDateFormat)format).toPattern();
187                        }
188                }
189                return DEFAULT_PATTERN;
190        }
191
192        @Override
193        protected String[] getInputTypes()
194        {
195                return new String[] { "text", "date", "datetime", "datetime-local", "month", "time", "week" };
196        }
197}