@@ -144,7 +144,7 @@ public static Path addExtension(Path path, String extension) {
144144 /**
145145 * Looks for the unique directory, if any, different to the provided paths
146146 *
147- * @param paths List of paths as Strings
147+ * @param paths List of paths as Strings
148148 * @param comparePath The to be tested path
149149 */
150150 public static Optional <String > getUniquePathDirectory (List <String > paths , Path comparePath ) {
@@ -153,15 +153,15 @@ public static Optional<String> getUniquePathDirectory(List<String> paths, Path c
153153 List <String > uniquePathParts = uniquePathSubstrings (paths );
154154 return uniquePathParts .stream ()
155155 .filter (part -> comparePath .toString ().contains (part )
156- && !part .equals (fileName ) && part .contains (File .separator ))
156+ && !part .equals (fileName ) && part .contains (File .separator ))
157157 .findFirst ()
158158 .map (part -> part .substring (0 , part .lastIndexOf (File .separator )));
159159 }
160160
161161 /**
162162 * Looks for the shortest unique path of the in a list of paths
163163 *
164- * @param paths List of paths as Strings
164+ * @param paths List of paths as Strings
165165 * @param comparePath The to be shortened path
166166 */
167167 public static Optional <String > getUniquePathFragment (List <String > paths , Path comparePath ) {
@@ -219,7 +219,7 @@ public static List<String> uniquePathSubstrings(List<String> paths) {
219219 * @param pathToSourceFile Path Source file
220220 * @param pathToDestinationFile Path Destination file
221221 * @param replaceExisting boolean Determines whether the copy goes on even if the file exists.
222- * @return boolean Whether the copy succeeded, or was stopped due to the file already existing.
222+ * @return boolean Whether the copy succeeded or was stopped due to the file already existing.
223223 */
224224 public static boolean copyFile (Path pathToSourceFile , Path pathToDestinationFile , boolean replaceExisting ) {
225225 // Check if the file already exists.
@@ -255,15 +255,40 @@ public static Path relativize(Path file, List<Path> directories) {
255255 if (!file .isAbsolute ()) {
256256 return file ;
257257 }
258+ Optional <Path > realFileOpt = toRealPath (file );
258259
259260 for (Path directory : directories ) {
260261 if (file .startsWith (directory )) {
261262 return directory .relativize (file );
262263 }
264+
265+ if (realFileOpt .isPresent ()) {
266+ Optional <Path > realDirOpt = toRealPath (directory );
267+ if (realDirOpt .isPresent ()) {
268+ Path realFile = realFileOpt .get ();
269+ Path realDir = realDirOpt .get ();
270+ if (realFile .startsWith (realDir )) {
271+ return realDir .relativize (realFile );
272+ }
273+ }
274+ }
263275 }
264276 return file ;
265277 }
266278
279+ private static Optional <Path > toRealPath (Path path ) {
280+ if (Files .exists (path )) {
281+ try {
282+ return Optional .of (path .toRealPath ());
283+ } catch (IOException e ) {
284+ LOGGER .warn ("Could not resolve real path for {}" , path , e );
285+ return Optional .empty ();
286+ }
287+ } else {
288+ return Optional .of (path .toAbsolutePath ());
289+ }
290+ }
291+
267292 /**
268293 * Converts an absolute file to a relative one, if possible. Returns the parameter file itself if no shortening is
269294 * possible.
@@ -342,8 +367,8 @@ public static String createFileNameFromPattern(BibDatabase database, BibEntry en
342367 /**
343368 * Determines directory name provided by an entry in a database
344369 *
345- * @param database the database, where the entry is located
346- * @param entry the entry to which the directory should be linked to
370+ * @param database the database, where the entry is located
371+ * @param entry the entry to which the directory should be linked to
347372 * @param directoryNamePattern the dirname pattern
348373 * @return a suggested dirName
349374 */
@@ -370,9 +395,9 @@ public static String createDirNameFromPattern(BibDatabase database, BibEntry ent
370395 public static Optional <Path > findSingleFileRecursively (String filename , Path rootDirectory ) {
371396 try (Stream <Path > pathStream = Files .walk (rootDirectory )) {
372397 return pathStream
373- .filter (Files ::isRegularFile )
374- .filter (f -> f .getFileName ().toString ().equals (filename ))
375- .findFirst ();
398+ .filter (Files ::isRegularFile )
399+ .filter (f -> f .getFileName ().toString ().equals (filename ))
400+ .findFirst ();
376401 } catch (UncheckedIOException | IOException ex ) {
377402 LOGGER .error ("Error trying to locate the file {} inside the directory {}" , filename , rootDirectory , ex );
378403 }
@@ -410,9 +435,8 @@ public static Optional<Path> find(String fileName, List<Path> directories) {
410435 /**
411436 * Converts a relative filename to an absolute one, if necessary.
412437 *
413- * @param fileName the filename (e.g., a .pdf file), may contain path separators
438+ * @param fileName the filename (e.g., a .pdf file), may contain path separators
414439 * @param directory the directory which should be search starting point
415- *
416440 * @return an empty optional if the file does not exist, otherwise, the absolute path
417441 */
418442 public static Optional <Path > find (String fileName , Path directory ) {
@@ -504,10 +528,9 @@ public static Path getInitialDirectory(BibDatabaseContext databaseContext, Path
504528 /**
505529 * Detect illegal characters in given filename.
506530 *
507- * @see org.jabref.logic.util.io.FileNameCleaner#cleanFileName
508- *
509531 * @param fileName the fileName to detect
510532 * @return Boolean whether there is an illegal name.
533+ * @see org.jabref.logic.util.io.FileNameCleaner#cleanFileName
511534 */
512535 public static boolean detectBadFileName (String fileName ) {
513536 // fileName could be a path, we want to check the fileName only (and don't care about the path)
@@ -579,9 +602,9 @@ public static String shortenFileName(String fileName, Integer maxLength) {
579602 numCharsAfterEllipsis = Math .min (numCharsAfterEllipsis , name .length () - numCharsBeforeEllipsis );
580603
581604 return name .substring (0 , numCharsBeforeEllipsis ) +
582- ELLIPSIS +
583- name .substring (name .length () - numCharsAfterEllipsis ) +
584- extension ;
605+ ELLIPSIS +
606+ name .substring (name .length () - numCharsAfterEllipsis ) +
607+ extension ;
585608 }
586609
587610 public static boolean isCharLegal (char c ) {
0 commit comments