Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ADR-0026 on using Swing's FileChooser #9235

Merged
merged 1 commit into from
Oct 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
---
nav_order: 26
parent: Decision Records
---
# Use Swing's FileChooser to Determine Default Directory

## Context and Problem Statement

JabRef needs to propose a file directory to a user for storing files.
How to determine the "best" directory native for the OS the user runs.

## Decision Drivers

* Low maintenance effort
* Follow JabRef's architectural guidelines
* No additional dependencies

## Considered Options

* Use Swing's FileChooser to Determine Default Directory
* Use `user.home`
* [AppDirs](https://github.com/harawata/appdirs)

## Decision Outcome

Chosen option: "Use Swing's FileChooser to Determine Default Directory", because
comes out best (see below).

## Pros and Cons of the Options

### Use Swing's FileChooser to Determine Default Directory

Swing's FileChooser implemented a very decent directory determination algorithm.
It thereby uses `sun.awt.shell.ShellFolder`.

* Good, because provides best results on most platforms.
* Bad, because introduces a dependency on Swing and thereby contradicts the second decision driver.
* Bad, because GraalVM's support Swing is experimental

### Use `user.home`

There is `System.getProperty("user.home");`.

* Bad, because "The concept of a HOME directory seems to be a bit vague when it comes to Windows". See <https://stackoverflow.com/a/586917/873282> for details.
* Bad, because it does not include `Documents`:
As of 2022, `System.getProperty("user.home")` returns `c:\Users\USERNAME` on Windows 10, whereas
`FileSystemView` returns `C:\Users\USERNAME\Documents`, which is the "better" directory

### AppDirs

> AppDirs is a small java library which provides a path to the platform dependent special folder/directory.

* Good, because already used in JabRef
* Bad, because does not use "MyDocuments" on Windows, but rather `C:\Users\<Account>\AppData\<AppAuthor>\<AppName>` as basis

## More Information

{You might want to provide additional evidence/confidence for the decision outcome here and/or
document the team agreement on the decision and/or
define when this decision when and how the decision should be realized and if/when it should be re-visited and/or
how the decision is validated.
Links to other decisions and resources might here appear as well.}
12 changes: 6 additions & 6 deletions src/main/java/org/jabref/gui/desktop/JabRefDesktop.java
Original file line number Diff line number Diff line change
Expand Up @@ -298,12 +298,12 @@ public static void openConsole(File file, PreferencesService preferencesService,
* @return The path to the directory
*/
public static String getDefaultFileChooserDirectory() {
// Property "user.home" might be "difficult" on Windows
// See https://stackoverflow.com/a/586917/873282 for a longer discussion
// The proposed solution is to use Swing's FileSystemView
// See https://stackoverflow.com/a/32914568/873282
// As of 2022, System.getProperty("user.home") returns c:\Users\USERNAME on Windows 10, whereas
// the FileSystemView returns C:\Users\USERNAME\Documents, which is the "better" directory
// Implementation: ADR-0026

// We do not return a subdirectory "JabRef", because
// - the directory might not exist at this point of the method
// - we might not have the rights to create a directory
// - getters should not have any side effect
return FileSystemView.getFileSystemView().getDefaultDirectory().getPath();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,8 @@ public List<Path> getFileDirectories(FilePreferences preferences) {
.ifPresent(metaDataDirectory -> fileDirs.add(getFileDirectoryPath(metaDataDirectory)));

// 3. BIB file directory or Main file directory
// fileDirs.isEmpty in the case, 1) no user-specific file directory and 2) no general file directory is set
// (in the metadata of the bib file)
if (fileDirs.isEmpty() && preferences.shouldStoreFilesRelativeToBibFile()) {
getDatabasePath().ifPresent(dbPath -> {
Path parentPath = dbPath.getParent();
Expand All @@ -181,7 +183,9 @@ public List<Path> getFileDirectories(FilePreferences preferences) {
* @return the path - or an empty optional, if none of the directories exists
*/
public Optional<Path> getFirstExistingFileDir(FilePreferences preferences) {
return getFileDirectories(preferences).stream().filter(Files::exists).findFirst();
return getFileDirectories(preferences).stream()
.filter(Files::exists)
.findFirst();
}

private Path getFileDirectoryPath(String directoryName) {
Expand Down