Skip to content

Commit 5bb7daa

Browse files
author
Uwe Voigt
committed
[COMPRESS-722] Introduce handling of entries compressed by a specific method in ZipArchiveOutputStream
- implicitly close entries when writing
1 parent f6d1fd8 commit 5bb7daa

14 files changed

Lines changed: 916 additions & 20 deletions
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* https://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.commons.compress.archivers.zip;
20+
21+
/**
22+
* Configuration for BZIP2 compression in ZIP archives.
23+
*
24+
* @since 1.29.0
25+
*/
26+
public class BZip2CompressorConfig implements CompressorConfig {
27+
28+
private final int blockSize;
29+
30+
/**
31+
* Creates a default BZIP2 configuration (blockSize 9).
32+
*/
33+
public BZip2CompressorConfig() {
34+
this(9);
35+
}
36+
37+
/**
38+
* Creates a BZIP2 configuration with the specified block size.
39+
*
40+
* @param blockSize the block size (1-9)
41+
*/
42+
public BZip2CompressorConfig(final int blockSize) {
43+
this.blockSize = blockSize;
44+
}
45+
46+
/**
47+
* Gets the block size.
48+
*
49+
* @return the block size
50+
*/
51+
public int getBlockSize() {
52+
return blockSize;
53+
}
54+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* https://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.commons.compress.archivers.zip;
20+
21+
import java.io.IOException;
22+
import java.io.OutputStream;
23+
24+
import org.apache.commons.compress.compressors.CompressorOutputStream;
25+
import org.apache.commons.compress.compressors.bzip2.BZip2CompressorOutputStream;
26+
27+
/**
28+
* Factory for creating BZIP2 compressor output streams in ZIP archives.
29+
*
30+
* @since 1.29.0
31+
*/
32+
public class BZip2ZipCompressorStreamFactory implements ZipCompressorStreamFactory {
33+
34+
@Override
35+
public CompressorOutputStream<?> createCompressorOutputStream(final OutputStream out, final CompressorConfig config) throws IOException {
36+
final BZip2CompressorConfig bzip2Config = (BZip2CompressorConfig) config;
37+
return new BZip2CompressorOutputStream(out, bzip2Config.getBlockSize());
38+
}
39+
40+
@Override
41+
public CompressorConfig defaultConfig() {
42+
return new BZip2CompressorConfig();
43+
}
44+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* https://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.commons.compress.archivers.zip;
20+
21+
/**
22+
* Marker interface for compressor-specific configuration.
23+
* Implementations carry parameters for a specific compression method
24+
* (e.g., compression level, block size).
25+
*
26+
* @since 1.29.0
27+
*/
28+
public interface CompressorConfig {
29+
}

src/main/java/org/apache/commons/compress/archivers/zip/StreamCompressor.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,30 @@ void reset() {
273273
writtenToOutputStreamForLastEntry = 0;
274274
}
275275

276+
/**
277+
* Updates the CRC checksum without writing data.
278+
*
279+
* @param b the byte array
280+
* @param offset start offset
281+
* @param length number of bytes
282+
*
283+
* @since 1.29.0
284+
*/
285+
void updateCrc(final byte[] b, final int offset, final int length) {
286+
crc.update(b, offset, length);
287+
}
288+
289+
/**
290+
* Updates the source payload length counter.
291+
*
292+
* @param length number of uncompressed bytes
293+
*
294+
* @since 1.29.0
295+
*/
296+
void updateSourcePayloadLength(final int length) {
297+
sourcePayloadLength += length;
298+
}
299+
276300
/**
277301
* Writes bytes to ZIP entry.
278302
*
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* https://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.commons.compress.archivers.zip;
20+
21+
/**
22+
* Configuration for XZ compression in ZIP archives.
23+
*
24+
* @since 1.29.0
25+
*/
26+
public class XZCompressorConfig implements CompressorConfig {
27+
28+
private final int preset;
29+
30+
/**
31+
* Creates a default XZ configuration (preset 6).
32+
*/
33+
public XZCompressorConfig() {
34+
this(6);
35+
}
36+
37+
/**
38+
* Creates an XZ configuration with the specified preset.
39+
*
40+
* @param preset the LZMA2 preset level (0-9)
41+
*/
42+
public XZCompressorConfig(final int preset) {
43+
this.preset = preset;
44+
}
45+
46+
/**
47+
* Gets the preset level.
48+
*
49+
* @return the preset level
50+
*/
51+
public int getPreset() {
52+
return preset;
53+
}
54+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* https://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.commons.compress.archivers.zip;
20+
21+
import java.io.IOException;
22+
import java.io.OutputStream;
23+
24+
import org.apache.commons.compress.compressors.CompressorOutputStream;
25+
import org.apache.commons.compress.compressors.xz.XZCompressorOutputStream;
26+
27+
/**
28+
* Factory for creating XZ compressor output streams in ZIP archives.
29+
*
30+
* @since 1.29.0
31+
*/
32+
public class XZZipCompressorStreamFactory implements ZipCompressorStreamFactory {
33+
34+
@Override
35+
public CompressorOutputStream<?> createCompressorOutputStream(final OutputStream out, final CompressorConfig config) throws IOException {
36+
final XZCompressorConfig xzConfig = (XZCompressorConfig) config;
37+
return new XZCompressorOutputStream(out, xzConfig.getPreset());
38+
}
39+
40+
@Override
41+
public CompressorConfig defaultConfig() {
42+
return new XZCompressorConfig();
43+
}
44+
}

src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveEntry.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,8 @@ private static String toEntryName(final Path inputPath, final String entryName,
320320

321321
private long time = -1;
322322

323+
private CompressorConfig compressorConfig;
324+
323325
/**
324326
* Constructs a new instance with an empty name.
325327
*/
@@ -854,6 +856,16 @@ public int getMethod() {
854856
return method;
855857
}
856858

859+
/**
860+
* Gets the compressor configuration for this entry.
861+
*
862+
* @return the compressor config, or {@code null} if not set
863+
* @since 1.29.0
864+
*/
865+
public CompressorConfig getCompressorConfig() {
866+
return compressorConfig;
867+
}
868+
857869
/**
858870
* Gets the name of the entry.
859871
*
@@ -1397,6 +1409,18 @@ public void setMethod(final int method) {
13971409
this.method = method;
13981410
}
13991411

1412+
/**
1413+
* Sets the compressor configuration for this entry.
1414+
* When used with {@link ZipArchiveOutputStream} in auto-compress mode,
1415+
* this configuration overrides the factory's default.
1416+
*
1417+
* @param compressorConfig the compressor config, or {@code null} to use the factory default
1418+
* @since 1.29.0
1419+
*/
1420+
public void setCompressorConfig(final CompressorConfig compressorConfig) {
1421+
this.compressorConfig = compressorConfig;
1422+
}
1423+
14001424
/**
14011425
* Sets the name of the entry.
14021426
*

0 commit comments

Comments
 (0)