001/*
002 *  Licensed to the Apache Software Foundation (ASF) under one or more
003 *  contributor license agreements.  See the NOTICE file distributed with
004 *  this work for additional information regarding copyright ownership.
005 *  The ASF licenses this file to You under the Apache License, Version 2.0
006 *  (the "License"); you may not use this file except in compliance with
007 *  the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 *  Unless required by applicable law or agreed to in writing, software
012 *  distributed under the License is distributed on an "AS IS" BASIS,
013 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 *  See the License for the specific language governing permissions and
015 *  limitations under the License.
016 *
017 */
018package org.apache.commons.compress.archivers.sevenz;
019
020/**
021 * Collects options for reading 7z archives.
022 *
023 * @since 1.19
024 * @Immutable
025 */
026public class SevenZFileOptions {
027    private static final int DEFAUL_MEMORY_LIMIT_IN_KB = Integer.MAX_VALUE;
028    private static final boolean DEFAULT_USE_DEFAULTNAME_FOR_UNNAMED_ENTRIES= false;
029    private static final boolean DEFAULT_TRY_TO_RECOVER_BROKEN_ARCHIVES = false;
030
031    private final int maxMemoryLimitInKb;
032    private final boolean useDefaultNameForUnnamedEntries;
033    private final boolean tryToRecoverBrokenArchives;
034
035    private SevenZFileOptions(final int maxMemoryLimitInKb, final boolean useDefaultNameForUnnamedEntries,
036        final boolean tryToRecoverBrokenArchives) {
037        this.maxMemoryLimitInKb = maxMemoryLimitInKb;
038        this.useDefaultNameForUnnamedEntries = useDefaultNameForUnnamedEntries;
039        this.tryToRecoverBrokenArchives = tryToRecoverBrokenArchives;
040    }
041
042    /**
043     * The default options.
044     *
045     * <ul>
046     *   <li>no memory limit</li>
047     *   <li>don't modify the name of unnamed entries</li>
048     * </ul>
049     */
050    public static final SevenZFileOptions DEFAULT = new SevenZFileOptions(DEFAUL_MEMORY_LIMIT_IN_KB,
051        DEFAULT_USE_DEFAULTNAME_FOR_UNNAMED_ENTRIES,
052        DEFAULT_TRY_TO_RECOVER_BROKEN_ARCHIVES);
053
054    /**
055     * Obtains a builder for SevenZFileOptions.
056     * @return a builder for SevenZFileOptions.
057     */
058    public static Builder builder() {
059        return new Builder();
060    }
061
062    /**
063     * Gets the maximum amount of memory to use for parsing the
064     * archive and during extraction.
065     *
066     * <p>Not all codecs will honor this setting. Currently only lzma
067     * and lzma2 are supported.</p>
068     *
069     * @return the maximum amount of memory to use for extraction
070     */
071    public int getMaxMemoryLimitInKb() {
072        return maxMemoryLimitInKb;
073    }
074
075    /**
076     * Gets whether entries without a name should get their names set
077     * to the archive's default file name.
078     * @return whether entries without a name should get their names
079     * set to the archive's default file name
080     */
081    public boolean getUseDefaultNameForUnnamedEntries() {
082        return useDefaultNameForUnnamedEntries;
083    }
084
085    /**
086     * Whether {@link SevenZFile} shall try to recover from a certain type of broken archive.
087     * @return whether SevenZFile shall try to recover from a certain type of broken archive.
088     * @since 1.21
089     */
090    public boolean getTryToRecoverBrokenArchives() {
091        return tryToRecoverBrokenArchives;
092    }
093
094    /**
095     * Mutable builder for the immutable {@link SevenZFileOptions}.
096     *
097     * @since 1.19
098     */
099    public static class Builder {
100        private int maxMemoryLimitInKb = DEFAUL_MEMORY_LIMIT_IN_KB;
101        private boolean useDefaultNameForUnnamedEntries = DEFAULT_USE_DEFAULTNAME_FOR_UNNAMED_ENTRIES;
102        private boolean tryToRecoverBrokenArchives = DEFAULT_TRY_TO_RECOVER_BROKEN_ARCHIVES;
103
104        /**
105         * Sets the maximum amount of memory to use for parsing the
106         * archive and during extraction.
107         *
108         * <p>Not all codecs will honor this setting. Currently only lzma
109         * and lzma2 are supported.</p>
110         *
111         * @param maxMemoryLimitInKb limit of the maximum amount of memory to use
112         * @return the reconfigured builder
113         */
114        public Builder withMaxMemoryLimitInKb(final int maxMemoryLimitInKb) {
115            this.maxMemoryLimitInKb = maxMemoryLimitInKb;
116            return this;
117        }
118
119        /**
120         * Sets whether entries without a name should get their names
121         * set to the archive's default file name.
122         *
123         * @param useDefaultNameForUnnamedEntries if true the name of
124         * unnamed entries will be set to the archive's default name
125         * @return the reconfigured builder
126         */
127        public Builder withUseDefaultNameForUnnamedEntries(final boolean useDefaultNameForUnnamedEntries) {
128            this.useDefaultNameForUnnamedEntries = useDefaultNameForUnnamedEntries;
129            return this;
130        }
131
132        /**
133         * Sets whether {@link SevenZFile} will try to revover broken archives where the CRC of the file's metadata is
134         * 0.
135         *
136         * <p>This special kind of broken archive is encountered when mutli volume archives are closed prematurely. If
137         * you enable this option SevenZFile will trust data that looks as if it could contain metadata of an archive
138         * and allocate big amounts of memory. It is strongly recommended to not enable this option without setting
139         * {@link #withMaxMemoryLimitInKb} at the same time.
140         *
141         * @param tryToRecoverBrokenArchives if true SevenZFile will try to recover archives that are broken in the
142         * specific way
143         * @return the reconfigured builder
144         * @since 1.21
145         */
146        public Builder withTryToRecoverBrokenArchives(final boolean tryToRecoverBrokenArchives) {
147            this.tryToRecoverBrokenArchives = tryToRecoverBrokenArchives;
148            return this;
149        }
150
151        /**
152         * Create the {@link SevenZFileOptions}.
153         *
154         * @return configured {@link SevenZFileOptions}.
155         */
156        public SevenZFileOptions build() {
157            return new SevenZFileOptions(maxMemoryLimitInKb, useDefaultNameForUnnamedEntries,
158                tryToRecoverBrokenArchives);
159        }
160    }
161}