001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software GmbH & Co. KG, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.scheduler.jobs; 029 030import org.opencms.file.CmsObject; 031import org.opencms.loader.CmsImageLoader; 032import org.opencms.main.CmsLog; 033import org.opencms.scheduler.I_CmsScheduledJob; 034 035import java.io.File; 036import java.util.Map; 037 038import org.apache.commons.logging.Log; 039 040/** 041 * A schedulable OpenCms job that clear the image cache for the scaled images created by the <code>{@link org.opencms.loader.CmsImageLoader}</code>.<p> 042 * 043 * Job parameters:<p> 044 * <dl> 045 * <dt><code>maxage={time in hours}</code></dt> 046 * <dd>Specifies the maximum age (in hours) images can be unused before they are removed from the cache. 047 * Any image in the image cache folder that has a RFS date of last modification older than this time is considered 048 * expired and is therefore deleted.</dd> 049 * </dl> 050 * 051 * @since 6.2.0 052 */ 053public class CmsImageCacheCleanupJob implements I_CmsScheduledJob { 054 055 /** Unlock parameter. */ 056 public static final String PARAM_MAXAGE = "maxage"; 057 058 /** The log object for this class. */ 059 private static final Log LOG = CmsLog.getLog(CmsImageCacheCleanupJob.class); 060 061 /** 062 * Removes all expired image cache entries from the RFS cache.<p> 063 * 064 * Empty directories are removed as well.<p> 065 * 066 * @param maxAge the maximum age of the image cache files in hours (or fractions of hours) 067 * 068 * @return the total number of deleted resources 069 */ 070 public static int cleanImageCache(float maxAge) { 071 072 // calculate oldest possible date for the cache files 073 long expireDate = System.currentTimeMillis() - (long)(maxAge * 60f * 60f * 1000f); 074 File basedir = new File(CmsImageLoader.getImageRepositoryPath()); 075 // perform the cache cleanup 076 return cleanImageCache(expireDate, basedir); 077 } 078 079 /** 080 * Removes all expired image cache entries from the given RFS directory, including recursion to subdirectories.<p> 081 * 082 * @param maxAge the maximum age of the image cache files 083 * @param directory the directory to remove the cache files in 084 * 085 * @return the total number of deleted resources 086 */ 087 private static int cleanImageCache(long maxAge, File directory) { 088 089 int count = 0; 090 if (directory.canRead() && directory.isDirectory()) { 091 File[] files = directory.listFiles(); 092 for (int i = 0; i < files.length; i++) { 093 File f = files[i]; 094 if (f.isDirectory()) { 095 count += cleanImageCache(maxAge, f); 096 } 097 if (f.canWrite()) { 098 if (f.lastModified() < maxAge) { 099 try { 100 f.delete(); 101 count++; 102 } catch (Exception e) { 103 LOG.error( 104 Messages.get().getBundle().key( 105 Messages.LOG_IMAGE_CACHE_UNABLE_TO_DELETE_1, 106 f.getAbsolutePath())); 107 } 108 } 109 } 110 } 111 if (directory.listFiles().length <= 0) { 112 try { 113 directory.delete(); 114 count++; 115 } catch (Exception e) { 116 LOG.error( 117 Messages.get().getBundle().key( 118 Messages.LOG_IMAGE_CACHE_UNABLE_TO_DELETE_1, 119 directory.getAbsolutePath())); 120 } 121 } 122 } 123 return count; 124 } 125 126 /** 127 * @see org.opencms.scheduler.I_CmsScheduledJob#launch(CmsObject, Map) 128 */ 129 public String launch(CmsObject cms, Map<String, String> parameters) throws Exception { 130 131 if (!CmsImageLoader.isEnabled() || (CmsImageLoader.getImageRepositoryPath() == null)) { 132 // scaling functions are not available 133 return Messages.get().getBundle().key(Messages.LOG_IMAGE_SCALING_DISABLED_0); 134 } 135 136 String maxAgeStr = parameters.get(PARAM_MAXAGE); 137 float maxAge; 138 try { 139 maxAge = Float.parseFloat(maxAgeStr); 140 } catch (NumberFormatException e) { 141 // in case of an error, use maxage of one week 142 maxAge = 24f * 7f; 143 LOG.error( 144 Messages.get().getBundle().key(Messages.LOG_IMAGE_CACHE_BAD_MAXAGE_2, maxAgeStr, Float.valueOf(maxAge))); 145 } 146 147 // now perform the image cache cleanup 148 int count = cleanImageCache(maxAge); 149 150 return Messages.get().getBundle().key(Messages.LOG_IMAGE_CACHE_CLEANUP_COUNT_1, Integer.valueOf(count)); 151 } 152}