Skip to content

Add auto-renaming of linked files on entry data change#13295

Merged
Siedlerchr merged 22 commits intoJabRef:mainfrom
paudelritij:fix-for-issue-11316
Aug 25, 2025
Merged

Add auto-renaming of linked files on entry data change#13295
Siedlerchr merged 22 commits intoJabRef:mainfrom
paudelritij:fix-for-issue-11316

Conversation

@paudelritij
Copy link
Copy Markdown
Contributor

Closes #11316

This PR introduces an option to automatically rename linked files when the associated entry data is modified. The feature is configurable in Preferences under Linked files -> Linked file name conventions, with a default setting of false. It also includes handling for entries with multiple attached files and adds relevant test cases.

Steps to test

  1. Open JabRef and go to Preferences > Linked files.
  2. Enable [ ] Auto rename files if entry changes.
  3. Create a new entry and attach a file.
  4. Modify any field in the entry.
  5. Check that the linked file's name updates to match the new citation key.
  6. Test with multiple files to ensure all are renamed.
image

Mandatory checks

  • I own the copyright of the code submitted and I license it under the MIT license
  • Change in CHANGELOG.md described in a way that is understandable for the average user (if change is visible to the user)
  • Tests created for changes (if applicable)
  • Manually tested changed features in running JabRef (always required)
  • Screenshots added in PR description (if change is visible to the user)
  • Checked developer's documentation: Is the information available and up to date? If not, I outlined it in this pull request.
  • Checked documentation: Is the information available and up to date? If not, I created an issue at https://github.com/JabRef/user-documentation/issues or, even better, I submitted a pull request to the documentation repository.

- Implemented a preference option under Linked files -> Linked file name conventions to enable auto-renaming of files when entry data changes (default: false).
- Added functionality to listen for entry change events and rename files if the preference is enabled and the file name matches the defined pattern.
- Ensured that no action is taken if the pattern is empty, as the file name would not match.
- Considered scenarios where an entry has multiple files attached and handled them appropriately.
- Added test cases to verify the new functionality.
Comment thread jablib/src/main/java/org/jabref/logic/FilePreferences.java
@paudelritij paudelritij marked this pull request as ready for review June 10, 2025 00:56
@koppor
Copy link
Copy Markdown
Member

koppor commented Jul 7, 2025

Ensure if the target file exists, do not use that name, use FileNameUniqueness.getNonOverWritingFileName(targetDirectory, targetFileName) to ensure that there is a unique other file name.

(Note to us: File should be kept even there are binary equal files. Otherwise, it gets complicated. E.g., if the same file is attached to another entry).

@paudelritij
Copy link
Copy Markdown
Contributor Author

Ensure if the target file exists, do not use that name, use FileNameUniqueness.getNonOverWritingFileName(targetDirectory, targetFileName) to ensure that there is a unique other file name.

(Note to us: File should be kept even there are binary equal files. Otherwise, it gets complicated. E.g., if the same file is attached to another entry).

I am trying implementing it in org.jabref.logic.externalfiles.LinkedFileHandler#renameToSuggestedName to put uniqueFileName. However, I'm encountering an issue with org.jabref.logic.search.indexing.DocumentReader#addMetaData, which is causing errors when reading timestamps. There may be creation of a loop where file changes name from e.g. abc.pdf to abc(1).pdf to abc.pdf again repeatedly. Any insights on how to resolve this would be greatly appreciated.

" ERROR: Could not read timestamp for /Users//Documents/JabRef/Gen28_ - Hands on Machine Learning with Scikit Learn, Keras, and TensorFlow.pdf: java.nio.file.NoSuchFileException: /Users//Documents/JabRef/Gen28_ - Hands on Machine Learning with Scikit Learn, Keras, and TensorFlow.pdf "

@koppor
Copy link
Copy Markdown
Member

koppor commented Jul 15, 2025

@LoayGhreeb Do you have some hints maybe?

@LoayGhreeb
Copy link
Copy Markdown
Member

I am trying implementing it in org.jabref.logic.externalfiles.LinkedFileHandler#renameToSuggestedName to put uniqueFileName. However, I'm encountering an issue with org.jabref.logic.search.indexing.DocumentReader#addMetaData, which is causing errors when reading timestamps. There may be creation of a loop where file changes name from e.g. abc.pdf to abc(1).pdf to abc.pdf again repeatedly. Any insights on how to resolve this would be greatly appreciated.

I don't think the problem is with the indexing itself. The NoSuchFileException means it's trying to access a file that doesn't exist, maybe it's still trying to use the old name, or the new one, but since there's a loop renaming the file back and forth, the file might not be available at the expected time during indexing.

I guess this loop could be happening if the same file is linked to two different entries. Could that be the case?

Please try to investigate further by adding some breakpoints to understand why, and where this loop is happening. Also, if possible, please push the commits that reproduce this issue, either here or in a new branch so we can take a proper look and help without guessing what's going on.

* of duplicate markers. For example, if "paper (1).pdf" is already linked to the entry and is the correct format,
* the method will return "paper (1).pdf" instead of generating "paper (2).pdf".
*/
public static String generateUniqueFileName(Path targetDirectory, String proposedName, String fileAlreadyInUse) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Method accepts null parameter 'fileAlreadyInUse' which violates modern Java practices of avoiding null parameters. Should use Optional instead.

@paudelritij
Copy link
Copy Markdown
Contributor Author

when using FileNameUniqueness.getNonOverWritingFileName(), a loop was occurring why?

  • Example: The original file name is paper_2082.pdf.
  • After renaming, the new name becomes paper1_2082.pdf. This triggers a file field change event.
  • On the next iteration, getSuggestedFileName() generates paper1_2082.pdf as the suggested name.
  • Since the file paper1_2082.pdf already exists (only we know that it is already linked to same entry), FileNameUniqueness.getNonOverWritingFileName() renames it to paper1_2082 (1).pdf.
  • This triggers another file field change event by generating file name again as paper1_2082.pdf (as it was in 1st place), and the process repeats, causing an infinite loop.

Solution Implemented

Case 1: File Exists but is Not Linked to the Entry: A new unique file name is suggested.
Case 2: File Exists and is Linked to the Entry: The file name change is discarded to prevent unnecessary renaming and event triggering.

Copy link
Copy Markdown
Member

@koppor koppor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think, the loop comes from org.jabref.logic.cleanup.RenamePdfCleanup#cleanup

you can add some LOGGER.trace calls and adjust the log level (locally) to trace as desribed at https://devdocs.jabref.org/code-howtos/logging.html

@paudelritij paudelritij requested a review from koppor August 4, 2025 00:15
Co-authored-by: Christoph <siedlerkiller@gmail.com>
@koppor
Copy link
Copy Markdown
Member

koppor commented Aug 23, 2025

I got following exceptions in the log if I had opened the PDF - therefore, I removed the exception at the log

image

@koppor
Copy link
Copy Markdown
Member

koppor commented Aug 23, 2025

I wired the listener to our CoarseGraindListener, because not at every single letter changes, the file should be renamed.

I also fixed the logger output - not each fired event should be logged as default. More reading on logging available at https://devdocs.jabref.org/code-howtos/logging.html.

Finally, I fixed the patterns for (2) suffixes etc. There should be tests, but I think I captered this wish at JabRef#719.

@koppor koppor added the status: awaiting-second-review For non-trivial changes label Aug 23, 2025
@trag-bot
Copy link
Copy Markdown

trag-bot Bot commented Aug 23, 2025

@trag-bot didn't find any issues in the code! ✅✨

@Siedlerchr Siedlerchr added this pull request to the merge queue Aug 25, 2025
Merged via the queue into JabRef:main with commit 32a3c50 Aug 25, 2025
1 check passed
@koppor koppor mentioned this pull request Aug 27, 2025
@koppor
Copy link
Copy Markdown
Member

koppor commented Aug 27, 2025

Introduces some test failres on Windows, but I don't know yet why. Just documenting --> #13766

@koppor koppor mentioned this pull request Aug 28, 2025
5 tasks
Siedlerchr added a commit that referenced this pull request Sep 8, 2025
* upstream/main: (32 commits)
  Fix path (#13769)
  Mode aware consistency check (#13584)
  Refine JBang check (#13765)
  Add Language Server to the UI and add the integrity/consistency check (#13697)
  Fix/remove comment code (#13763)
  New Crowdin updates (#13760)
  Bump org.openrewrite.rewrite from 7.14.0 to 7.14.1 (#13757)
  Bump com.autonomousapps:dependency-analysis-gradle-plugin (#13756)
  Bump dev.langchain4j:langchain4j-bom from 1.2.0 to 1.3.0 in /versions (#13755)
  Bump jablib/src/main/resources/csl-locales from `fa56de1` to `e29c453` (#13754)
  Bump com.autonomousapps:dependency-analysis-gradle-plugin (#13753)
  Bump org.mockito:mockito-core from 5.18.0 to 5.19.0 in /versions (#13752)
  Bump actions/upload-pages-artifact from 3 to 4 (#13751)
  Migrate fetchers to Search.g4 ANTLR parser. (#13691)
  [Junie]: fix: resolve IllegalArgumentException for non-absolute URIs (#13669)
  Add auto-renaming of linked files on entry data change (#13295)
  Walkthrough additions (#13745)
  Switch from zulu to corretto (#13749)
  New Crowdin updates (#13747)
  Fix copy to (#13741)
  ...
@bblhd bblhd mentioned this pull request Jan 1, 2026
6 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status: awaiting-second-review For non-trivial changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

If entry data is changed, file name should also be changed

4 participants