• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  * http://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.compressors.brotli;
20 
21 /**
22  * Utility code for the Brotli compression format.
23  * @ThreadSafe
24  * @since 1.14
25  */
26 public class BrotliUtils {
27 
28     enum CachedAvailability {
29         DONT_CACHE, CACHED_AVAILABLE, CACHED_UNAVAILABLE
30     }
31 
32     private static volatile CachedAvailability cachedBrotliAvailability;
33 
34     static {
35         cachedBrotliAvailability = CachedAvailability.DONT_CACHE;
36         try {
37             Class.forName("org.osgi.framework.BundleEvent");
38         } catch (final Exception ex) { // NOSONAR
39             setCacheBrotliAvailablity(true);
40         }
41     }
42 
43     /** Private constructor to prevent instantiation of this utility class. */
BrotliUtils()44     private BrotliUtils() {
45     }
46 
47 
48     /**
49      * Are the classes required to support Brotli compression available?
50      * @return true if the classes required to support Brotli compression are available
51      */
isBrotliCompressionAvailable()52     public static boolean isBrotliCompressionAvailable() {
53         final CachedAvailability cachedResult = cachedBrotliAvailability;
54         if (cachedResult != CachedAvailability.DONT_CACHE) {
55             return cachedResult == CachedAvailability.CACHED_AVAILABLE;
56         }
57         return internalIsBrotliCompressionAvailable();
58     }
59 
internalIsBrotliCompressionAvailable()60     private static boolean internalIsBrotliCompressionAvailable() {
61         try {
62             Class.forName("org.brotli.dec.BrotliInputStream");
63             return true;
64         } catch (NoClassDefFoundError | Exception error) { // NOSONAR
65             return false;
66         }
67     }
68 
69     /**
70      * Whether to cache the result of the Brotli for Java check.
71      *
72      * <p>This defaults to {@code false} in an OSGi environment and {@code true} otherwise.</p>
73      * @param doCache whether to cache the result
74      */
setCacheBrotliAvailablity(final boolean doCache)75     public static void setCacheBrotliAvailablity(final boolean doCache) {
76         if (!doCache) {
77             cachedBrotliAvailability = CachedAvailability.DONT_CACHE;
78         } else if (cachedBrotliAvailability == CachedAvailability.DONT_CACHE) {
79             final boolean hasBrotli = internalIsBrotliCompressionAvailable();
80             cachedBrotliAvailability = hasBrotli ? CachedAvailability.CACHED_AVAILABLE
81                 : CachedAvailability.CACHED_UNAVAILABLE;
82         }
83     }
84 
85     // only exists to support unit tests
getCachedBrotliAvailability()86     static CachedAvailability getCachedBrotliAvailability() {
87         return cachedBrotliAvailability;
88     }
89 }
90