001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *   https://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.apache.commons.compress.archivers.zip;
020
021import java.util.Collections;
022import java.util.Map;
023import java.util.function.Function;
024import java.util.stream.Collectors;
025import java.util.stream.Stream;
026import java.util.zip.ZipEntry;
027
028/**
029 * Enumerates known compression methods.
030 *
031 * Some of these methods are currently not supported by commons compress.
032 *
033 * @since 1.5
034 */
035public enum ZipMethod {
036
037    /**
038     * Compression method 0 for uncompressed entries.
039     *
040     * @see ZipEntry#STORED
041     */
042    STORED(ZipEntry.STORED),
043
044    /**
045     * UnShrinking. dynamic Lempel-Ziv-Welch-Algorithm
046     *
047     * @see <a href="https://www.pkware.com/documents/casestudies/APPNOTE.TXT">Explanation of fields: compression method: (2 bytes)</a>
048     */
049    UNSHRINKING(1),
050
051    /**
052     * Reduced with compression factor 1.
053     *
054     * @see <a href="https://www.pkware.com/documents/casestudies/APPNOTE.TXT">Explanation of fields: compression method: (2 bytes)</a>
055     */
056    EXPANDING_LEVEL_1(2),
057
058    /**
059     * Reduced with compression factor 2.
060     *
061     * @see <a href="https://www.pkware.com/documents/casestudies/APPNOTE.TXT">Explanation of fields: compression method: (2 bytes)</a>
062     */
063    EXPANDING_LEVEL_2(3),
064
065    /**
066     * Reduced with compression factor 3.
067     *
068     * @see <a href="https://www.pkware.com/documents/casestudies/APPNOTE.TXT">Explanation of fields: compression method: (2 bytes)</a>
069     */
070    EXPANDING_LEVEL_3(4),
071
072    /**
073     * Reduced with compression factor 4.
074     *
075     * @see <a href="https://www.pkware.com/documents/casestudies/APPNOTE.TXT">Explanation of fields: compression method: (2 bytes)</a>
076     */
077    EXPANDING_LEVEL_4(5),
078
079    /**
080     * Imploding.
081     *
082     * @see <a href="https://www.pkware.com/documents/casestudies/APPNOTE.TXT">Explanation of fields: compression method: (2 bytes)</a>
083     */
084    IMPLODING(6),
085
086    /**
087     * Tokenization.
088     *
089     * @see <a href="https://www.pkware.com/documents/casestudies/APPNOTE.TXT">Explanation of fields: compression method: (2 bytes)</a>
090     */
091    TOKENIZATION(7),
092
093    /**
094     * Compression method 8 for compressed (deflated) entries.
095     *
096     * @see ZipEntry#DEFLATED
097     */
098    DEFLATED(ZipEntry.DEFLATED),
099
100    /**
101     * Compression Method 9 for enhanced deflate.
102     *
103     * @see <a href="https://www.pkware.com/documents/casestudies/APPNOTE.TXT">Explanation of fields: compression method: (2 bytes)</a>
104     */
105    ENHANCED_DEFLATED(9),
106
107    /**
108     * PKWARE Data Compression Library Imploding.
109     *
110     * @see <a href="https://www.pkware.com/documents/casestudies/APPNOTE.TXT">Explanation of fields: compression method: (2 bytes)</a>
111     */
112    PKWARE_IMPLODING(10),
113
114    /**
115     * Compression Method 12 for bzip2.
116     *
117     * @see <a href="https://www.pkware.com/documents/casestudies/APPNOTE.TXT">Explanation of fields: compression method: (2 bytes)</a>
118     */
119    BZIP2(12),
120
121    /**
122     * Compression Method 14 for LZMA.
123     *
124     * @see <a href="https://www.7-zip.org/sdk.html">https://www.7-zip.org/sdk.html</a>
125     * @see <a href="https://www.pkware.com/documents/casestudies/APPNOTE.TXT">Explanation of fields: compression method: (2 bytes)</a>
126     */
127    LZMA(14),
128
129    /**
130     * Compression Method 20 for Zstandard (deprecated).
131     *
132     * @see <a href="https://github.com/facebook/zstd">Facebook Zstandard source code</a>
133     * @see <a href="https://pkwaredownloads.blob.core.windows.net/pkware-general/Documentation/APPNOTE-6.3.7.TXT">.ZIP File Format Specification 6.3.7:
134     *      Deprecated zstd compression method id</a>
135     * @see <a href="https://www.pkware.com/documents/casestudies/APPNOTE.TXT">.ZIP File Format Specification: Explanation of fields: compression method: (2
136     *      bytes)</a>
137     * @since 1.28.0
138     */
139    ZSTD_DEPRECATED(20),
140
141    /**
142     * Compression Method 93 for Zstandard.
143     *
144     * @see <a href="https://github.com/facebook/zstd">Facebook Zstandard source code</a>
145     * @see <a href="https://pkwaredownloads.blob.core.windows.net/pkware-general/Documentation/APPNOTE-6.3.8.TXT">.ZIP File Format Specification 6.3.8: Changed
146     *      zstd compression method id</a>
147     * @see <a href="https://www.pkware.com/documents/casestudies/APPNOTE.TXT">.ZIP File Format Specification: Explanation of fields: compression method: (2
148     *      bytes)</a>
149     * @since 1.28.0
150     */
151    ZSTD(93),
152
153    /**
154     * Compression Method 95 for XZ.
155     *
156     * @see <a href="https://www.pkware.com/documents/casestudies/APPNOTE.TXT">Explanation of fields: compression method: (2 bytes)</a>
157     */
158    XZ(95),
159
160    /**
161     * Compression Method 96 for Jpeg compression.
162     *
163     * @see <a href="https://www.pkware.com/documents/casestudies/APPNOTE.TXT">Explanation of fields: compression method: (2 bytes)</a>
164     */
165    JPEG(96),
166
167    /**
168     * Compression Method 97 for WavPack.
169     *
170     * @see <a href="https://www.pkware.com/documents/casestudies/APPNOTE.TXT">Explanation of fields: compression method: (2 bytes)</a>
171     */
172    WAVPACK(97),
173
174    /**
175     * Compression Method 98 for PPMd.
176     *
177     * @see <a href="https://www.pkware.com/documents/casestudies/APPNOTE.TXT">Explanation of fields: compression method: (2 bytes)</a>
178     */
179    PPMD(98),
180
181    /**
182     * Compression Method 99 for AES encryption.
183     *
184     * @see <a href="https://www.pkware.com/documents/casestudies/APPNOTE.TXT">Explanation of fields: compression method: (2 bytes)</a>
185     */
186    AES_ENCRYPTED(99),
187
188    /**
189     * Unknown compression method.
190     */
191    UNKNOWN();
192
193    static final int UNKNOWN_CODE = -1;
194
195    private static final Map<Integer, ZipMethod> codeToEnum = Collections
196            .unmodifiableMap(Stream.of(values()).collect(Collectors.toMap(ZipMethod::getCode, Function.identity())));
197
198    /**
199     * Gets the {@link ZipMethod} for the given code or null if the method is not known.
200     *
201     * @param code the code
202     * @return the {@link ZipMethod} for the given code or null if the method is not known.
203     */
204    public static ZipMethod getMethodByCode(final int code) {
205        return codeToEnum.get(code);
206    }
207
208    /**
209     * Tests whether the given ZIP method is a ZStandard method.
210     *
211     * @param method The method to test.
212     * @return Whether the given ZIP method is a ZStandard method.
213     */
214    static boolean isZstd(final int method) {
215        return method == ZSTD.getCode() || method == ZSTD_DEPRECATED.getCode();
216    }
217
218    private final int code;
219
220    ZipMethod() {
221        this(UNKNOWN_CODE);
222    }
223
224    /**
225     * Constructs a new instance.
226     */
227    ZipMethod(final int code) {
228        this.code = code;
229    }
230
231    /**
232     * Gets the code of the compression method.
233     *
234     * @see ZipArchiveEntry#getMethod()
235     * @return an integer code for the method
236     */
237    public int getCode() {
238        return code;
239    }
240}