Refactor export code to fix #3576#3578
Conversation
| * TemplateExporter for exporting in MODS XML format. | ||
| */ | ||
| class ModsExportFormat extends ExportFormat { | ||
| class ModsExporter extends TemplateExporter { |
There was a problem hiding this comment.
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.
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.
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.
The last FileOutputStream could be replaced by the Files.newFileOutputStream which directly accepts a path
| 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())))) { |
| ### Changed | ||
|
|
||
| ### Fixed | ||
| - We fixed the name of an exported file. |
| 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.
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
|
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.
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.
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.
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.
If I recall our git guidelines correctly, you should add a new line here
There was a problem hiding this comment.
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.
Since you are already touching this code, please also use proper naming, e.g. builder.
| @@ -52,7 +52,7 @@ public void performExport(final BibDatabaseContext databaseContext, final String | |||
| } catch (TransformerException | IllegalArgumentException | TransformerFactoryConfigurationError e) { | |||
| throw new Error(e); | |||
There was a problem hiding this comment.
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.
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.
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.
Again, since you are already refactoring this method, please also improve the naming of variables.
|
|
||
| } | ||
|
|
||
| ; |
There was a problem hiding this comment.
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.
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?