001/*
002 * Copyright 2009 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.sys.batch.service.impl;
017
018import java.io.File;
019import java.util.List;
020
021import org.apache.commons.io.filefilter.AndFileFilter;
022import org.apache.commons.io.filefilter.IOFileFilter;
023import org.apache.commons.io.filefilter.OrFileFilter;
024import org.kuali.ole.sys.FileUtil;
025import org.kuali.ole.sys.batch.FilePurgeCustomAge;
026import org.kuali.ole.sys.batch.FilePurgeDirectoryWalker;
027import org.kuali.ole.sys.batch.FilePurgeStep;
028import org.kuali.ole.sys.batch.MaxAgePurgeFileFilter;
029import org.kuali.ole.sys.batch.NotAmongDirectoriesFileFilter;
030import org.kuali.ole.sys.batch.service.FilePurgeService;
031import org.kuali.rice.coreservice.framework.parameter.ParameterService;
032
033/**
034 * Default implementation of the FilePurgeService
035 */
036public class FilePurgeServiceImpl implements FilePurgeService {
037    protected org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(FilePurgeServiceImpl.class);
038    private ParameterService parameterService;
039    
040    protected static final String DAYS_BEFORE_PURGE_PARAMETER_SUFFIX = "_NUMBER_OF_DAYS_OLD";
041    protected static final String DAYS_BEFORE_PURGE_PARAMETER_PREFIX = "DEFAULT";
042    
043    /**
044     * Uses a FilePurgeDirectoryWalker to get a List of Files to purge, then purges each
045     * @see org.kuali.ole.gl.batch.service.FilePurgeService#purgeFiles(java.lang.String, java.util.List)
046     */
047    public void purgeFiles(String directory, List<FilePurgeCustomAge> customAges) {
048        //add a step to check for directory existence
049        FileUtil.createDirectory(directory);
050        
051        purgeCustomAgeFiles(directory, customAges);
052        purgeDefaultFiles(directory, customAges);
053    }
054    
055    /**
056     * Purges any files in the given directory associated with custom ages
057     * @param directory the directory to purge files from
058     * @param customAges custom ages to purge files for
059     */
060    protected void purgeCustomAgeFiles(String directory, List<FilePurgeCustomAge> customAges) {
061        // purge custom age directories
062        if (customAges != null && customAges.size() > 0) {
063            FilePurgeDirectoryWalker directoryWalker = getCustomAgesDirectoryWalker(customAges);
064            List<File> filesToPurge = directoryWalker.getFilesToPurge(directory);
065            for (File fileToPurge : filesToPurge) {
066                LOG.info("Purging file "+fileToPurge.getPath());
067                fileToPurge.delete();
068            }
069        }
070    }
071    
072    /**
073     * Purges any files in the given directory not associated with custom ages
074     * @param directory the directory to purge files from
075     * @param customAges the custom ages with directories to avoid
076     */
077    protected void purgeDefaultFiles(String directory, List<FilePurgeCustomAge> customAges) {
078        // purge standard directories
079        FilePurgeDirectoryWalker directoryWalker = getDefaultDirectoryWalker(customAges);
080        List<File> filesToPurge = directoryWalker.getFilesToPurge(directory);
081        for (File fileToPurge : filesToPurge) {
082            LOG.info("Purging file "+fileToPurge.getPath());
083            fileToPurge.delete();
084        }
085    }
086    
087    /**
088     * Gets a directory walker which will 
089     * @param customAges the custom ages to purge files for
090     * @return a new FilePurgeDirectoryWalker which will walk directories for us
091     */
092    protected FilePurgeDirectoryWalker getCustomAgesDirectoryWalker(List<FilePurgeCustomAge> customAges) {
093        OrFileFilter fileFilter = new OrFileFilter();
094        for (FilePurgeCustomAge customAge : customAges) {
095            fileFilter.addFileFilter(customAge.getFileFilter());
096        }
097        return new FilePurgeDirectoryWalker(fileFilter);
098    }
099    
100    /**
101     * Gets the directory walker for the default directories
102     * @param customAges the custom ages, because custom age directories will not be purged
103     * @return a new FilePurgeDirectoryWalker
104     */
105    protected FilePurgeDirectoryWalker getDefaultDirectoryWalker(List<FilePurgeCustomAge> customAges) {
106        IOFileFilter ageFileFilter = buildDefaultAgeFileFilter();
107        if (customAges != null && customAges.size() > 0) {
108            AndFileFilter andFileFilter = new AndFileFilter();
109            andFileFilter.addFileFilter(ageFileFilter);
110            andFileFilter.addFileFilter(buildAnyDirectoryButCustomAgeDirectoryFileFilter(customAges));
111            return new FilePurgeDirectoryWalker(andFileFilter);
112        } else {
113            return new FilePurgeDirectoryWalker(ageFileFilter);
114        }
115    }
116    
117    /**
118     * Builds a file filter which will skip the directories taken by the CustomAges
119     * @param customAges the customAges to avoid
120     * @return a file filter
121     */
122    protected IOFileFilter buildAnyDirectoryButCustomAgeDirectoryFileFilter(List<FilePurgeCustomAge> customAges) {
123        NotAmongDirectoriesFileFilter skipDirectoriesFileFilter = new NotAmongDirectoriesFileFilter(customAges);
124        return skipDirectoriesFileFilter;
125    }
126
127    /**
128     * @see org.kuali.ole.gl.batch.service.FilePurgeService#getAgeInDaysForCustomAge(org.kuali.ole.sys.batch.FilePurgeCustomAge)
129     */
130    public int getDaysBeforePurgeForCustomAge(FilePurgeCustomAge customAge) {
131        final String parameterName = customAge.getParameterPrefix()+getDaysBeforePurgeSuffix();
132        return retrieveDaysBeforePurgeParameterValue(parameterName);
133    }
134    
135    /**
136     * @return the standard suffix of parameter names from a custom age
137     */
138    protected String getDaysBeforePurgeSuffix() {
139        return FilePurgeServiceImpl.DAYS_BEFORE_PURGE_PARAMETER_SUFFIX;
140    }
141
142    /**
143     * @see org.kuali.ole.gl.batch.service.FilePurgeService#getStandardDaysBeforePurge()
144     */
145    public int getStandardDaysBeforePurge() {
146        final String parameterName = getStandardDaysBeforePurgeParameterName();
147        return retrieveDaysBeforePurgeParameterValue(parameterName);
148    }
149    
150    /**
151     * @return the parameter name to find the default days before purging files
152     */
153    protected String getStandardDaysBeforePurgeParameterName() {
154        return FilePurgeServiceImpl.DAYS_BEFORE_PURGE_PARAMETER_PREFIX+FilePurgeServiceImpl.DAYS_BEFORE_PURGE_PARAMETER_SUFFIX;
155    }
156    
157    /**
158     * Retrieves the parameter value of the OLE-SYS / FilePurgeStep / parameterName parameter and converts it to an integer number of days
159     * @param parameterName the name of the parameter to retrieve the value of
160     * @return the integer number of days
161     */
162    protected int retrieveDaysBeforePurgeParameterValue(String parameterName) {
163        final String parameterValue = getParameterService().getParameterValueAsString(FilePurgeStep.class, parameterName);
164        Integer parameterValueAsInteger = null;
165        parameterValueAsInteger = new Integer(parameterValue);
166        return (parameterValueAsInteger == null ? Integer.MAX_VALUE : parameterValueAsInteger.intValue());
167    }
168
169    /**
170     * Builds an age file filter for the default removal run
171     * @return a properly constructed IOFileFilter
172     */
173    protected IOFileFilter buildDefaultAgeFileFilter() {
174        return new MaxAgePurgeFileFilter();
175    }
176
177    /**
178     * Gets the parameterService attribute. 
179     * @return Returns the parameterService.
180     */
181    public ParameterService getParameterService() {
182        return parameterService;
183    }
184
185    /**
186     * Sets the parameterService attribute value.
187     * @param parameterService The parameterService to set.
188     */
189    public void setParameterService(ParameterService parameterService) {
190        this.parameterService = parameterService;
191    }
192}