Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
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
2 changes: 1 addition & 1 deletion .github/workflows/sbom-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ jobs:
Generated via Gradle task `cyclonedxBom` using the org.cyclonedx.bom plugin configured in the build.
branch: chore/update-sbom
delete-branch: true
labels: "dev: dependencies""
labels: "dev: dependencies"
add-paths: |
bom.json
bom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public void browse() {
FileDialogConfiguration fileDialogConfiguration = new FileDialogConfiguration.Builder()
.addExtensionFilter(StandardFileType.AUX)
.withDefaultExtension(StandardFileType.AUX)
.withInitialDirectory(preferences.getFilePreferences().getWorkingDirectory()).build();
.withInitialDirectory(auxFileProperty.get() == null ? preferences.getFilePreferences().getWorkingDirectory().toString(): auxFileProperty.get()).build();
dialogService.showFileOpenDialog(fileDialogConfiguration).ifPresent(file -> auxFileProperty.setValue(file.toAbsolutePath().toString()));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ public void setLatexDirectory() {
.withInitialDirectory(directory.get()).build();

dialogService.showDirectorySelectionDialog(directoryDialogConfiguration).ifPresent(selectedDirectory ->
currentDatabaseContext.getMetaData().setLatexFileDirectory(preferences.getFilePreferences().getUserAndHost(), selectedDirectory.toAbsolutePath()));
currentDatabaseContext.getMetaData().setLatexFileDirectory(preferences.getFilePreferences().getUserAndHost(), selectedDirectory.toString()));

checkAndUpdateDirectory();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,8 +231,8 @@ private void setupValidation() {
return false;
}
return FileUtil.getFileExtension(input)
.map("aux"::equalsIgnoreCase)
.orElse(false);
.map("aux"::equalsIgnoreCase)
.orElse(false);
}
},
ValidationMessage.error(Localization.lang("Please provide a valid aux file.")));
Expand Down Expand Up @@ -485,9 +485,10 @@ public void texGroupBrowse() {
FileDialogConfiguration fileDialogConfiguration = new FileDialogConfiguration.Builder()
.addExtensionFilter(StandardFileType.AUX)
.withDefaultExtension(StandardFileType.AUX)
.withInitialDirectory(currentDatabase.getMetaData()
.getLatexFileDirectory(preferences.getFilePreferences().getUserAndHost())
.orElse(FileUtil.getInitialDirectory(currentDatabase, preferences.getFilePreferences().getWorkingDirectory()))).build();
.withInitialDirectory(texGroupFilePathProperty.getValue().isBlank() ?
currentDatabase.getMetaData()
.getLatexFileDirectory(preferences.getFilePreferences().getUserAndHost())
.orElse(FileUtil.getInitialDirectory(currentDatabase, preferences.getFilePreferences().getWorkingDirectory())).toString() : texGroupFilePathProperty.get()).build();
dialogService.showFileOpenDialog(fileDialogConfiguration)
.ifPresent(file -> texGroupFilePathProperty.setValue(
FileUtil.relativize(file.toAbsolutePath(), getFileDirectoriesAsPaths()).toString()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ public void storeSettings() {
if (latexFileDirectory.isEmpty()) {
newMetaData.clearLatexFileDirectory(preferences.getFilePreferences().getUserAndHost());
} else if (laTexFileDirectoryStatus().isValid()) {
newMetaData.setLatexFileDirectory(preferences.getFilePreferences().getUserAndHost(), Path.of(latexFileDirectory));
newMetaData.setLatexFileDirectory(preferences.getFilePreferences().getUserAndHost(), latexFileDirectory);
}

databaseContext.setMetaData(newMetaData);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
import org.jabref.model.metadata.ContentSelectors;
import org.jabref.model.metadata.MetaData;
import org.jabref.model.metadata.SaveOrder;
import org.jabref.model.metadata.UserHostInfo;
import org.jabref.model.strings.StringUtil;
import org.jabref.model.util.FileUpdateMonitor;

Expand Down Expand Up @@ -131,20 +130,7 @@ public MetaData parse(MetaData metaData, Map<String, String> data, Character key
} else if (entry.getKey().startsWith(MetaData.FILE_DIRECTORY_LATEX)) {
// The user-host string starts directly after FILE_DIRECTORY_LATEX + '-'
String userHostString = entry.getKey().substring(MetaData.FILE_DIRECTORY_LATEX.length() + 1);
Path path = Path.of(parseDirectory(entry.getValue())).normalize();

UserHostInfo userHostInfo = UserHostInfo.parse(userHostString);
String currentHost = org.jabref.logic.os.OS.getHostName();

if (!userHostInfo.host().isEmpty() && !userHostInfo.host().equals(currentHost)) {
// If the host doesn't match the current host, we need to use the current user-host
// This w that the LaTeX file directory is set for the current user on the current host
LOGGER.warn("Host mismatch for LaTeX file directory: {} vs current host {}", userHostInfo.host(), currentHost);
// We don't have access to the current user-host here, so we'll just store the path
// The correct user-host will be used when the path is retrieved via the GUI
}

metaData.setLatexFileDirectory(userHostString, path);
metaData.setLatexFileDirectory(userHostString, parseDirectory(entry.getValue()));
} else if (MetaData.SAVE_ACTIONS.equals(entry.getKey())) {
metaData.setSaveActions(fieldFormatterCleanupsParse(values));
} else if (MetaData.DATABASE_TYPE.equals(entry.getKey())) {
Expand Down
37 changes: 25 additions & 12 deletions jablib/src/main/java/org/jabref/logic/util/io/FileUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.jabref.model.entry.LinkedFile;
import org.jabref.model.entry.field.StandardField;

import org.jspecify.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -146,9 +147,9 @@ public static Path addExtension(Path path, String extension) {
}

/// Looks for the shortest unique path of the parent directory in the list of paths
///
/// @param paths List of paths as Strings
/// @param comparePath The to be tested path
///
/// @return Optional.empty() if the paths are disjoint
public static Optional<String> getUniquePathDirectory(List<String> paths, Path comparePath) {
// Difference to getUniquePathFragment: We want the parent directory, so we cut off the last path fragment
Expand All @@ -161,7 +162,6 @@ public static Optional<String> getUniquePathDirectory(List<String> paths, Path c
///
/// @param paths List of paths as Strings
/// @param comparePath The to be shortened path
///
/// @return Shortest unique path fragment (if exists) - Optional.empty() if the paths are disjoint
public static Optional<String> getUniquePathFragment(List<String> paths, Path comparePath) {
return uniquePathSubstrings(paths).stream()
Expand Down Expand Up @@ -251,23 +251,35 @@ public static boolean copyFile(Path pathToSourceFile, Path pathToDestinationFile
* @param directories directories to check
*/
public static Path relativize(Path file, List<Path> directories) {
return relativize(file, directories, null);
}

/**
*
* @param file The file to relativize, can be already relative or absolute
* @param directories File directories to resolve against
* @param baseDirForRelative Base directory for resolve a relative file path against first (e.g. "." )
* @return Relative path to the file, or the original file if it is already relative or thw
*/
public static Path relativize(Path file, List<Path> directories, @Nullable Path baseDirForRelative) {
if (!file.isAbsolute()) {
return file;
}
Optional<Path> realFileOpt = toRealPath(file);

for (Path directory : directories) {
if (file.startsWith(directory)) {
return directory.relativize(file);
}

if (realFileOpt.isPresent()) {
Optional<Path> realDirOpt = toRealPath(directory);
if (realDirOpt.isPresent()) {
Path realFile = realFileOpt.get();
Path realDir = realDirOpt.get();
if (realFile.startsWith(realDir)) {
return realDir.relativize(realFile);
if (baseDirForRelative != null) {
Optional<Path> realFileOpt = toRealPath(file);
if (realFileOpt.isPresent()) {
Optional<Path> realDirOpt = toRealPath(directory);
if (realDirOpt.isPresent()) {
Path realFile = realFileOpt.get();
Path realDir = realDirOpt.get();
if (realFile.startsWith(realDir)) {
return realDir.relativize(realFile);
}
}
}
}
Expand Down Expand Up @@ -644,7 +656,8 @@ public static Path convertCygwinPathToWindows(String filePath) {
}

/// Builds a Windows-style path from a Cygwin-style path using a known prefix index.
/// @param path the input file path
///
/// @param path the input file path
/// @param letterIndex the index driver letter, zero-based indexing
/// @return a windows-style path
private static Path buildWindowsPathWithDriveLetterIndex(String path, int letterIndex) {
Expand Down
27 changes: 4 additions & 23 deletions jablib/src/main/java/org/jabref/model/metadata/MetaData.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public class MetaData {
private final EventBus eventBus = new EventBus();
private final Map<EntryType, String> citeKeyPatterns = new HashMap<>(); // <BibType, Pattern>
private final Map<String, String> userFileDirectory = new HashMap<>(); // <User, FilePath>
private final Map<String, Path> latexFileDirectory = new HashMap<>(); // <User-Host, FilePath>
private final Map<String, String> latexFileDirectory = new HashMap<>(); // <User-Host, FilePath>

private final ObjectProperty<GroupTreeNode> groupsRoot = new SimpleObjectProperty<>(null);
private final OptionalBinding<GroupTreeNode> groupsRootBinding = new OptionalWrapper<>(groupsRoot);
Expand Down Expand Up @@ -261,29 +261,10 @@ public void clearUserFileDirectory(String user) {
}

public Optional<Path> getLatexFileDirectory(String userHostString) {
// First try to get the LaTeX file directory for the exact user-host
Path path = latexFileDirectory.get(userHostString);
if (path != null) {
return Optional.of(path);
}

// If not found, try to find a LaTeX file directory for the same host
// This handles the case where a file is moved between hosts with different users
UserHostInfo requestedUserHost = UserHostInfo.parse(userHostString);
if (!requestedUserHost.host().isEmpty()) {
for (Map.Entry<String, Path> entry : latexFileDirectory.entrySet()) {
UserHostInfo entryUserHost = UserHostInfo.parse(entry.getKey());
if (entryUserHost.hasSameHost(requestedUserHost)) {
// Found a LaTeX file directory for the same host, return it
return Optional.of(entry.getValue());
}
}
}

return Optional.empty();
return Optional.ofNullable(latexFileDirectory.get(userHostString)).map(Path::of);
}

public void setLatexFileDirectory(@NonNull String userHostString, @NonNull Path path) {
public void setLatexFileDirectory(@NonNull String userHostString, @NonNull String path) {
latexFileDirectory.put(userHostString, path);
postChange();
}
Expand Down Expand Up @@ -380,7 +361,7 @@ public Map<String, String> getUserFileDirectories() {
return Collections.unmodifiableMap(userFileDirectory);
}

public Map<String, Path> getLatexFileDirectories() {
public Map<String, String> getLatexFileDirectories() {
return Collections.unmodifiableMap(latexFileDirectory);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -810,7 +810,7 @@ void writeProtectedFlag() throws IOException {
void writeFileDirectories() throws IOException {
metaData.setLibrarySpecificFileDirectory("\\Literature\\");
metaData.setUserFileDirectory("defaultOwner-user", "D:\\Documents");
metaData.setLatexFileDirectory("defaultOwner-user", Path.of("D:\\Latex"));
metaData.setLatexFileDirectory("defaultOwner-user", "D:\\Latex");

databaseWriter.savePartOfDatabase(bibtexContext, List.of());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ void containsReturnsTrueForEntryNotInAux() throws IOException, URISyntaxExceptio
void getFilePathReturnsRelativePath() throws URISyntaxException {
Path auxFile = Path.of(TexGroupTest.class.getResource("paper.aux").toURI());
String user = "Darwin";
metaData.setLatexFileDirectory(user, auxFile.getParent());
metaData.setLatexFileDirectory(user, auxFile.getParent().toString());
TexGroup group = new TexGroup("paper", GroupHierarchyType.INDEPENDENT, auxFile, new DefaultAuxParser(new BibDatabase()), new DummyFileUpdateMonitor(), metaData, user);

assertEquals("paper.aux", group.getFilePath().toString());
Expand Down
65 changes: 1 addition & 64 deletions jablib/src/test/java/org/jabref/model/metadata/MetaDataTest.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
package org.jabref.model.metadata;

import java.nio.file.Path;
import java.util.Optional;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

class MetaDataTest {

Expand All @@ -22,70 +20,9 @@ void setUp() {
void emptyGroupsIfNotSet() {
assertEquals(Optional.empty(), metaData.getGroups());
}

@Test
void getLatexFileDirectoryReturnsEmptyWhenNotSet() {
assertEquals(Optional.empty(), metaData.getLatexFileDirectory("user-host"));
}

@Test
void getLatexFileDirectoryReturnsPathForExactUserHostMatch() {
String userHost = "user-host";
Path expectedPath = Path.of("/path/to/latex");
metaData.setLatexFileDirectory(userHost, expectedPath);

Optional<Path> result = metaData.getLatexFileDirectory(userHost);

assertTrue(result.isPresent());
assertEquals(expectedPath, result.get());
}

@Test
void getLatexFileDirectoryReturnsPathForSameHostButDifferentUser() {
String originalUserHost = "user1-host";
String newUserHost = "user2-host";
Path expectedPath = Path.of("/path/to/latex");
metaData.setLatexFileDirectory(originalUserHost, expectedPath);

Optional<Path> result = metaData.getLatexFileDirectory(newUserHost);

assertTrue(result.isPresent());
assertEquals(expectedPath, result.get());
}

@Test
void getLatexFileDirectoryReturnsEmptyForDifferentHost() {
String userHost1 = "user-host1";
Path path1 = Path.of("/path/for/host1");
metaData.setLatexFileDirectory(userHost1, path1);

Optional<Path> result = metaData.getLatexFileDirectory("user-host2");

assertEquals(Optional.empty(), result);
}

@Test
void getLatexFileDirectoryHandlesMultipleEntriesCorrectly() {
String userHost1 = "user1-host1";
String userHost2 = "user2-host2";
String userHost3 = "user3-host1";

Path path1 = Path.of("/path/for/host1/user1");
Path path2 = Path.of("/path/for/host2");
Path path3 = Path.of("/path/for/host1/user3");

metaData.setLatexFileDirectory(userHost1, path1);
metaData.setLatexFileDirectory(userHost2, path2);
metaData.setLatexFileDirectory(userHost3, path3);

assertEquals(path1, metaData.getLatexFileDirectory(userHost1).get());
assertEquals(path2, metaData.getLatexFileDirectory(userHost2).get());
assertEquals(path3, metaData.getLatexFileDirectory(userHost3).get());

String newUserOnHost1 = "newuser-host1";
Optional<Path> resultForNewUser = metaData.getLatexFileDirectory(newUserOnHost1);
assertTrue(resultForNewUser.isPresent());

assertEquals(Optional.empty(), metaData.getLatexFileDirectory("user-differenthost"));
}
}
Loading