View Javadoc
1   /*
2    * Copyright 2021-2022 The OSHI Project Contributors
3    * SPDX-License-Identifier: MIT
4    */
5   package oshi.util;
6   
7   import java.nio.file.FileSystem;
8   import java.nio.file.FileSystems;
9   import java.nio.file.Path;
10  import java.nio.file.PathMatcher;
11  import java.nio.file.Paths;
12  import java.util.ArrayList;
13  import java.util.List;
14  
15  import oshi.annotation.concurrent.ThreadSafe;
16  
17  /**
18   * Utility class for common filesystem code
19   */
20  @ThreadSafe
21  public final class FileSystemUtil {
22  
23      private static final String GLOB_PREFIX = "glob:";
24      private static final String REGEX_PREFIX = "regex:";
25  
26      private FileSystemUtil() {
27      }
28  
29      /**
30       * Evaluates if file store (identified by {@code path} and {@code volume}) should be excluded or not based on
31       * configuration {@code pathIncludes, pathExcludes, volumeIncludes, volumeExcludes}.
32       *
33       * Inclusion has priority over exclusion. If no exclusion/inclusion pattern is specified, then filestore is not
34       * excluded.
35       *
36       * @param path           Mountpoint of filestore.
37       * @param volume         Filestore volume.
38       * @param pathIncludes   List of patterns for path inclusions.
39       * @param pathExcludes   List of patterns for path exclusions.
40       * @param volumeIncludes List of patterns for volume inclusions.
41       * @param volumeExcludes List of patterns for volume exclusions.
42       * @return {@code true} if file store should be excluded or {@code false} otherwise.
43       */
44      public static boolean isFileStoreExcluded(String path, String volume, List<PathMatcher> pathIncludes,
45              List<PathMatcher> pathExcludes, List<PathMatcher> volumeIncludes, List<PathMatcher> volumeExcludes) {
46          Path p = Paths.get(path);
47          Path v = Paths.get(volume);
48          if (matches(p, pathIncludes) || matches(v, volumeIncludes)) {
49              return false;
50          }
51          return matches(p, pathExcludes) || matches(v, volumeExcludes);
52      }
53  
54      /**
55       * Load from config and parse file system include/exclude line.
56       *
57       * @param configPropertyName The config property containing the line to be parsed.
58       * @return List of PathMatchers to be used to match filestore volume and path.
59       */
60      public static List<PathMatcher> loadAndParseFileSystemConfig(String configPropertyName) {
61          String config = GlobalConfig.get(configPropertyName, "");
62          return parseFileSystemConfig(config);
63      }
64  
65      /**
66       * Parse file system include/exclude line.
67       *
68       * @param config The config line to be parsed.
69       * @return List of PathMatchers to be used to match filestore volume and path.
70       */
71      public static List<PathMatcher> parseFileSystemConfig(String config) {
72          FileSystem fs = FileSystems.getDefault(); // can't be closed
73          List<PathMatcher> patterns = new ArrayList<>();
74          for (String item : config.split(",")) {
75              if (item.length() > 0) {
76                  // Using glob: prefix as the defult unless user has specified glob or regex. See
77                  // https://docs.oracle.com/javase/8/docs/api/java/nio/file/FileSystem.html#getPathMatcher-java.lang.String-
78                  if (!(item.startsWith(GLOB_PREFIX) || item.startsWith(REGEX_PREFIX))) {
79                      item = GLOB_PREFIX + item;
80                  }
81                  patterns.add(fs.getPathMatcher(item));
82              }
83          }
84          return patterns;
85      }
86  
87      /**
88       * Checks if {@code text} matches any of @param patterns}.
89       *
90       * @param text     The text to be matched.
91       * @param patterns List of patterns.
92       * @return {@code true} if given text matches at least one glob pattern or {@code false} otherwise.
93       * @see <a href="https://en.wikipedia.org/wiki/Glob_(programming)">Wikipedia - glob (programming)</a>
94       */
95      public static boolean matches(Path text, List<PathMatcher> patterns) {
96          for (PathMatcher pattern : patterns) {
97              if (pattern.matches(text)) {
98                  return true;
99              }
100         }
101         return false;
102     }
103 
104 }