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

hazendaz / smartsprites / 266

03 May 2025 07:20PM UTC coverage: 84.619%. Remained the same
266

push

github

hazendaz
Use path over file and fix test that would now break with modern usage (had extra /)

533 of 658 branches covered (81.0%)

Branch coverage included in aggregate %.

1277 of 1481 relevant lines covered (86.23%)

0.86 hits per line

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

77.97
/src/main/java/org/carrot2/util/FileUtils.java
1
/*
2
 * SmartSprites Project
3
 *
4
 * Copyright (C) 2007-2009, Stanisław Osiński.
5
 * All rights reserved.
6
 *
7
 * Redistribution and use in source and binary forms, with or without modification,
8
 * are permitted provided that the following conditions are met:
9
 *
10
 * - Redistributions of  source code must  retain the above  copyright notice, this
11
 *   list of conditions and the following disclaimer.
12
 *
13
 * - Redistributions in binary form must reproduce the above copyright notice, this
14
 *   list of conditions and the following  disclaimer in  the documentation  and/or
15
 *   other materials provided with the distribution.
16
 *
17
 * - Neither the name of the SmartSprites Project nor the names of its contributors
18
 *   may  be used  to endorse  or  promote  products derived   from  this  software
19
 *   without specific prior written permission.
20
 *
21
 * - We kindly request that you include in the end-user documentation provided with
22
 *   the redistribution and/or in the software itself an acknowledgement equivalent
23
 *   to  the  following: "This product includes software developed by the SmartSprites
24
 *   Project."
25
 *
26
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"  AND
27
 * ANY EXPRESS OR  IMPLIED WARRANTIES, INCLUDING,  BUT NOT LIMITED  TO, THE IMPLIED
28
 * WARRANTIES  OF  MERCHANTABILITY  AND  FITNESS  FOR  A  PARTICULAR  PURPOSE   ARE
29
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE  FOR
30
 * ANY DIRECT, INDIRECT, INCIDENTAL,  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL  DAMAGES
31
 * (INCLUDING, BUT  NOT LIMITED  TO, PROCUREMENT  OF SUBSTITUTE  GOODS OR SERVICES;
32
 * LOSS OF USE, DATA, OR PROFITS;  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND  ON
33
 * ANY  THEORY  OF  LIABILITY,  WHETHER  IN  CONTRACT,  STRICT  LIABILITY,  OR TORT
34
 * (INCLUDING NEGLIGENCE OR OTHERWISE)  ARISING IN ANY WAY  OUT OF THE USE  OF THIS
35
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36
 */
37
package org.carrot2.util;
38

39
import java.io.File;
40
import java.io.IOException;
41
import java.nio.file.Path;
42
import java.util.ArrayList;
43
import java.util.regex.Pattern;
44

45
import org.apache.commons.io.FilenameUtils;
46

47
/**
48
 * Various utility methods for working with {@link File}s.
49
 */
50
public class FileUtils {
51

52
    /**
53
     * Instantiates a new file utils.
54
     */
55
    private FileUtils() {
56
        // Prevent Instantiation
57
    }
58

59
    /**
60
     * Creates a new {@link File} from the provided path and attempts to execute {@link File#getCanonicalFile()}. In
61
     * case of a failure, returns the result of {@link File#getAbsoluteFile()}.
62
     *
63
     * @param path
64
     *            the path
65
     *
66
     * @return the canonical or absolute file
67
     */
68
    public static File getCanonicalOrAbsoluteFile(String path) {
69
        File file = Path.of(path).toFile();
1✔
70
        try {
71
            return file.getCanonicalFile();
1✔
72
        } catch (final IOException e) {
×
73
            return file.getAbsoluteFile();
×
74
        }
75
    }
76

77
    /**
78
     * 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,
79
     * the result will be /x/y/d/e.
80
     *
81
     * @param file
82
     *            the file
83
     * @param oldRoot
84
     *            the old root
85
     * @param newRoot
86
     *            the new root
87
     *
88
     * @return the string
89
     */
90
    public static String changeRoot(String file, String oldRoot, String newRoot) {
91
        // File is assumed to be a subpath of oldRoot, so PathUtils.getRelativeFilePath()
92
        // shouldn't return null here.
93
        final String relativePath = PathUtils.getRelativeFilePath(oldRoot, file);
1✔
94
        return FilenameUtils.concat(newRoot, relativePath);
1✔
95
    }
96

97
    /**
98
     * Removes useless segments in relative paths, e.g. replaces <code>../path/../other/file.css</code> with
99
     * <code>../other/file.css</code>
100
     *
101
     * @param path
102
     *            the path
103
     * @param separator
104
     *            the separator
105
     *
106
     * @return the string
107
     */
108
    public static String canonicalize(String path, String separator) {
109
        String replaced = path;
1✔
110
        String toReplace = null;
1✔
111
        final String separatorEscaped = Pattern.quote(separator);
1✔
112
        final Pattern pattern = Pattern
1✔
113
                .compile("[^" + separatorEscaped + "\\.]+" + separatorEscaped + "\\.\\." + separatorEscaped + "?");
1✔
114
        while (!replaced.equals(toReplace)) {
1✔
115
            toReplace = replaced;
1✔
116
            replaced = pattern.matcher(toReplace).replaceFirst("");
1✔
117
        }
118
        return replaced;
1✔
119
    }
120

121
    /**
122
     * Attempts to delete the provided files and throws an {@link IOException} in case {@link File#delete()} returns
123
     * <code>false</code> for any of them.
124
     *
125
     * @param files
126
     *            the files
127
     *
128
     * @throws IOException
129
     *             Signals that an I/O exception has occurred.
130
     */
131
    public static void deleteThrowingExceptions(File... files) throws IOException {
132
        if (files == null) {
1✔
133
            return;
1✔
134
        }
135

136
        final ArrayList<String> undeletedFiles = new ArrayList<>();
1✔
137
        for (File file : files) {
1✔
138
            if (file == null) {
1!
139
                continue;
×
140
            }
141

142
            if (file.exists() && !file.delete()) {
1!
143
                undeletedFiles.add(file.getPath());
×
144
            }
145
        }
146

147
        if (!undeletedFiles.isEmpty()) {
1!
148
            throw new IOException("Unable to delete files: " + undeletedFiles.toString());
×
149
        }
150
    }
1✔
151

152
    /**
153
     * Calls {@link File#mkdirs()} on the provided argument and throws an {@link IOException} if the call returns
154
     * <code>false</code>.
155
     *
156
     * @param dirs
157
     *            the dirs
158
     *
159
     * @throws IOException
160
     *             Signals that an I/O exception has occurred.
161
     */
162
    public static void mkdirsThrowingExceptions(File dirs) throws IOException {
163
        if (dirs.exists()) {
1!
164
            return;
×
165
        }
166

167
        if (!dirs.mkdirs()) {
1!
168
            throw new IOException("Unable to create directories: " + dirs.getPath());
×
169
        }
170
    }
1✔
171

172
    /**
173
     * Returns <code>true</code> if file is contained in the parent directory or any parent of the parent directory.
174
     *
175
     * @param file
176
     *            the file
177
     * @param parent
178
     *            the parent
179
     *
180
     * @return true, if is file in parent
181
     */
182
    public static boolean isFileInParent(File file, File parent) {
183
        final File fileParent = file.getParentFile();
1✔
184
        if (fileParent == null) {
1✔
185
            return false;
1✔
186
        }
187

188
        if (fileParent.equals(parent)) {
1✔
189
            return true;
1✔
190
        }
191

192
        return isFileInParent(fileParent, parent);
1✔
193
    }
194
}
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