-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
[WIP] This relativizes the PDF's filepaths after importing through "Find Unlinked Files" #10582
Conversation
@@ -116,7 +116,7 @@ protected List<ImportFilesResultItemViewModel> call() { | |||
|
|||
try { | |||
if (FileUtil.isPDFFile(file)) { | |||
var pdfImporterResult = contentImporter.importPDFContent(file); | |||
var pdfImporterResult = contentImporter.importPDFContent(file, bibDatabaseContext.getMetaData()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better use this directory: Optional firstExistingFileDir = bibDatabaseContext.getFirstExistingFileDir(filePreferences);
This will make sure that you always get the "right" file directory (global or from metadata)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. I've included 2 more commits in this PR. The first commit was about a slight change that made checkstyle task fail: space character was missing after if
.
Your suggestion to use the "first existing file directory" does indeed seem like a better approach. Now, the path is relativized even if the "global file directory" property is missing. That would nicely go along with the approach that "relative paths are better", which was mentioned here.
@@ -116,7 +116,8 @@ protected List<ImportFilesResultItemViewModel> call() { | |||
|
|||
try { | |||
if (FileUtil.isPDFFile(file)) { | |||
var pdfImporterResult = contentImporter.importPDFContent(file, bibDatabaseContext.getMetaData()); | |||
Optional<Path> globalFileDir = bibDatabaseContext.getFirstExistingFileDir(preferencesService.getFilePreferences()); | |||
var pdfImporterResult = contentImporter.importPDFContent(file, globalFileDir); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Optionals should not be passed as parameter, they should only be used for return types. Better
Path workingDirectory = databaseContext.getFirstExistingFileDir(filePreferences)
.orElse(filePreferences.getWorkingDirectory());
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I agree. This feels like a code smell. I've pushed 2 new commits: the 1st removes the Optional
and the 2nd one is about renaming the Path
variable.
Looks good so far |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add (at least) one test case.
You can find one at the description "How to reproduce" at JabRef#549.
I've committed a new test case. I also wanted to add a more exhaustive test by testing not only the low-level In
But I'd end up with I'd like to continue to work on the test case in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor issues
// Expecting relative path | ||
expected.setField(StandardField.FILE, ":minimal.pdf:PDF"); | ||
|
||
assertEquals(Collections.singletonList(expected), result); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assertEquals(Collections.singletonList(expected), result); | |
assertEquals(List.of(expected), result); |
BibEntry expected = new BibEntry(StandardEntryType.InProceedings); | ||
expected.setField(StandardField.AUTHOR, "1 "); | ||
expected.setField(StandardField.TITLE, "Hello World"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Try to use the JabRef style:
BibEntry expected = new BibEntry(StandardEntryType.InProceedings); | |
expected.setField(StandardField.AUTHOR, "1 "); | |
expected.setField(StandardField.TITLE, "Hello World"); | |
BibEntry expected = new BibEntry(StandardEntryType.InProceedings) | |
.withField(StandardField.AUTHOR, "1 ") | |
.withField(StandardField.TITLE, "Hello World"); |
(also rewrite next line with the .with...
pattern
if (workingDir != null) { | ||
Path relativizedFilePath = workingDir.relativize(filePath); | ||
entry.addFile(new LinkedFile("", relativizedFilePath, StandardFileType.PDF.getName())); | ||
} else { | ||
entry.addFile(new LinkedFile("", filePath, StandardFileType.PDF.getName())); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add JavaDoc explaning the param workingDir
and state when this can be null.
I was about to write that you should switch the if branches to avoid negation (and use workingDir == null), but this one is IMHO more readable
if (workingDir != null) { | |
Path relativizedFilePath = workingDir.relativize(filePath); | |
entry.addFile(new LinkedFile("", relativizedFilePath, StandardFileType.PDF.getName())); | |
} else { | |
entry.addFile(new LinkedFile("", filePath, StandardFileType.PDF.getName())); | |
} | |
if (workingDir != null) { | |
filePath = workingDir.relativize(filePath); | |
} | |
entry.addFile(new LinkedFile("", filePath, StandardFileType.PDF.getName())); |
Avoid the background task in tests. Isn't there another method you can check directly? You would run a UI test then. Search for You changed logic, thus you should have a test in |
I was talking here about a "high-level" method - at the top of the method chain. In this draft PR, I've so far modified 3 main classes: I tested the I can't figure out how to test it, though. It's a Anyway, please see new commits. I've implemented your suggestions and wrote a bit of JavaDoc. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the late reply. I just saw the PR again.
The implementation is not working for all cases. I provided a sketch of the required implementation. Should be 10 lines of code.
Would be nice if you could try it. If not, we can do.
Path workingDir = bibDatabaseContext.getFirstExistingFileDir(filePreferences) | ||
.orElse(filePreferences.getWorkingDirectory()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
JabRef's logic of storing files is more complicated.
JabRef searchers in EACH directory, not in ONE.
See org.jabref.logic.util.io.FileUtil#getListOfLinkedFiles.
if (workingDir != null) { | ||
filePath = workingDir.relativize(filePath); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Call org.jabref.logic.util.io.FileUtil#relativize
here.
The required directories
are provided by databaseContext.getFileDirectories(filePreferences)
@IceMajor2 I saw no activity the last weeks, thus I am closing. In case you are going to resume work, feel free to reopen or file a new PR. |
Fixes JabRef#549
I'll start explaining the changes I've made from the top of the method chain.
ImportHandler
It is the place where the logic of importing a PDF file starts being executed.
At line 119, there's an
importPDFContent
(ofExternalFilesContentImporter
class) method executed, which takes in a filepath as a parameter. In order to access the "General file directory" library property, I've modified this method (see 2nd point).ExternalFilesContentImporter
As mentioned,
importPDFContent
method gets a new parameter: an instance ofMetaData
. The "General file directory" path is stored there.PdfMergeMetadataImporter
Finally, the actual logic is being executed here. The class is an implementation of an abstract class
Importer
. Among others, it overridesimportDatabase(Path)
method. Previous step's methodimportPDFContent
callsPdfMergeMetadataImporter
'simportDatabase
method, where the filepath can be manipulated. Because of extending that method, I can provideimportDatabase
withMetaData
object. At last - just at the end of the method - I've included some basic logic that:Please, do provide me with feedback on the above implementation. I'm particularly interested whether the extensions with
MetaData
instance is an okay decision. I'm also wondering if the "General file directory" property may be accessed in some other way.Note that I've not included any changes to the
CHANGELOG.md
as this is still a work-in-progress pull request and it does not yet solve the issue of other than PDF files.Mandatory checks
CHANGELOG.md
described in a way that is understandable for the average user (if applicable)