View Javadoc

1   /**
2    * Logback: the reliable, generic, fast and flexible logging framework.
3    * Copyright (C) 1999-2009, QOS.ch. All rights reserved.
4    *
5    * This program and the accompanying materials are dual-licensed under
6    * either the terms of the Eclipse Public License v1.0 as published by
7    * the Eclipse Foundation
8    *
9    *   or (per the licensee's choosing)
10   *
11   * under the terms of the GNU Lesser General Public License version 2.1
12   * as published by the Free Software Foundation.
13   */
14  package ch.qos.logback.core.rolling.helper;
15  
16  import java.io.File;
17  import java.io.FileInputStream;
18  import java.io.FileOutputStream;
19  import java.util.zip.GZIPOutputStream;
20  import java.util.zip.ZipEntry;
21  import java.util.zip.ZipOutputStream;
22  
23  import ch.qos.logback.core.rolling.TimeBasedRollingPolicy;
24  import ch.qos.logback.core.spi.ContextAwareBase;
25  import ch.qos.logback.core.status.ErrorStatus;
26  import ch.qos.logback.core.status.WarnStatus;
27  
28  /**
29   * The <code>Compression</code> class implements ZIP and GZ file
30   * compression/decompression methods.
31   * 
32   * @author Ceki G&uuml;lc&uuml;
33   */
34  public class Compressor extends ContextAwareBase {
35  
36    final CompressionMode compressionMode;
37  
38    // final String nameOfFile2Compress;
39    // final String nameOfCompressedFile;
40  
41    public Compressor(CompressionMode compressionMode) {
42      this.compressionMode = compressionMode;
43    }
44  
45    // public Compressor(CompressionMode compressionMode, String
46    // nameOfFile2Compress, String nameOfCompressedFile) {
47    // this.compressionMode = compressionMode;
48    // //this.nameOfFile2Compress = nameOfFile2Compress;
49    // //this.nameOfCompressedFile = nameOfCompressedFile;
50    // }
51  
52    public void compress(String nameOfFile2Compress, String nameOfCompressedFile) {
53      switch (compressionMode) {
54      case GZ:
55        addInfo("GZ compressing [" + nameOfFile2Compress + "].");
56        gzCompress(nameOfFile2Compress, nameOfCompressedFile);
57        break;
58      case ZIP:
59        addInfo("ZIP compressing [" + nameOfFile2Compress + "].");
60        zipCompress(nameOfFile2Compress, nameOfCompressedFile);
61        break;
62      case NONE:
63        throw new UnsupportedOperationException(
64            "compress method called in NONE compression mode");
65      }
66    }
67  
68    private void zipCompress(String nameOfFile2zip, String nameOfZippedFile) {
69      File file2zip = new File(nameOfFile2zip);
70  
71      if (!file2zip.exists()) {
72        addStatus(new WarnStatus("The file to compress named [" + nameOfFile2zip
73            + "] does not exist.", this));
74  
75        return;
76      }
77  
78      if (!nameOfZippedFile.endsWith(".zip")) {
79        nameOfZippedFile = nameOfZippedFile + ".zip";
80      }
81  
82      File zippedFile = new File(nameOfZippedFile);
83  
84      if (zippedFile.exists()) {
85        addStatus(new WarnStatus("The target compressed file named ["
86            + nameOfZippedFile + "] exist already.", this));
87  
88        return;
89      }
90  
91      try {
92        FileOutputStream fos = new FileOutputStream(nameOfZippedFile);
93        ZipOutputStream zos = new ZipOutputStream(fos);
94        FileInputStream fis = new FileInputStream(nameOfFile2zip);
95  
96        ZipEntry zipEntry = computeZipEntry(zippedFile);
97        zos.putNextEntry(zipEntry);
98  
99        byte[] inbuf = new byte[8102];
100       int n;
101 
102       while ((n = fis.read(inbuf)) != -1) {
103         zos.write(inbuf, 0, n);
104       }
105 
106       fis.close();
107       zos.close();
108 
109       if (!file2zip.delete()) {
110         addStatus(new WarnStatus("Could not delete [" + nameOfFile2zip + "].",
111             this));
112       }
113     } catch (Exception e) {
114       addStatus(new ErrorStatus("Error occurred while compressing ["
115           + nameOfFile2zip + "] into [" + nameOfZippedFile + "].", this, e));
116     }
117   }
118 
119   // http://jira.qos.ch/browse/LBCORE-98
120   // The name of the compressed file as nested within the zip archive
121   //
122   // Case 1: RawFile = null, Patern = foo-%d.zip
123   // nestedFilename = foo-${current-date}
124   //
125   // Case 2: RawFile = hello.txtm, Pattern = = foo-%d.zip
126   // nestedFilename = foo-${current-date}
127   //
128   // in both cases, the strategy consisting of removing the compression
129   // suffix of zip file works reasonably well. The alternative strategy
130   // whereby the nested file name was based on the value of the raw file name
131   // (applicable to case 2 only) has the disadvantage of the nested files
132   // all having the same name, which could make it harder for the user
133   // to unzip the file without collisions
134   ZipEntry computeZipEntry(File zippedFile) {
135     String nameOfFileNestedWithinArchive = TimeBasedRollingPolicy
136         .computeFileNameStr_WCS(zippedFile.getName(), compressionMode);
137     return new ZipEntry(nameOfFileNestedWithinArchive);
138   }
139 
140   private void gzCompress(String nameOfFile2gz, String nameOfgzedFile) {
141     File file2gz = new File(nameOfFile2gz);
142 
143     if (!file2gz.exists()) {
144       addStatus(new WarnStatus("The file to compress named [" + nameOfFile2gz
145           + "] does not exist.", this));
146 
147       return;
148     }
149 
150     if (!nameOfgzedFile.endsWith(".gz")) {
151       nameOfgzedFile = nameOfgzedFile + ".gz";
152     }
153 
154     File gzedFile = new File(nameOfgzedFile);
155 
156     if (gzedFile.exists()) {
157       addStatus(new WarnStatus("The target compressed file named ["
158           + nameOfgzedFile + "] exist already.", this));
159 
160       return;
161     }
162 
163     try {
164       FileOutputStream fos = new FileOutputStream(nameOfgzedFile);
165       GZIPOutputStream gzos = new GZIPOutputStream(fos);
166       FileInputStream fis = new FileInputStream(nameOfFile2gz);
167       byte[] inbuf = new byte[8102];
168       int n;
169 
170       while ((n = fis.read(inbuf)) != -1) {
171         gzos.write(inbuf, 0, n);
172       }
173 
174       fis.close();
175       gzos.close();
176 
177       if (!file2gz.delete()) {
178         addStatus(new WarnStatus("Could not delete [" + nameOfFile2gz + "].",
179             this));
180       }
181     } catch (Exception e) {
182       addStatus(new ErrorStatus("Error occurred while compressing ["
183           + nameOfFile2gz + "] into [" + nameOfgzedFile + "].", this, e));
184     }
185   }
186 
187   @Override
188   public String toString() {
189     return "c.q.l.core.rolling.helper.Compress";
190   }
191 
192 }