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 }