001/* 002 * Copyright 2007 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.ole.gl.batch.service.impl; 017 018import java.util.Calendar; 019import java.util.Date; 020import java.util.StringTokenizer; 021 022import org.apache.commons.lang.StringUtils; 023import org.kuali.ole.gl.GeneralLedgerConstants; 024import org.kuali.ole.gl.batch.ScrubberStep; 025import org.kuali.ole.gl.batch.service.RunDateService; 026import org.kuali.rice.coreservice.framework.parameter.ParameterService; 027 028/** 029 * The default implementation of RunDateService 030 */ 031public class RunDateServiceImpl implements RunDateService { 032 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(RunDateServiceImpl.class); 033 034 private ParameterService parameterService; 035 036 /** 037 * 038 * @see org.kuali.ole.gl.batch.service.RunDateService#calculateRunDate(java.util.Date) 039 */ 040 public Date calculateRunDate(Date executionDate) { 041 Calendar currentCal = Calendar.getInstance(); 042 currentCal.setTime(executionDate); 043 044 CutoffTime cutoffTime = parseCutoffTime(retrieveCutoffTimeValue()); 045 046 if (isCurrentDateBeforeCutoff(currentCal, cutoffTime)) { 047 // time to set the date to the previous day's last minute/second 048 currentCal.add(Calendar.DAY_OF_MONTH, -1); 049 // per old COBOL code (see KULRNE-70), 050 // the time is set to 23:59:59 (assuming 0 ms) 051 currentCal.set(Calendar.HOUR_OF_DAY, 23); 052 currentCal.set(Calendar.MINUTE, 59); 053 currentCal.set(Calendar.SECOND, 59); 054 currentCal.set(Calendar.MILLISECOND, 0); 055 return new Date(currentCal.getTimeInMillis()); 056 } 057 return new Date(executionDate.getTime()); 058 } 059 060 /** 061 * Determines if the given calendar time is before the given cutoff time 062 * 063 * @param currentCal the current time 064 * @param cutoffTime the "start of the day" cut off time 065 * @return true if the current time is before the cutoff, false otherwise 066 */ 067 protected boolean isCurrentDateBeforeCutoff(Calendar currentCal, CutoffTime cutoffTime) { 068 if (cutoffTime != null) { 069 // if cutoff date is not properly defined 070 // 24 hour clock (i.e. hour is 0 - 23) 071 072 // clone the calendar so we get the same month, day, year 073 // then change the hour, minute, second fields 074 // then see if the cutoff is before or after 075 Calendar cutoffCal = (Calendar) currentCal.clone(); 076 cutoffCal.setLenient(false); 077 cutoffCal.set(Calendar.HOUR_OF_DAY, cutoffTime.hour); 078 cutoffCal.set(Calendar.MINUTE, cutoffTime.minute); 079 cutoffCal.set(Calendar.SECOND, cutoffTime.second); 080 cutoffCal.set(Calendar.MILLISECOND, 0); 081 082 return currentCal.before(cutoffCal); 083 } 084 // if cutoff date is not properly defined, then it is considered to be after the cutoff 085 return false; 086 } 087 088 /** 089 * Holds the hour, minute, and second of a given cut off time 090 */ 091 protected class CutoffTime { 092 /** 093 * 24 hour time, from 0-23, inclusive 094 */ 095 protected int hour; 096 097 /** 098 * From 0-59, inclusive 099 */ 100 protected int minute; 101 102 /** 103 * From 0-59, inclusive 104 */ 105 protected int second; 106 107 /** 108 * Constructs a RunDateServiceImpl instance 109 * @param hour the cutoff hour 110 * @param minute the cutoff minute 111 * @param second the cutoff second 112 */ 113 protected CutoffTime(int hour, int minute, int second) { 114 this.hour = hour; 115 this.minute = minute; 116 this.second = second; 117 } 118 } 119 120 /** 121 * Parses a String representation of the cutoff time 122 * 123 * @param cutoffTime the cutoff time String to parse 124 * @return a record holding the cutoff time 125 */ 126 protected CutoffTime parseCutoffTime(String cutoffTime) { 127 if (StringUtils.isBlank(cutoffTime)) { 128 return new CutoffTime(0, 0, 0); 129 } 130 else { 131 cutoffTime = cutoffTime.trim(); 132 if (LOG.isDebugEnabled()) { 133 LOG.debug("Cutoff time value found: " + cutoffTime); 134 } 135 StringTokenizer st = new StringTokenizer(cutoffTime, ":", false); 136 137 try { 138 String hourStr = st.nextToken(); 139 String minuteStr = st.nextToken(); 140 String secondStr = st.nextToken(); 141 142 int hourInt = Integer.parseInt(hourStr, 10); 143 int minuteInt = Integer.parseInt(minuteStr, 10); 144 int secondInt = Integer.parseInt(secondStr, 10); 145 146 if (hourInt < 0 || hourInt > 23 || minuteInt < 0 || minuteInt > 59 || secondInt < 0 || secondInt > 59) { 147 throw new IllegalArgumentException("Cutoff time must be in the format \"HH:mm:ss\", where HH, mm, ss are defined in the java.text.SimpleDateFormat class. In particular, 0 <= hour <= 23, 0 <= minute <= 59, and 0 <= second <= 59"); 148 } 149 return new CutoffTime(hourInt, minuteInt, secondInt); 150 } 151 catch (Exception e) { 152 throw new IllegalArgumentException("Cutoff time should either be null, or in the format \"HH:mm:ss\", where HH, mm, ss are defined in the java.text.SimpleDateFormat class."); 153 } 154 } 155 } 156 157 /** 158 * Retrieves the cutoff time from a repository. 159 * 160 * @return a time of day in the format "HH:mm:ss", where HH, mm, ss are defined in the java.text.SimpleDateFormat class. In 161 * particular, 0 <= hour <= 23, 0 <= minute <= 59, and 0 <= second <= 59 162 */ 163 protected String retrieveCutoffTimeValue() { 164 String value = parameterService.getParameterValueAsString(ScrubberStep.class, GeneralLedgerConstants.GlScrubberGroupParameters.SCRUBBER_CUTOFF_TIME); 165 if (StringUtils.isBlank(value)) { 166 LOG.error("Unable to retrieve parameter for GL process cutoff date. Defaulting to no cutoff time (i.e. midnight)"); 167 value = null; 168 } 169 return value; 170 } 171 172 public void setParameterService(ParameterService parameterService) { 173 this.parameterService = parameterService; 174 } 175 176}