EN · DE · RU · FR · ES

#1878: CanonicalFileUtils.java

projectforge-common/src/main/java/org/projectforge/common/CanonicalFileUtils.java Utility class — org.projectforge.common package, projectforge-common/src/main/java/org/projectforge/common/CanonicalFileUtils.java 67 lines · 34 code · 27 comments · 6 blank
File path normalization utility that resolves symbolic links, eliminates .. and . path components, and normalizes path separators via File.getCanonicalPath(). Handles I/O errors gracefully by falling back to getAbsolutePath(). Provides both string-based and File-object-based overloads for path resolution. Used wherever ProjectForge needs to compare file paths or ensure consistent path representation.

Architecture

Imports

Core Operations

1. absolutePath(File file) → String

Returns the canonical path of a file as a String. If getCanonicalPath() throws IOException (e.g., the file doesn't exist and the filesystem can't resolve its canonical form), falls back to getAbsolutePath() and logs the error.

2. absolute(File file) → File

Same logic but returns a File object via getCanonicalFile() / getAbsoluteFile().

3. absolute(String path) → File

Convenience overload that wraps a string path in new File(path) and delegates to absolute(File).

Why Canonical Path?

Java's File.getCanonicalPath() provides several guarantees that getAbsolutePath() does not:

This is critical for security-sensitive operations where paths from user input must be compared against allowed paths — two different string representations might refer to the same file (e.g., /home/user/../user/file and /home/user/file).

Error Handling Strategy

The class uses a graceful degradation pattern: if canonical resolution fails (IOException), it falls back to absolute path and logs the error. This is important because getCanonicalPath() can throw IOException for reasons beyond the application's control (e.g., filesystem permissions, NFS mount issues, or the file not existing). The fallback ensures the application continues to function, albeit with a potentially non-normalized path.

Null Handling

All methods handle null input gracefully — returning null without throwing NullPointerException. This simplifies caller code by eliminating the need for null checks before calling the utility.

Usage Context in ProjectForge

CanonicalFileUtils is used in scenarios such as:

The log message "Internal error while trying to get canonical path" is slightly misleading — an IOException from getCanonicalPath() is not necessarily an "internal error" but often an environmental condition (missing file, permission denied). The fallback to getAbsolutePath() silently accepts a potentially un-normalized path.
The class is intentionally minimal (3 methods, ~30 lines of logic). It extracts a very specific concern — path normalization with graceful fallback — from the broader FileHelper class. This follows the Single Responsibility Principle, keeping utilities focused and testable.

Git History

868d6abb7 2025 -> 2026
63081666f Source file headers: 2024-> 2025.
b6092df09 Copyright 2023 -> 2024
ab45d51fa Copyright 2001-2022 -> 2001-2023.
5f7ef41b8 Copyright 2021 -> 2022
ceb63e8a1 Source code header: (C) 2001-2021.
7c79f1922 Copyright of source header -> 2020.
bd25a85fb WIP: Setup wizard (Swing and Lanterna)