View Javadoc
1   /*
2    * This file is part of dependency-check-utils.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   *
16   * Copyright (c) 2012 Jeremy Long. All Rights Reserved.
17   */
18  package org.owasp.dependencycheck.utils;
19  
20  import java.io.Closeable;
21  import java.io.File;
22  import java.io.FileInputStream;
23  import java.io.FileNotFoundException;
24  import java.io.IOException;
25  import java.io.InputStream;
26  import java.net.URL;
27  import java.nio.file.Files;
28  import java.nio.file.Path;
29  import java.util.Comparator;
30  import java.util.UUID;
31  import java.util.stream.Stream;
32  
33  import org.apache.commons.io.FilenameUtils;
34  import org.apache.commons.lang3.StringUtils;
35  import org.apache.commons.lang3.SystemUtils;
36  import org.jetbrains.annotations.NotNull;
37  import org.jetbrains.annotations.Nullable;
38  import org.slf4j.Logger;
39  import org.slf4j.LoggerFactory;
40  
41  /**
42   * A collection of utilities for processing information about files.
43   *
44   * @author Jeremy Long
45   */
46  public final class FileUtils {
47  
48      /**
49       * The logger.
50       */
51      private static final Logger LOGGER = LoggerFactory.getLogger(FileUtils.class);
52      /**
53       * Bit bucket for non-Windows systems
54       */
55      private static final String BIT_BUCKET_UNIX = "/dev/null";
56  
57      /**
58       * Bit bucket for Windows systems (yes, only one 'L')
59       */
60      private static final String BIT_BUCKET_WIN = "NUL";
61  
62      /**
63       * Private constructor for a utility class.
64       */
65      private FileUtils() {
66      }
67  
68      /**
69       * Returns the (lowercase) file extension for a specified file.
70       *
71       * @param fileName the file name to retrieve the file extension from.
72       * @return the file extension.
73       */
74      @Nullable
75      public static String getFileExtension(@NotNull String fileName) {
76          @Nullable
77          final String fileExt = FilenameUtils.getExtension(fileName);
78          return StringUtils.isNoneEmpty(fileExt) ? StringUtils.lowerCase(fileExt) : null;
79      }
80  
81      /**
82       * Deletes a file. If the File is a directory it will recursively delete the
83       * contents.
84       *
85       * @param file the File to delete
86       * @return true if the file was deleted successfully, otherwise false
87       */
88      public static boolean delete(@Nullable File file) {
89          if (file == null) {
90              LOGGER.warn("cannot delete null File");
91              return false;
92          }
93  
94          try (Stream<Path> paths = Files.walk(file.toPath())) {
95              paths.sorted(Comparator.reverseOrder())
96              .map(Path::toFile)
97              .forEach(File::delete);
98          } catch (IOException ex) {
99              LOGGER.trace(ex.getMessage(), ex);
100             LOGGER.debug("Failed to delete file: {} (error message: {}); attempting to delete on exit.", file.getPath(), ex.getMessage());
101             file.deleteOnExit();
102             return false;
103         }
104 
105         return true;
106     }
107 
108     /**
109      * Creates a unique temporary directory in the given directory.
110      *
111      * @param base the base directory to create a temporary directory within
112      * @return the temporary directory
113      * @throws java.io.IOException thrown when a directory cannot be created
114      * within the base directory
115      */
116     @NotNull
117     public static File createTempDirectory(@Nullable final File base) throws IOException {
118         final File tempDir = new File(base, "dctemp" + UUID.randomUUID());
119         if (tempDir.exists()) {
120             return createTempDirectory(base);
121         }
122         if (!tempDir.mkdirs()) {
123             throw new IOException("Could not create temp directory `" + tempDir.getAbsolutePath() + "`");
124         }
125         LOGGER.debug("Temporary directory is `{}`", tempDir.getAbsolutePath());
126         return tempDir;
127     }
128 
129     /**
130      * Return the bit bucket for the OS. '/dev/null' for Unix and 'NUL' for
131      * Windows
132      *
133      * @return a String containing the bit bucket
134      */
135     @NotNull
136     public static String getBitBucket() {
137         return SystemUtils.IS_OS_WINDOWS ? BIT_BUCKET_WIN : BIT_BUCKET_UNIX;
138     }
139 
140     /**
141      * Close the given {@link java.io.Closeable} instance, ignoring nulls, and
142      * logging any thrown {@link java.io.IOException}.
143      *
144      * @param closeable to be closed
145      */
146     public static void close(@Nullable final Closeable closeable) {
147         if (null != closeable) {
148             try {
149                 closeable.close();
150             } catch (IOException ex) {
151                 LOGGER.trace("", ex);
152             }
153         }
154     }
155 
156     /**
157      * Gets the {@link java.io.InputStream} for this resource.
158      *
159      * @param resource path
160      * @return the input stream for the given resource
161      * @throws FileNotFoundException if the file could not be found
162      */
163     @Nullable
164     public static InputStream getResourceAsStream(@NotNull String resource) throws FileNotFoundException {
165         final ClassLoader classLoader = FileUtils.class.getClassLoader();
166         final InputStream inputStream = classLoader != null
167                 ? classLoader.getResourceAsStream(resource)
168                 : ClassLoader.getSystemResourceAsStream(resource);
169 
170         if (inputStream == null) {
171             return new FileInputStream(resource);
172         }
173         return inputStream;
174     }
175 
176     /**
177      * Returns a File object for the given resource. The resource is attempted
178      * to be loaded from the class loader.
179      *
180      * @param resource path
181      * @return the file reference for the resource
182      */
183     public static File getResourceAsFile(final String resource) {
184         final ClassLoader classLoader = FileUtils.class.getClassLoader();
185         String path = null;
186         if (classLoader != null) {
187             final URL url = classLoader.getResource(resource);
188             if (url != null) {
189                 path = url.getFile();
190             }
191         } else {
192             path = ClassLoader.getSystemResource(resource).getFile();
193         }
194 
195         if (path == null) {
196             return new File(resource);
197         }
198         return new File(path);
199     }
200 }