• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

hazendaz / smartsprites / 555

21 May 2026 03:26PM UTC coverage: 87.799%. Remained the same
555

push

github

hazendaz
[tests] Fix tests that were looking at size of original license before spdx change

557 of 670 branches covered (83.13%)

Branch coverage included in aggregate %.

1350 of 1502 relevant lines covered (89.88%)

0.9 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

84.75
/src/main/java/org/carrot2/util/FileUtils.java
1
/*
2
 * SPDX-License-Identifier: BSD-3-Clause
3
 * See LICENSE file for details.
4
 *
5
 * Copyright 2021-2026 Hazendaz
6
 * Copyright (C) 2007-2009, Stanisław Osiński.
7
 */
8
package org.carrot2.util;
9

10
import java.io.File;
11
import java.io.IOException;
12
import java.nio.file.Path;
13
import java.util.ArrayList;
14
import java.util.regex.Pattern;
15

16
import org.apache.commons.io.FilenameUtils;
17

18
/**
19
 * Various utility methods for working with {@link File}s.
20
 */
21
public class FileUtils {
22

23
    /**
24
     * Instantiates a new file utils.
25
     */
26
    private FileUtils() {
27
        // Prevent Instantiation
28
    }
29

30
    /**
31
     * Creates a new {@link File} from the provided path and attempts to execute {@link File#getCanonicalFile()}. In
32
     * case of a failure, returns the result of {@link File#getAbsoluteFile()}.
33
     *
34
     * @param path
35
     *            the path
36
     *
37
     * @return the canonical or absolute file
38
     */
39
    public static File getCanonicalOrAbsoluteFile(String path) {
40
        File file = Path.of(path).toFile();
1✔
41
        try {
42
            return file.getCanonicalFile();
1✔
43
        } catch (final IOException e) {
×
44
            return file.getAbsoluteFile();
×
45
        }
46
    }
47

48
    /**
49
     * Changes the root directory of a file. For example, file is /a/b/c/d/e and oldRoot is /a/b/c, and newRoot is /x/y,
50
     * the result will be /x/y/d/e.
51
     *
52
     * @param file
53
     *            the file
54
     * @param oldRoot
55
     *            the old root
56
     * @param newRoot
57
     *            the new root
58
     *
59
     * @return the string
60
     */
61
    public static String changeRoot(String file, String oldRoot, String newRoot) {
62
        // File is assumed to be a subpath of oldRoot, so PathUtils.getRelativeFilePath()
63
        // shouldn't return null here.
64
        final String relativePath = PathUtils.getRelativeFilePath(oldRoot, file);
1✔
65
        return FilenameUtils.concat(newRoot, relativePath);
1✔
66
    }
67

68
    /**
69
     * Removes useless segments in relative paths, e.g. replaces <code>../path/../other/file.css</code> with
70
     * <code>../other/file.css</code>
71
     *
72
     * @param path
73
     *            the path
74
     * @param separator
75
     *            the separator
76
     *
77
     * @return the string
78
     */
79
    public static String canonicalize(String path, String separator) {
80
        String replaced = path;
1✔
81
        String toReplace = null;
1✔
82
        final String separatorEscaped = Pattern.quote(separator);
1✔
83
        final Pattern pattern = Pattern
1✔
84
                .compile("[^" + separatorEscaped + "\\.]+" + separatorEscaped + "\\.\\." + separatorEscaped + "?");
1✔
85
        while (!replaced.equals(toReplace)) {
1✔
86
            toReplace = replaced;
1✔
87
            replaced = pattern.matcher(toReplace).replaceFirst("");
1✔
88
        }
89
        return replaced;
1✔
90
    }
91

92
    /**
93
     * Attempts to delete the provided files and throws an {@link IOException} in case {@link File#delete()} returns
94
     * <code>false</code> for any of them.
95
     *
96
     * @param files
97
     *            the files
98
     *
99
     * @throws IOException
100
     *             Signals that an I/O exception has occurred.
101
     */
102
    public static void deleteThrowingExceptions(File... files) throws IOException {
103
        if (files == null) {
1✔
104
            return;
1✔
105
        }
106

107
        final ArrayList<String> undeletedFiles = new ArrayList<>();
1✔
108
        for (File file : files) {
1✔
109
            if (file == null) {
1✔
110
                continue;
1✔
111
            }
112

113
            if (file.exists() && !file.delete()) {
1!
114
                undeletedFiles.add(file.getPath());
×
115
            }
116
        }
117

118
        if (!undeletedFiles.isEmpty()) {
1!
119
            throw new IOException("Unable to delete files: " + undeletedFiles.toString());
×
120
        }
121
    }
1✔
122

123
    /**
124
     * Calls {@link File#mkdirs()} on the provided argument and throws an {@link IOException} if the call returns
125
     * <code>false</code>.
126
     *
127
     * @param dirs
128
     *            the dirs
129
     *
130
     * @throws IOException
131
     *             Signals that an I/O exception has occurred.
132
     */
133
    public static void mkdirsThrowingExceptions(File dirs) throws IOException {
134
        if (dirs.exists()) {
1✔
135
            return;
1✔
136
        }
137

138
        if (!dirs.mkdirs()) {
1!
139
            throw new IOException("Unable to create directories: " + dirs.getPath());
×
140
        }
141
    }
1✔
142

143
    /**
144
     * Returns <code>true</code> if file is contained in the parent directory or any parent of the parent directory.
145
     *
146
     * @param file
147
     *            the file
148
     * @param parent
149
     *            the parent
150
     *
151
     * @return true, if is file in parent
152
     */
153
    public static boolean isFileInParent(File file, File parent) {
154
        final File fileParent = file.getParentFile();
1✔
155
        if (fileParent == null) {
1✔
156
            return false;
1✔
157
        }
158

159
        if (fileParent.equals(parent)) {
1✔
160
            return true;
1✔
161
        }
162

163
        return isFileInParent(fileParent, parent);
1✔
164
    }
165
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc