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