From 3c491146db7d4c437a07dc0ce5e2569edf8a252b Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Mon, 10 Oct 2022 21:46:56 +0200 Subject: [PATCH] Add ADR-0026 on using Swing's FileChooser (#9235) Also refines code explanations on BibDatabaseContext Co-authored-by: Christoph Co-authored-by: Carl Christian Snethlage <50491877+calixtus@users.noreply.github.com> Co-authored-by: Houssem Nasri Co-authored-by: Christoph Co-authored-by: Carl Christian Snethlage <50491877+calixtus@users.noreply.github.com> Co-authored-by: Houssem Nasri --- ...-chooser-to-determine-default-directory.md | 62 +++++++++++++++++++ .../org/jabref/gui/desktop/JabRefDesktop.java | 12 ++-- .../model/database/BibDatabaseContext.java | 6 +- 3 files changed, 73 insertions(+), 7 deletions(-) create mode 100644 docs/decisions/0026-use-swings-file-chooser-to-determine-default-directory.md diff --git a/docs/decisions/0026-use-swings-file-chooser-to-determine-default-directory.md b/docs/decisions/0026-use-swings-file-chooser-to-determine-default-directory.md new file mode 100644 index 00000000000..127067b12f8 --- /dev/null +++ b/docs/decisions/0026-use-swings-file-chooser-to-determine-default-directory.md @@ -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 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\\AppData\\` 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.} diff --git a/src/main/java/org/jabref/gui/desktop/JabRefDesktop.java b/src/main/java/org/jabref/gui/desktop/JabRefDesktop.java index b74fea558d4..cb43b1284ab 100644 --- a/src/main/java/org/jabref/gui/desktop/JabRefDesktop.java +++ b/src/main/java/org/jabref/gui/desktop/JabRefDesktop.java @@ -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(); } diff --git a/src/main/java/org/jabref/model/database/BibDatabaseContext.java b/src/main/java/org/jabref/model/database/BibDatabaseContext.java index 45563f6328a..4331f66d90b 100644 --- a/src/main/java/org/jabref/model/database/BibDatabaseContext.java +++ b/src/main/java/org/jabref/model/database/BibDatabaseContext.java @@ -158,6 +158,8 @@ public List 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(); @@ -181,7 +183,9 @@ public List getFileDirectories(FilePreferences preferences) { * @return the path - or an empty optional, if none of the directories exists */ public Optional getFirstExistingFileDir(FilePreferences preferences) { - return getFileDirectories(preferences).stream().filter(Files::exists).findFirst(); + return getFileDirectories(preferences).stream() + .filter(Files::exists) + .findFirst(); } private Path getFileDirectoryPath(String directoryName) {