001    /*
002     * Copyright 2007 The Kuali Foundation Licensed under the Educational Community
003     * License, Version 1.0 (the "License"); you may not use this file except in
004     * compliance with the License. You may obtain a copy of the License at
005     * http://www.opensource.org/licenses/ecl1.php Unless required by applicable law
006     * or agreed to in writing, software distributed under the License is
007     * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
008     * KIND, either express or implied. See the License for the specific language
009     * governing permissions and limitations under the License.
010     */
011    package org.kuali.rice.krad.web.bind;
012    
013    import org.kuali.rice.core.api.CoreConstants;
014    import org.kuali.rice.core.api.datetime.DateTimeService;
015    import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
016    import org.kuali.rice.core.util.RiceKeyConstants;
017    import org.kuali.rice.core.web.format.FormatException;
018    
019    import java.beans.PropertyEditorSupport;
020    import java.sql.Date;
021    import java.text.ParseException;
022    import java.util.Calendar;
023    
024    /**
025     * This PropertyEditor converts between date display strings and
026     * <code>java.sql.Date</code> objects.
027     * 
028     * @author Kuali Rice Team (rice.collab@kuali.org)
029     */
030    public class UifDateEditor extends PropertyEditorSupport {
031    
032        /** The date time service. */
033        private transient DateTimeService dateTimeService;
034    
035        /**
036         * This overridden method uses the
037         * <code>org.kuali.rice.core.api.datetime.DateTimeService</code> to convert
038         * the date object to the display string.
039         * 
040         * @see java.beans.PropertyEditorSupport#getAsText()
041         */
042        @Override
043        public String getAsText() {
044            if (this.getValue() == null) {
045                return null;
046            }
047            if ("".equals(this.getValue())) {
048                return null;
049            }
050            return getDateTimeService().toDateString((java.util.Date) this.getValue());
051        }
052    
053        /**
054         * Gets the date time service.
055         * 
056         * @return the date time service
057         */
058        protected DateTimeService getDateTimeService() {
059            if (this.dateTimeService == null) {
060                this.dateTimeService = GlobalResourceLoader.getService(CoreConstants.Services.DATETIME_SERVICE);
061            }
062            return this.dateTimeService;
063        }
064    
065        /**
066         * This overridden method converts the display string to a
067         * <code>java.sql.Date</code> object using the
068         * <code>org.kuali.rice.core.api.datetime.DateTimeService</code>.
069         * 
070         * @see java.beans.PropertyEditorSupport#setAsText(java.lang.String)
071         */
072        @Override
073        public void setAsText(String text) throws IllegalArgumentException {
074            this.setValue(convertToObject(text));
075        }
076    
077        /**
078         * Convert display text to <code>java.sql.Date</code> object using the
079         * <code>org.kuali.rice.core.api.datetime.DateTimeService</code>.
080         * 
081         * @param text
082         *            the display text
083         * @return the <code>java.sql.Date</code> object
084         * @throws IllegalArgumentException
085         *             the illegal argument exception
086         */
087        protected Object convertToObject(String text) throws IllegalArgumentException {
088            try {
089                Date result = getDateTimeService().convertToSqlDate(text);
090                Calendar calendar = Calendar.getInstance();
091                calendar.setTime(result);
092                if (calendar.get(Calendar.YEAR) < 1000 && verbatimYear(text).length() < 4) {
093                    throw new FormatException("illegal year format", RiceKeyConstants.ERROR_DATE, text);
094                }
095                return result;
096            } catch (ParseException e) {
097                throw new FormatException("parsing", RiceKeyConstants.ERROR_DATE, text, e);
098            }
099        }
100    
101        /**
102         * For a given user input date, this method returns the exact string the
103         * user entered after the last slash. This allows the formatter to
104         * distinguish between ambiguous values such as "/06" "/6" and "/0006"
105         * 
106         * @param date
107         * @return
108         */
109        private String verbatimYear(String date) {
110            String result = "";
111    
112            int pos = date.lastIndexOf("/");
113            if (pos >= 0) {
114                result = date.substring(pos);
115            }
116    
117            return result;
118        }
119    
120    }