001/** 002 * Copyright 2005-2018 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 */ 016package org.kuali.rice.krad.web.bind; 017 018import org.apache.commons.lang.StringUtils; 019import org.joda.time.DateTime; 020import org.kuali.rice.core.api.CoreConstants; 021import org.kuali.rice.core.api.datetime.DateTimeService; 022import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader; 023import org.kuali.rice.core.api.util.RiceKeyConstants; 024import org.kuali.rice.core.web.format.FormatException; 025 026import java.beans.PropertyEditorSupport; 027import java.io.Serializable; 028import java.sql.Date; 029import java.sql.Timestamp; 030import java.text.ParseException; 031import java.util.Calendar; 032 033/** 034 * PropertyEditor converts between timestamp display strings and @{DateTime} objects. 035 * 036 * @author Kuali Rice Team (rice.collab@kuali.org) 037 */ 038public class UifDateTimeEditor extends PropertyEditorSupport implements Serializable { 039 040 private static final long serialVersionUID = -1315597474978280713L; 041 042 private transient DateTimeService dateTimeService; 043 044 /** 045 * {@inheritDoc} 046 * 047 * <p> 048 * This implementation uses the {@link DateTimeService} to convert the {@link DateTime} object to a 049 * {@link Timestamp} display string. 050 * </p> 051 */ 052 @Override 053 public String getAsText() { 054 if (getValue() == null) { 055 return null; 056 } 057 058 if (getValue().equals(StringUtils.EMPTY)) { 059 return null; 060 } 061 062 DateTime value = (DateTime) getValue(); 063 064 return getDateTimeService().toDateTimeString(new Timestamp(value.getMillis())); 065 } 066 067 /** 068 * {@inheritDoc} 069 * 070 * This implementation converts the {@link Date} display string to a {@link DateTime} object using the 071 * {@link DateTimeService}. 072 */ 073 @Override 074 public void setAsText(String text) throws IllegalArgumentException { 075 if (StringUtils.isBlank(text)) { 076 setValue(null); 077 return; 078 } 079 080 try { 081 Date value = getDateTimeService().convertToSqlDate(text); 082 083 Calendar calendar = Calendar.getInstance(); 084 calendar.setTime(value); 085 if (calendar.get(Calendar.YEAR) < 1000 && verbatimYear(text).length() < 4) { 086 throw new FormatException("illegal year format", RiceKeyConstants.ERROR_DATE, text); 087 } 088 089 setValue(new DateTime(value.getTime())); 090 } catch (ParseException e) { 091 throw new FormatException("parsing", RiceKeyConstants.ERROR_DATE, text, e); 092 } 093 } 094 095 /** 096 * For a given user input date, this method returns the exact string the 097 * user entered after the last slash. This allows the formatter to 098 * distinguish between ambiguous values such as "/06" "/6" and "/0006" 099 * 100 * @param date the date to process 101 * 102 * @return the year 103 */ 104 protected String verbatimYear(String date) { 105 String result = ""; 106 107 int pos = date.lastIndexOf("/"); 108 if (pos >= 0) { 109 result = date.substring(pos); 110 } 111 112 return result; 113 } 114 115 /** 116 * Returns the {@link DateTimeService}. 117 * 118 * @return the {@link DateTimeService} 119 */ 120 protected DateTimeService getDateTimeService() { 121 if (dateTimeService == null) { 122 dateTimeService = GlobalResourceLoader.getService(CoreConstants.Services.DATETIME_SERVICE); 123 } 124 125 return dateTimeService; 126 } 127 128}