001 /* 002 * Copyright 2010 the original author or authors. 003 * 004 * Licensed under the Apache 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.apache.org/licenses/LICENSE-2.0 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 com.hs.mail.imap.schedule; 017 018 import java.io.File; 019 import java.io.FilenameFilter; 020 import java.io.IOException; 021 import java.util.Date; 022 023 import org.apache.commons.lang.time.DateFormatUtils; 024 import org.apache.commons.lang.time.DateUtils; 025 import org.apache.log4j.Logger; 026 027 import com.hs.mail.container.config.Config; 028 import com.hs.mail.util.FileUtils; 029 030 /** 031 * 032 * @author Won Chul Doh 033 * @since Oct 2, 2010 034 * 035 */ 036 public class MessageCompressor { 037 038 static Logger logger = Logger.getLogger(MessageCompressor.class); 039 040 private static final String DOT_GZIP_EXTENSION = "." + FileUtils.GZIP_EXTENSION; 041 private static final String COMPRESSED = ".compressed"; 042 043 public MessageCompressor() { 044 super(); 045 } 046 047 public void compress(String prop, long timeLimit) { 048 Date base = ScheduleUtils.getDateBefore(prop); 049 if (base != null) { 050 Date start = getStartDate(base); 051 if (start != null) { 052 Date date = start; 053 if (logger.isDebugEnabled()) { 054 logger.debug("Compressing directories from " 055 + DateFormatUtils.ISO_DATE_FORMAT.format(start) 056 + " to " 057 + DateFormatUtils.ISO_DATE_FORMAT.format(base)); 058 } 059 while (date.before(base) 060 && System.currentTimeMillis() < timeLimit) { 061 compressDirectories(date, timeLimit); 062 date = DateUtils.addDays(date, 1); 063 } 064 } 065 } 066 } 067 068 public static File getDataDirectory(Date date, long physmessageid) { 069 return new File(Config.getDataDirectory(), Config.getSubDirectory(date, 070 physmessageid)); 071 } 072 073 private Date getStartDate(Date date) { 074 while (true) { 075 File dir = getDataDirectory(date, 0).getParentFile(); 076 if (dir.exists()) { 077 File[] subdirs = dir.listFiles(); 078 for (int i = 0; i < subdirs.length; i++) { 079 if (new File(subdirs[i], COMPRESSED).exists()) { 080 return date; 081 } 082 } 083 } else if (!dir.getParentFile().getParentFile().exists()) { 084 return DateUtils.addDays(date, 1); 085 } 086 date = DateUtils.addDays(date, -1); 087 } 088 } 089 090 private void compressDirectories(Date date, long timeLimit) { 091 File directory = getDataDirectory(date, 0).getParentFile(); 092 if (directory.exists()) { 093 File[] subdirs = directory.listFiles(); 094 for (int i = 0; i < subdirs.length 095 && System.currentTimeMillis() < timeLimit; i++) { 096 if (!new File(subdirs[i], COMPRESSED).exists()) { 097 if (logger.isDebugEnabled()) { 098 logger.debug("Start compressing " 099 + subdirs[i].getAbsolutePath()); 100 } 101 compressDirectory(subdirs[i]); 102 } 103 } 104 } 105 } 106 107 private void compressDirectory(File directory) { 108 File[] files = directory.listFiles(new FilenameFilter() { 109 public boolean accept(File dir, String name) { 110 return !name.endsWith(DOT_GZIP_EXTENSION); 111 } 112 }); 113 for (int i = 0; i < files.length; i++) { 114 compressFile(files[i]); 115 } 116 FileUtils.createNewFile(new File(directory, COMPRESSED)); 117 } 118 119 private void compressFile(File srcFile) { 120 File destFile = null; 121 try { 122 destFile = new File(srcFile.getCanonicalPath() + DOT_GZIP_EXTENSION); 123 FileUtils.compress(srcFile, destFile); 124 srcFile.delete(); 125 } catch (IOException e) { 126 if (srcFile.exists() && destFile != null && destFile.exists()) { 127 destFile.delete(); 128 } 129 } 130 } 131 132 }