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