-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Refactor export code to fix #3576 #3578
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
Conversation
| * TemplateExporter for exporting in MODS XML format. | ||
| */ | ||
| class ModsExportFormat extends ExportFormat { | ||
| class ModsExporter extends TemplateExporter { |
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.
I don't know by what you define a TemplateExporter: If it's the one where you can define a html/layout file, then this is not one.
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.
I now made Exporter an abstract class with the basic fields. Not sure why these special exporter derived from ExportFormat.
| * TemplateExporter for exporting in MSBIB XML format. | ||
| */ | ||
| class MSBibExportFormat extends ExportFormat { | ||
| class MSBibExporter extends TemplateExporter { |
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.
Not a Template exporter. You can't create a layout file for it
| private static void storeOpenDocumentSpreadsheetFile(Path file, InputStream source) throws IOException { | ||
|
|
||
| try (ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(file)))) { | ||
| try (ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(file.toFile())))) { |
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.
The last FileOutputStream could be replaced by the Files.newFileOutputStream which directly accepts a path
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.
Fixed.
| private static void storeOpenOfficeFile(File file, InputStream source) throws Exception { | ||
| try (ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(file)))) { | ||
| private static void storeOpenOfficeFile(Path file, InputStream source) throws Exception { | ||
| try (ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(file.toFile())))) { |
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.
see as above
CHANGELOG.md
Outdated
| ### Changed | ||
|
|
||
| ### Fixed | ||
| - We fixed the name of an exported file. |
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.
Improve changelog entry
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.
Fixed
| return importers.stream().filter(importer -> importer.getDescription().equals(extensionFilter.getDescription())).findFirst(); | ||
| } | ||
|
|
||
| public static Optional<Exporter> getExporter(FileChooser.ExtensionFilter extensionFilter, Collection<Exporter> exporters) { |
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.
Either you move the whole class to a new "meta" package, or you move the getExporter method to another class
Atm it is still in import and I would not expect an export class here
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.
Moved to gui.util
|
Some mior things, The only thing we should discuss is the renaming of the FileExtensions to FileType. |
| return this; | ||
| } | ||
|
|
||
| public Builder withDefaultExtension(String fileTypeDescription) { |
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 these cases to the unit tests we already have for this class
|
@Siedlerchr Thanks for the feedback. I now changed the code accordingly. Why don't you like the name |
lenhard
left a comment
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.
Overall a nice refactoring. I have some minor code comments, which are partly down to the structure of the code as it has been before.
I don't really have a strong opinion on FileType vs FileExtension.
| importMenu.automatedImport(Collections.singletonList(file.toString())); | ||
| // Set last working dir for import | ||
| Globals.prefs.put(JabRefPreferences.IMPORT_WORKING_DIRECTORY, file.getParent().toString()); | ||
| } catch (Exception ex) { |
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.
There's certainly a more specific type of exception you can catch here, isn't it?
| public String getDescription() { | ||
| return getFileType().getDescription(); | ||
| } | ||
| } |
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.
If I recall our git guidelines correctly, you should add a new line here
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.
There is actually a blank line 58, but github does not show these last empty lines (but it displays a warning symbol if the file actually does not end with an empty line).
| * @return The string describing available exporters. | ||
| */ | ||
| public String getExportersAsString(int maxLineLength, int firstLineSubtraction, String linePrefix) { | ||
| StringBuilder sb = new StringBuilder(); |
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.
Since you are already touching this code, please also use proper naming, e.g. builder.
| trans.setOutputProperty(OutputKeys.INDENT, "yes"); | ||
| trans.transform(source, result); | ||
| } catch (TransformerException | IllegalArgumentException | TransformerFactoryConfigurationError e) { | ||
| throw new Error(e); |
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.
Not your code, I know, but isn't it weird to throw an error here? Wouldn't it be better at least scale that down to a RuntimeException?
| this.undoableFieldChanges.addAll(newUndoableFieldChanges); | ||
| } | ||
|
|
||
| public void finalize(Path file) throws SaveException, IOException { |
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.
Just a thought: Would it make sense to have this class implement AutoCloseable, so that it could be used in a try-with-resources? This method seems to be built for that use case. Otherwise, it's not guaranteed that the writer will be closed.
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.
Never head about AutoClosable. Thanks for pointing this out. This is a good idea but there are quite a few places where the save session is canceled (i.e. commit or finalized is not called). Moreover, a quick look at the code showed that it is relatively hard to shift the file argument to the constructor of the save session (the creation happens in different classes then the actual commit).
| return; | ||
| } | ||
| Path outFile = Paths.get(file); | ||
| SaveSession ss = null; |
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.
Again, since you are already refactoring this method, please also improve the naming of variables.
|
|
||
| } | ||
|
|
||
| ; |
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.
It's really weird what kind of code you still find in JabRef. Great job removing this!
|
|
||
| @Test | ||
| public void testExportingEmptyDatabaseYieldsEmptyFile() throws Exception { | ||
| File tmpFile = testFolder.newFile(); |
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.
Instead of calling toPath below, it would be better if you created a Path object here directly. That applies to the other tests as well.
Fixes #3576.
I refactored the export package so that it now has a similar structure of the importer and a similar code can now be used for imports and exports. Since the issue #3576 didn't occurred for imports, this refactoring automatically fixes the problem for the export.
Notable changes:
ExportFormatis renamed toExporterExportFormatsis renamed toExportFactoryand no longer static.FileExtensionsis renamed toFileTypegradle localizationUpdate?