Java tutorial
/** * Copyright 2014 Sakaiproject Licensed under the * Educational Community License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. You may * obtain a copy of the License at * * http://www.osedu.org/licenses/ECL-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an "AS IS" * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing * permissions and limitations under the License. */ package org.sakaiproject.lap.service; import java.util.ArrayList; import java.util.Calendar; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.NullArgumentException; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.sakaiproject.component.cover.ServerConfigurationService; import org.sakaiproject.lap.Constants; import org.sakaiproject.lap.util.DateUtils; import org.sakaiproject.lap.util.ExtractorUtils; import org.sakaiproject.lap.util.FileUtils; /** * Handles all needed date functionality * * @author Robert E. Long (rlong @ unicon.net) * */ public class DateService { private final Log log = LogFactory.getLog(getClass()); private String currentDay; private Map<String, List<Date>> remainingTimes = new HashMap<String, List<Date>>(); private ArrayList<String> scheduledRunTimes; private String lastScheduledExtractionDate = null; public void init() { processCurrentDay(new Date()); processScheduledRunTimes(); processLastScheduledExtractionDate(); } /** * Sets the day string to the current one * format: yyyyMMdd * * @param date the current date object */ public void processCurrentDay(Date date) { if (date == null) { date = new Date(); } if (!StringUtils.equalsIgnoreCase(currentDay, DateUtils.SDF_DATE_ONLY.format(date))) { currentDay = DateUtils.SDF_DATE_ONLY.format(date); processRemainingTimes(date); } } /** * Sets all the configured run times from sakai.properties * Defaults to coded times, if none specified in sakai.properties */ private void processScheduledRunTimes() { // get run dates from config String[] runTimes = ServerConfigurationService.getStrings("lap.data.extraction.times"); // get hard-coded auto-extraction times if (ArrayUtils.isEmpty(runTimes)) { runTimes = Constants.DEFAULT_DATA_EXTRACTION_TIMES; } if (runTimes != null) { scheduledRunTimes = new ArrayList<String>(runTimes.length); for (String runTime : runTimes) { scheduledRunTimes.add(runTime); } Collections.sort(scheduledRunTimes); } else { scheduledRunTimes = new ArrayList<String>(0); } } /** * Sets all the remaining future times for the given date * * @param date the date to set times */ private void processRemainingTimes(Date date) { if (scheduledRunTimes == null) { processScheduledRunTimes(); } List<Date> dates = new ArrayList<Date>(scheduledRunTimes.size()); String dateString = DateUtils.SDF_DATE_ONLY.format(date); try { for (String s : scheduledRunTimes) { Date scheduledDate = DateUtils.SDF_DATE_TIME.parse(dateString + " " + s); // add the date to the schedule if it's after the current date or is next day if (!StringUtils.equalsIgnoreCase(currentDay, dateString) || scheduledDate.after(date)) { dates.add(scheduledDate); } } } catch (Exception e) { log.error("Error parsing scheduled dates. Error: " + e, e); } finally { remainingTimes.put(dateString, dates); } } /** * Gets the last data extraction date from the listing of directories * * @param directoryListing the directory listing map * @return the last extraction date */ public Map<String, Map<String, String>> getLatestExtractionDate( Map<String, Map<String, String>> directoryListing) { String displayDate = Constants.DEFAULT_NO_TIME; String dateTime = Constants.DEFAULT_NO_TIME; Map<String, Map<String, String>> extractionDate = new HashMap<String, Map<String, String>>(1); Map<String, String> dateMap = new HashMap<String, String>(2); if (directoryListing == null || directoryListing.isEmpty()) { dateMap.put(Constants.REST_MAP_KEY_DISPLAY_DATE, displayDate); dateMap.put(Constants.REST_MAP_KEY_DATE_TIME, dateTime); extractionDate.put(Constants.DEFAULT_NO_TIME, dateMap); return extractionDate; } String firstDirectory = directoryListing.keySet().iterator().next(); displayDate = directoryListing.get(firstDirectory).get(Constants.REST_MAP_KEY_DISPLAY_DATE); dateTime = directoryListing.get(firstDirectory).get(Constants.REST_MAP_KEY_DATE_TIME); dateMap.put(Constants.REST_MAP_KEY_DISPLAY_DATE, displayDate); dateMap.put(Constants.REST_MAP_KEY_DATE_TIME, dateTime); extractionDate.put(firstDirectory, dateMap); return extractionDate; } /** * Gets the next scheduled extraction date * If none available for current date, calculates the next day's times * * @return the next extraction date */ public String getNextScheduledExtractionDate() { String nextScheduledExtractionDate = Constants.DEFAULT_NO_TIME; List<Date> times = remainingTimes.get(currentDay); if (times != null) { if (times.size() > 0) { nextScheduledExtractionDate = DateUtils.SDF_DISPLAY.format(times.get(0)); } else { // we are after the last time scheduled for today, get the next day's times Calendar calendar = Calendar.getInstance(); calendar.setTime(new Date()); calendar.add(Calendar.DATE, 1); Date nextDay = calendar.getTime(); String nextDayString = DateUtils.SDF_DATE_ONLY.format(nextDay); processRemainingTimes(nextDay); List<Date> nextDayTimes = remainingTimes.get(nextDayString); nextScheduledExtractionDate = DateUtils.SDF_DISPLAY.format(nextDayTimes.get(0)); } } return nextScheduledExtractionDate; } /** * Gets a listing of all the extraction dates * * @return the list of all extraction dates */ public Map<String, String> getAllExtractionDates() { String directory = fileService.getStoragePath(); List<String> directoryNames = FileUtils.parseDirectory(directory, ""); Map<String, String> extractionDates = new HashMap<String, String>(directoryNames.size()); for (String directoryName : directoryNames) { try { Date date = parseDirectoryToDateTime(directoryName); String dateTime = DateUtils.SDF_DISPLAY.format(date); String displayDateTime = dateTime; String extractionType = ExtractorUtils.calculateExtractionType(directoryName); if (StringUtils.isNotBlank(extractionType)) { displayDateTime += " (" + extractionType + ")"; } extractionDates.put(dateTime, displayDateTime); } catch (Exception e) { log.error("Error parsing directory name: " + e, e); extractionDates.put(directoryName, directoryName); } } return extractionDates; } /** * Finds the last directory created by a scheduled extraction */ private void processLastScheduledExtractionDate() { String directory = fileService.getStoragePath(); List<String> scheduledDirectories = FileUtils.parseDirectory(directory, Constants.EXTRACTION_TYPE_EXTENSION_SCHEDULED); if (scheduledDirectories.size() > 0) { lastScheduledExtractionDate = scheduledDirectories.get(0); } } /** * Parses a dated directory name to get the date object * e.g. yyyyMMdd_HHmmss_A => date object * * @param directory the directory name * @return the date object */ public Date parseDirectoryToDateTime(String directory) { if (StringUtils.isBlank(directory)) { throw new NullArgumentException(directory); } if (directory.length() > 15) { directory = StringUtils.substring(directory, 0, 15); } Date date = null; try { date = DateUtils.SDF_FILE_NAME.parse(directory); } catch (Exception e) { log.error("Error parsing directory string to date. Error: " + e, e); } return date; } public String getCurrentDay() { return currentDay; } public Map<String, List<Date>> getRemainingTimes() { return remainingTimes; } public void setRemainingTimes(Map<String, List<Date>> remainingTimes) { this.remainingTimes = remainingTimes; } public ArrayList<String> getScheduledRunTimes() { return scheduledRunTimes; } public String getLastScheduledExtractionDate() { return lastScheduledExtractionDate; } public void setLastScheduledExtractionDate(String lastScheduledExtractionDate) { this.lastScheduledExtractionDate = lastScheduledExtractionDate; } private FileService fileService; public void setFileService(FileService fileService) { this.fileService = fileService; } }