View Javadoc
1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one or more
3    *  contributor license agreements.  See the NOTICE file distributed with
4    *  this work for additional information regarding copyright ownership.
5    *  The ASF licenses this file to You under the Apache License, Version 2.0
6    *  (the "License"); you may not use this file except in compliance with
7    *  the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   *  Unless required by applicable law or agreed to in writing, software
12   *  distributed under the License is distributed on an "AS IS" BASIS,
13   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   *  See the License for the specific language governing permissions and
15   *  limitations under the License.
16   */
17  package org.apache.commons.compress.archivers.sevenz;
18  
19  import java.io.IOException;
20  import java.io.InputStream;
21  import java.io.OutputStream;
22  import java.util.Objects;
23  import java.util.stream.Stream;
24  
25  import org.apache.commons.compress.utils.ByteUtils;
26  
27  /**
28   * Abstracts a base Codec class.
29   */
30  abstract class AbstractCoder {
31  
32      /**
33       * If the option represents a number, return its integer value, otherwise return the given default value.
34       *
35       * @param options      A Number.
36       * @param defaultValue A default value if options is not a number.
37       * @return The given number or default value.
38       */
39      protected static int toInt(final Object options, final int defaultValue) {
40          return options instanceof Number ? ((Number) options).intValue() : defaultValue;
41      }
42  
43      private final Class<?>[] optionClasses;
44  
45      /**
46       * Constructs a new instance.
47       *
48       * @param optionClasses types that can be used as options for this codec.
49       */
50      protected AbstractCoder(final Class<?>... optionClasses) {
51          this.optionClasses = Objects.requireNonNull(optionClasses, "optionClasses");
52      }
53  
54      /**
55       * Decodes using stream that reads from in using the configured coder and password.
56       *
57       * @return a stream that reads from in using the configured coder and password.
58       */
59      abstract InputStream decode(String archiveName, InputStream in, long uncompressedLength, Coder coder, byte[] password, int maxMemoryLimitInKb)
60              throws IOException;
61  
62      /**
63       * Encodes using a stream that writes to out using the given configuration.
64       *
65       * @return a stream that writes to out using the given configuration.
66       * @throws IOException Optionally thrown by subclassses.
67       */
68      OutputStream encode(final OutputStream out, final Object options) throws IOException {
69          throw new UnsupportedOperationException("Method doesn't support writing");
70      }
71  
72      /**
73       * Gets property bytes to write in a Folder block.
74       *
75       * @return property bytes to write in a Folder block.
76       * @throws IOException Optionally thrown by subclassses.
77       */
78      byte[] getOptionsAsProperties(final Object options) throws IOException {
79          return ByteUtils.EMPTY_BYTE_ARRAY;
80      }
81  
82      /**
83       * Gets configuration options that have been used to create the given InputStream from the given Coder.
84       *
85       * @return configuration options that have been used to create the given InputStream from the given Coder
86       * @throws IOException Optionally thrown by subclassses.
87       */
88      Object getOptionsFromCoder(final Coder coder, final InputStream in) throws IOException {
89          return null;
90      }
91  
92      /**
93       * Tests whether this method can extract options from the given object.
94       *
95       * @return whether this method can extract options from the given object.
96       */
97      boolean isOptionInstance(final Object opts) {
98          return Stream.of(optionClasses).anyMatch(c -> c.isInstance(opts));
99      }
100 }