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 */
018
019package org.apache.commons.compress.archivers.zip;
020
021import java.util.zip.ZipException;
022
023/**
024 * Exception thrown when attempting to read or write data for a zip
025 * entry that uses ZIP features not supported by this library.
026 * @since 1.1
027 */
028public class UnsupportedZipFeatureException extends ZipException {
029
030    private final Feature reason;
031    private transient final ZipArchiveEntry entry;
032    private static final long serialVersionUID = 20161219L;
033
034    /**
035     * Creates an exception.
036     * @param reason the feature that is not supported
037     * @param entry the entry using the feature
038     */
039    public UnsupportedZipFeatureException(final Feature reason,
040                                          final ZipArchiveEntry entry) {
041        super("unsupported feature " + reason +  " used in entry "
042              + entry.getName());
043        this.reason = reason;
044        this.entry = entry;
045    }
046
047    /**
048     * Creates an exception for archives that use an unsupported
049     * compression algorithm.
050     * @param method the method that is not supported
051     * @param entry the entry using the feature
052     * @since 1.5
053     */
054    public UnsupportedZipFeatureException(final ZipMethod method,
055                                          final ZipArchiveEntry entry) {
056        super("unsupported feature method '" + method.name()
057              +  "' used in entry " + entry.getName());
058        this.reason = Feature.METHOD;
059        this.entry = entry;
060    }
061
062    /**
063     * Creates an exception when the whole archive uses an unsupported
064     * feature.
065     *
066     * @param reason the feature that is not supported
067     * @since 1.5
068     */
069    public UnsupportedZipFeatureException(final Feature reason) {
070        super("unsupported feature " + reason +  " used in archive.");
071        this.reason = reason;
072        this.entry = null;
073    }
074
075    /**
076     * The unsupported feature that has been used.
077     * @return The unsupported feature that has been used.
078     */
079    public Feature getFeature() {
080        return reason;
081    }
082
083    /**
084     * The entry using the unsupported feature.
085     * @return The entry using the unsupported feature.
086     */
087    public ZipArchiveEntry getEntry() {
088        return entry;
089    }
090
091    /**
092     * ZIP Features that may or may not be supported.
093     * @since 1.1
094     */
095    public static class Feature implements java.io.Serializable {
096
097        private static final long serialVersionUID = 4112582948775420359L;
098        /**
099         * The entry is encrypted.
100         */
101        public static final Feature ENCRYPTION = new Feature("encryption");
102        /**
103         * The entry used an unsupported compression method.
104         */
105        public static final Feature METHOD = new Feature("compression method");
106        /**
107         * The entry uses a data descriptor.
108         */
109        public static final Feature DATA_DESCRIPTOR = new Feature("data descriptor");
110        /**
111         * The archive uses splitting or spanning.
112         * @since 1.5
113         */
114        public static final Feature SPLITTING = new Feature("splitting");
115        /**
116         * The archive contains entries with unknown compressed size
117         * for a compression method that doesn't support detection of
118         * the end of the compressed stream.
119         * @since 1.16
120         */
121        public static final Feature UNKNOWN_COMPRESSED_SIZE = new Feature("unknown compressed size");
122
123        private final String name;
124
125        private Feature(final String name) {
126            this.name = name;
127        }
128
129        @Override
130        public String toString() {
131            return name;
132        }
133    }
134}