Skip to content

Commit 8968d0f

Browse files
committed
introduce strategy based compression
Signed-off-by: Ceki Gulcu <ceki@qos.ch>
1 parent 834059c commit 8968d0f

File tree

5 files changed

+288
-138
lines changed

5 files changed

+288
-138
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Logback: the reliable, generic, fast and flexible logging framework.
3+
* Copyright (C) 1999-2025, 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+
15+
package ch.qos.logback.core.rolling.helper;
16+
17+
import ch.qos.logback.core.spi.ContextAware;
18+
19+
public interface CompressionStrategy extends ContextAware {
20+
21+
void compress(String originalFileName, String compressedFileName, String innerEntryName);
22+
23+
String computeFileNameStrWithoutCompSuffix(String fileNamePatternStr);
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Logback: the reliable, generic, fast and flexible logging framework.
3+
* Copyright (C) 1999-2025, 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+
15+
package ch.qos.logback.core.rolling.helper;
16+
17+
import ch.qos.logback.core.ContextBase;
18+
import ch.qos.logback.core.spi.ContextAwareBase;
19+
import ch.qos.logback.core.util.FileUtil;
20+
21+
import java.io.File;
22+
23+
abstract public class CompressionStrategyBase extends ContextAwareBase implements CompressionStrategy {
24+
25+
void createMissingTargetDirsIfNecessary(File file) {
26+
boolean result = FileUtil.createMissingParentDirectories(file);
27+
if (!result) {
28+
addError("Failed to create parent directories for [" + file.getAbsolutePath() + "]");
29+
}
30+
}
31+
}

logback-core/src/main/java/ch/qos/logback/core/rolling/helper/Compressor.java

+34-138
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,11 @@
1313
*/
1414
package ch.qos.logback.core.rolling.helper;
1515

16-
import java.io.BufferedInputStream;
17-
import java.io.File;
18-
import java.io.FileInputStream;
19-
import java.io.FileOutputStream;
2016
import java.util.concurrent.ExecutorService;
2117
import java.util.concurrent.Future;
22-
import java.util.zip.GZIPOutputStream;
23-
import java.util.zip.ZipEntry;
24-
import java.util.zip.ZipOutputStream;
2518

2619
import ch.qos.logback.core.rolling.RolloverFailure;
2720
import ch.qos.logback.core.spi.ContextAwareBase;
28-
import ch.qos.logback.core.status.ErrorStatus;
29-
import ch.qos.logback.core.status.WarnStatus;
30-
import ch.qos.logback.core.util.FileUtil;
3121

3222
/**
3323
* The <code>Compression</code> class implements ZIP and GZ file
@@ -46,75 +36,31 @@ public Compressor(CompressionMode compressionMode) {
4636
}
4737

4838
/**
49-
* @param nameOfFile2Compress
50-
* @param nameOfCompressedFile
39+
* @param originalFileName
40+
* @param compressedFileName
5141
* @param innerEntryName The name of the file within the zip file. Use for
5242
* ZIP compression.
5343
*/
54-
public void compress(String nameOfFile2Compress, String nameOfCompressedFile, String innerEntryName) {
44+
public void compress(String originalFileName, String compressedFileName, String innerEntryName) {
45+
CompressionStrategy compressionStrategy = makeCompressionStrategy(compressionMode);
46+
if (compressionStrategy == null) {
47+
addWarn("Could not ");
48+
}
49+
compressionStrategy.setContext(getContext());
50+
compressionStrategy.compress(originalFileName, compressedFileName, innerEntryName);
51+
52+
}
53+
54+
CompressionStrategy makeCompressionStrategy(CompressionMode compressionMode) {
5555
switch (compressionMode) {
5656
case GZ:
57-
gzCompress(nameOfFile2Compress, nameOfCompressedFile);
58-
break;
57+
return new GZCompressionStrategy();
5958
case ZIP:
60-
zipCompress(nameOfFile2Compress, nameOfCompressedFile, innerEntryName);
61-
break;
59+
return new ZipCompressionStrategy();
6260
case NONE:
6361
throw new UnsupportedOperationException("compress method called in NONE compression mode");
64-
}
65-
}
66-
67-
private void zipCompress(String nameOfFile2zip, String nameOfZippedFile, String innerEntryName) {
68-
File file2zip = new File(nameOfFile2zip);
69-
70-
if (!file2zip.exists()) {
71-
addStatus(new WarnStatus("The file to compress named [" + nameOfFile2zip + "] does not exist.", this));
72-
73-
return;
74-
}
75-
76-
if (innerEntryName == null) {
77-
addStatus(new WarnStatus("The innerEntryName parameter cannot be null", this));
78-
return;
79-
}
80-
81-
if (!nameOfZippedFile.endsWith(".zip")) {
82-
nameOfZippedFile = nameOfZippedFile + ".zip";
83-
}
84-
85-
File zippedFile = new File(nameOfZippedFile);
86-
87-
if (zippedFile.exists()) {
88-
addStatus(
89-
new WarnStatus("The target compressed file named [" + nameOfZippedFile + "] exist already.", this));
90-
91-
return;
92-
}
93-
94-
addInfo("ZIP compressing [" + file2zip + "] as [" + zippedFile + "]");
95-
createMissingTargetDirsIfNecessary(zippedFile);
96-
97-
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(nameOfFile2zip));
98-
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(nameOfZippedFile))) {
99-
100-
ZipEntry zipEntry = computeZipEntry(innerEntryName);
101-
zos.putNextEntry(zipEntry);
102-
103-
byte[] inbuf = new byte[BUFFER_SIZE];
104-
int n;
105-
106-
while ((n = bis.read(inbuf)) != -1) {
107-
zos.write(inbuf, 0, n);
108-
}
109-
110-
addInfo("Done ZIP compressing [" + file2zip + "] as [" + zippedFile + "]");
111-
} catch (Exception e) {
112-
addStatus(new ErrorStatus(
113-
"Error occurred while compressing [" + nameOfFile2zip + "] into [" + nameOfZippedFile + "].", this,
114-
e));
115-
}
116-
if (!file2zip.delete()) {
117-
addStatus(new WarnStatus("Could not delete [" + nameOfFile2zip + "].", this));
62+
default:
63+
return null;
11864
}
11965
}
12066

@@ -133,64 +79,16 @@ private void zipCompress(String nameOfFile2zip, String nameOfZippedFile, String
13379
// (applicable to case 2 only) has the disadvantage of the nested files
13480
// all having the same name, which could make it harder for the user
13581
// to unzip the file without collisions
136-
ZipEntry computeZipEntry(File zippedFile) {
137-
return computeZipEntry(zippedFile.getName());
138-
}
139-
140-
ZipEntry computeZipEntry(String filename) {
141-
String nameOfFileNestedWithinArchive = computeFileNameStrWithoutCompSuffix(filename, compressionMode);
142-
return new ZipEntry(nameOfFileNestedWithinArchive);
143-
}
144-
145-
private void gzCompress(String nameOfFile2gz, String nameOfgzedFile) {
146-
File file2gz = new File(nameOfFile2gz);
147-
148-
if (!file2gz.exists()) {
149-
addStatus(new WarnStatus("The file to compress named [" + nameOfFile2gz + "] does not exist.", this));
150-
151-
return;
152-
}
153-
154-
if (!nameOfgzedFile.endsWith(".gz")) {
155-
nameOfgzedFile = nameOfgzedFile + ".gz";
156-
}
157-
158-
File gzedFile = new File(nameOfgzedFile);
159-
160-
if (gzedFile.exists()) {
161-
addWarn("The target compressed file named [" + nameOfgzedFile
162-
+ "] exist already. Aborting file compression.");
163-
return;
164-
}
165-
166-
addInfo("GZ compressing [" + file2gz + "] as [" + gzedFile + "]");
167-
createMissingTargetDirsIfNecessary(gzedFile);
168-
169-
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(nameOfFile2gz));
170-
GZIPOutputStream gzos = new GZIPOutputStream(new FileOutputStream(nameOfgzedFile))) {
171-
172-
byte[] inbuf = new byte[BUFFER_SIZE];
173-
int n;
174-
175-
while ((n = bis.read(inbuf)) != -1) {
176-
gzos.write(inbuf, 0, n);
177-
}
178-
179-
addInfo("Done GZ compressing [" + file2gz + "] as [" + gzedFile + "]");
180-
} catch (Exception e) {
181-
addStatus(new ErrorStatus(
182-
"Error occurred while compressing [" + nameOfFile2gz + "] into [" + nameOfgzedFile + "].", this,
183-
e));
184-
}
185-
186-
if (!file2gz.delete()) {
187-
addStatus(new WarnStatus("Could not delete [" + nameOfFile2gz + "].", this));
188-
}
189-
190-
}
82+
// ZipEntry computeZipEntry(File zippedFile) {
83+
// return computeZipEntry(zippedFile.getName());
84+
// }
85+
//
86+
// ZipEntry computeZipEntry(String filename) {
87+
// String nameOfFileNestedWithinArchive = computeFileNameStrWithoutCompSuffix(filename, compressionMode);
88+
// return new ZipEntry(nameOfFileNestedWithinArchive);
89+
// }
19190

192-
static public String computeFileNameStrWithoutCompSuffix(String fileNamePatternStr,
193-
CompressionMode compressionMode) {
91+
static public String computeFileNameStrWithoutCompSuffix(String fileNamePatternStr, CompressionMode compressionMode) {
19492
int len = fileNamePatternStr.length();
19593
switch (compressionMode) {
19694
case GZ:
@@ -209,22 +107,20 @@ static public String computeFileNameStrWithoutCompSuffix(String fileNamePatternS
209107
throw new IllegalStateException("Execution should not reach this point");
210108
}
211109

212-
void createMissingTargetDirsIfNecessary(File file) {
213-
boolean result = FileUtil.createMissingParentDirectories(file);
214-
if (!result) {
215-
addError("Failed to create parent directories for [" + file.getAbsolutePath() + "]");
216-
}
217-
}
110+
// void createMissingTargetDirsIfNecessary(File file) {
111+
// boolean result = FileUtil.createMissingParentDirectories(file);
112+
// if (!result) {
113+
// addError("Failed to create parent directories for [" + file.getAbsolutePath() + "]");
114+
// }
115+
// }
218116

219117
@Override
220118
public String toString() {
221119
return this.getClass().getName();
222120
}
223121

224-
public Future<?> asyncCompress(String nameOfFile2Compress, String nameOfCompressedFile, String innerEntryName)
225-
throws RolloverFailure {
226-
CompressionRunnable runnable = new CompressionRunnable(nameOfFile2Compress, nameOfCompressedFile,
227-
innerEntryName);
122+
public Future<?> asyncCompress(String nameOfFile2Compress, String nameOfCompressedFile, String innerEntryName) throws RolloverFailure {
123+
CompressionRunnable runnable = new CompressionRunnable(nameOfFile2Compress, nameOfCompressedFile, innerEntryName);
228124
ExecutorService executorService = context.getExecutorService();
229125
Future<?> future = executorService.submit(runnable);
230126
return future;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*
2+
* Logback: the reliable, generic, fast and flexible logging framework.
3+
* Copyright (C) 1999-2025, 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+
15+
package ch.qos.logback.core.rolling.helper;
16+
17+
import ch.qos.logback.core.status.ErrorStatus;
18+
import ch.qos.logback.core.status.WarnStatus;
19+
20+
import java.io.BufferedInputStream;
21+
import java.io.File;
22+
import java.io.FileInputStream;
23+
import java.io.FileOutputStream;
24+
import java.util.zip.GZIPOutputStream;
25+
26+
public class GZCompressionStrategy extends CompressionStrategyBase {
27+
28+
static final int BUFFER_SIZE = 8192;
29+
30+
@Override
31+
public void compress(String originalFileName, String compressedFileName, String innerEntryName) {
32+
33+
File file2gz = new File(originalFileName);
34+
35+
if (!file2gz.exists()) {
36+
addStatus(new WarnStatus("The file to compress named [" + originalFileName + "] does not exist.", this));
37+
38+
return;
39+
}
40+
41+
if (!compressedFileName.endsWith(".gz")) {
42+
compressedFileName = compressedFileName + ".gz";
43+
}
44+
45+
File gzedFile = new File(compressedFileName);
46+
47+
if (gzedFile.exists()) {
48+
addWarn("The target compressed file named [" + compressedFileName + "] exist already. Aborting file compression.");
49+
return;
50+
}
51+
52+
addInfo("GZ compressing [" + file2gz + "] as [" + gzedFile + "]");
53+
createMissingTargetDirsIfNecessary(gzedFile);
54+
55+
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(originalFileName));
56+
GZIPOutputStream gzos = new GZIPOutputStream(new FileOutputStream(compressedFileName))) {
57+
58+
byte[] inbuf = new byte[BUFFER_SIZE];
59+
int n;
60+
61+
while ((n = bis.read(inbuf)) != -1) {
62+
gzos.write(inbuf, 0, n);
63+
}
64+
65+
addInfo("Done GZ compressing [" + file2gz + "] as [" + gzedFile + "]");
66+
} catch (Exception e) {
67+
addStatus(new ErrorStatus("Error occurred while compressing [" + originalFileName + "] into [" + compressedFileName + "].", this, e));
68+
}
69+
70+
if (!file2gz.delete()) {
71+
addStatus(new WarnStatus("Could not delete [" + originalFileName + "].", this));
72+
}
73+
74+
}
75+
76+
@Override
77+
public String computeFileNameStrWithoutCompSuffix(String fileNamePatternStr) {
78+
int len = fileNamePatternStr.length();
79+
if (fileNamePatternStr.endsWith(".gz"))
80+
return fileNamePatternStr.substring(0, len - 3);
81+
else
82+
return fileNamePatternStr;
83+
}
84+
}

0 commit comments

Comments
 (0)