From 06d0753b8f5e6caee2231480d83280db2d2adae4 Mon Sep 17 00:00:00 2001 From: Stefan Kolb Date: Thu, 18 Aug 2016 15:48:25 +0200 Subject: [PATCH 01/14] Fix #1771 Show all supported import types as default --- CHANGELOG.md | 2 + .../external/ExternalFileTypeEntryEditor.java | 2 +- .../java/net/sf/jabref/gui/FileDialog.java | 25 +++- .../sf/jabref/gui/FileListEntryEditor.java | 2 +- .../sf/jabref/gui/actions/BrowseAction.java | 4 +- .../importer/ImportCustomizationDialog.java | 4 +- .../sf/jabref/gui/importer/ImportFormats.java | 136 +++++++----------- .../jabref/gui/importer/ImportMenuItem.java | 7 - .../gui/journals/ManageJournalsPanel.java | 2 +- .../gui/plaintextimport/TextInputDialog.java | 2 +- .../gui/preftabs/PreferencesDialog.java | 2 +- .../logic/importer/ImportFormatReader.java | 3 +- .../jabref/preferences/JabRefPreferences.java | 1 - 13 files changed, 85 insertions(+), 107 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 60733aa74c5..ee2fe0d3732 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - [#1751](https://github.com/JabRef/jabref/issues/1751) Added tooltip to web search button - [#1758](https://github.com/JabRef/jabref/issues/1758) Added a button to open Database Properties dialog help - Improve focus of the maintable after a sidepane gets closed (Before it would focus the toolbar or it would focus the wrong entry) +- File open dialogs now use default extensions as primary file filter ### Fixed - Fixed [#1632](https://github.com/JabRef/jabref/issues/1632): User comments (@Comment) with or without brackets are now kept @@ -72,6 +73,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - Fixed [#1716](https://github.com/JabRef/jabref/issues/1716): `@`-Symbols stored in BibTeX fields no longer break the database - Fixed [#1499](https://github.com/JabRef/jabref/issues/1499): {} braces are now treated correctly in in author/editor - Fixed [#1531](https://github.com/JabRef/jabref/issues/1531): `\relax` can be used for abbreviation of author names +- Fixed [#1771](https://github.com/JabRef/jabref/issues/1771): Show all supported import types as default ### Removed diff --git a/src/main/java/net/sf/jabref/external/ExternalFileTypeEntryEditor.java b/src/main/java/net/sf/jabref/external/ExternalFileTypeEntryEditor.java index 696af7d8cbb..126d553eb94 100644 --- a/src/main/java/net/sf/jabref/external/ExternalFileTypeEntryEditor.java +++ b/src/main/java/net/sf/jabref/external/ExternalFileTypeEntryEditor.java @@ -73,7 +73,7 @@ public class ExternalFileTypeEntryEditor { appDir = Globals.prefs.get(JabRefPreferences.FILE_WORKING_DIRECTORY); } - Optional path = new FileDialog(fParent, appDir).openDialogAndGetSelectedFile(); + Optional path = new FileDialog(fParent, appDir).showDialogAndGetSelectedFile(); path.ifPresent(applicationDir -> { if (applicationDir.getParent() != null) { Globals.prefs.put(JabRefPreferences.FILE_WORKING_DIRECTORY, applicationDir.getParent().toString()); diff --git a/src/main/java/net/sf/jabref/gui/FileDialog.java b/src/main/java/net/sf/jabref/gui/FileDialog.java index 1f5e4f1a662..6dc06588f01 100644 --- a/src/main/java/net/sf/jabref/gui/FileDialog.java +++ b/src/main/java/net/sf/jabref/gui/FileDialog.java @@ -16,6 +16,7 @@ import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JOptionPane; +import javax.swing.filechooser.FileFilter; import javax.swing.filechooser.FileNameExtensionFilter; import net.sf.jabref.Globals; @@ -57,7 +58,6 @@ public void approveSelection() { private final JFrame parent; private final String directory; - private List fileFilters = new ArrayList<>(); private Collection extensions = EnumSet.noneOf(FileExtensions.class); /** @@ -111,7 +111,6 @@ public FileDialog withExtensions(Collection fileExtensions) { for (FileExtensions ext : fileExtensions) { FileNameExtensionFilter extFilter = new FileNameExtensionFilter(ext.getDescription(), ext.getExtensions()); fileChooser.addChoosableFileFilter(extFilter); - fileFilters.add(extFilter); } return this; @@ -130,6 +129,25 @@ public void setDefaultExtension(FileExtensions extension) { .ifPresent(fileChooser::setFileFilter); } + /** + * Returns the currently selected file filter. + * + * @return FileFilter + */ + public FileFilter getFileFilter() { + return fileChooser.getFileFilter(); + } + + /** + * Sets a custom file filter. + * Only use when withExtension() does not suffice. + * + * @param filter the custom file filter + */ + public void setFileFiler(FileFilter filter) { + fileChooser.setFileFilter(filter); + } + /** * Updates the working directory preference * @return FileDialog @@ -161,7 +179,7 @@ public List showDialogAndGetMultipleFiles() { * Shows an {@link JFileChooser#OPEN_DIALOG} and allows to select a single file/folder * @return The path of the selected file/folder or {@link Optional#empty()} if dialog is aborted */ - public Optional openDialogAndGetSelectedFile() { + public Optional showDialogAndGetSelectedFile() { fileChooser.setDialogType(JFileChooser.OPEN_DIALOG); if (showDialogAndIsAccepted()) { @@ -198,5 +216,4 @@ private boolean showDialogAndIsAccepted() { private static String getWorkingDir() { return Globals.prefs.get(JabRefPreferences.WORKING_DIRECTORY); } - } diff --git a/src/main/java/net/sf/jabref/gui/FileListEntryEditor.java b/src/main/java/net/sf/jabref/gui/FileListEntryEditor.java index f8a0081171f..f2420f65a0a 100644 --- a/src/main/java/net/sf/jabref/gui/FileListEntryEditor.java +++ b/src/main/java/net/sf/jabref/gui/FileListEntryEditor.java @@ -361,7 +361,7 @@ public boolean okPressed() { workingDir = Globals.prefs.get(JabRefPreferences.FILE_WORKING_DIRECTORY); } - Optional path = new FileDialog(this.frame, workingDir).openDialogAndGetSelectedFile(); + Optional path = new FileDialog(this.frame, workingDir).showDialogAndGetSelectedFile(); path.ifPresent(selection -> { diff --git a/src/main/java/net/sf/jabref/gui/actions/BrowseAction.java b/src/main/java/net/sf/jabref/gui/actions/BrowseAction.java index 873a03ab3c9..1c4f2dfbc1f 100644 --- a/src/main/java/net/sf/jabref/gui/actions/BrowseAction.java +++ b/src/main/java/net/sf/jabref/gui/actions/BrowseAction.java @@ -87,13 +87,13 @@ public void actionPerformed(ActionEvent e) { private String askUser() { if (dirsOnly) { Path path = new FileDialog(frame, comp.getText()).dirsOnly().withExtensions(extensions) - .openDialogAndGetSelectedFile().orElse(Paths.get("")); + .showDialogAndGetSelectedFile().orElse(Paths.get("")); String file = path.toString(); return file; } else { Path path = new FileDialog(frame, comp.getText()).withExtensions(extensions) - .openDialogAndGetSelectedFile().orElse(Paths.get("")); + .showDialogAndGetSelectedFile().orElse(Paths.get("")); String file = path.toString(); return file; diff --git a/src/main/java/net/sf/jabref/gui/importer/ImportCustomizationDialog.java b/src/main/java/net/sf/jabref/gui/importer/ImportCustomizationDialog.java index 86dee5923ca..09694ec2762 100644 --- a/src/main/java/net/sf/jabref/gui/importer/ImportCustomizationDialog.java +++ b/src/main/java/net/sf/jabref/gui/importer/ImportCustomizationDialog.java @@ -107,7 +107,7 @@ public ImportCustomizationDialog(final JabRefFrame frame) { CustomImporter importer = new CustomImporter(); Optional selectedFile = new FileDialog(frame).withExtension(FileExtensions.CLASS) - .openDialogAndGetSelectedFile(); + .showDialogAndGetSelectedFile(); if (selectedFile.isPresent() && (selectedFile.get().getParent() != null)) { importer.setBasePath(selectedFile.get().getParent().toString()); @@ -137,7 +137,7 @@ public ImportCustomizationDialog(final JabRefFrame frame) { JButton addFromJarButton = new JButton(Localization.lang("Add from JAR")); addFromJarButton.addActionListener(e -> { Optional jarZipFile = new FileDialog(frame) - .withExtensions(EnumSet.of(FileExtensions.ZIP, FileExtensions.JAR)).openDialogAndGetSelectedFile(); + .withExtensions(EnumSet.of(FileExtensions.ZIP, FileExtensions.JAR)).showDialogAndGetSelectedFile(); if (jarZipFile.isPresent()) { try (ZipFile zipFile = new ZipFile(jarZipFile.get().toFile(), ZipFile.OPEN_READ)) { diff --git a/src/main/java/net/sf/jabref/gui/importer/ImportFormats.java b/src/main/java/net/sf/jabref/gui/importer/ImportFormats.java index 7e691bced93..7214fc1101a 100644 --- a/src/main/java/net/sf/jabref/gui/importer/ImportFormats.java +++ b/src/main/java/net/sf/jabref/gui/importer/ImportFormats.java @@ -17,61 +17,37 @@ import java.awt.event.ActionEvent; import java.io.File; +import java.nio.file.Path; import java.util.Collections; -import java.util.Set; +import java.util.List; +import java.util.Objects; +import java.util.Optional; import java.util.SortedSet; -import java.util.TreeSet; +import java.util.stream.Collectors; +import java.util.stream.Stream; import javax.swing.AbstractAction; import javax.swing.Action; -import javax.swing.JFileChooser; import javax.swing.JOptionPane; - import javax.swing.filechooser.FileFilter; +import javax.swing.filechooser.FileNameExtensionFilter; import net.sf.jabref.Globals; +import net.sf.jabref.gui.FileDialog; import net.sf.jabref.gui.JabRefFrame; import net.sf.jabref.gui.actions.MnemonicAwareAction; import net.sf.jabref.gui.keyboard.KeyBinding; import net.sf.jabref.logic.importer.fileformat.ImportFormat; import net.sf.jabref.logic.l10n.Localization; +import net.sf.jabref.logic.util.FileExtensions; import net.sf.jabref.preferences.JabRefPreferences; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class ImportFormats { - private static final Log LOGGER = LogFactory.getLog(ImportFormats.class); - - private static JFileChooser createImportFileChooser(String currentDir) { - - SortedSet importers = Globals.IMPORT_FORMAT_READER.getImportFormats(); - - String lastUsedFormat = Globals.prefs.get(JabRefPreferences.LAST_USED_IMPORT); - FileFilter defaultFilter = null; - JFileChooser fc = new JFileChooser(currentDir); - Set filters = new TreeSet<>(); - for (ImportFormat format : importers) { - ImportFileFilter filter = new ImportFileFilter(format); - filters.add(filter); - if (format.getFormatName().equals(lastUsedFormat)) { - defaultFilter = filter; - } - } - for (ImportFileFilter filter : filters) { - fc.addChoosableFileFilter(filter); - } - - if (defaultFilter == null) { - fc.setFileFilter(fc.getAcceptAllFileFilter()); - } else { - fc.setFileFilter(defaultFilter); - } - return fc; - } - /** * Create an AbstractAction for performing an Import operation. * @param frame The JabRefFrame of this JabRef instance. @@ -84,64 +60,56 @@ public static AbstractAction getImportAction(JabRefFrame frame, boolean openInNe class ImportAction extends MnemonicAwareAction { private final JabRefFrame frame; - private final boolean openInNew; - + private final boolean newDatabase; - public ImportAction(JabRefFrame frame, boolean openInNew) { + public ImportAction(JabRefFrame frame, boolean newDatabase) { this.frame = frame; - this.openInNew = openInNew; - - putValue(Action.NAME, openInNew ? Localization.menuTitle("Import into new database") : Localization - .menuTitle("Import into current database")); - putValue(Action.ACCELERATOR_KEY, - openInNew ? Globals.getKeyPrefs().getKey(KeyBinding.IMPORT_INTO_NEW_DATABASE) : Globals - .getKeyPrefs().getKey(KeyBinding.IMPORT_INTO_CURRENT_DATABASE)); + this.newDatabase = newDatabase; + + if (newDatabase) { + putValue(Action.NAME, Localization.menuTitle("Import into new database")); + putValue(Action.ACCELERATOR_KEY, Globals.getKeyPrefs().getKey(KeyBinding.IMPORT_INTO_NEW_DATABASE)); + } else { + putValue(Action.NAME, Localization.menuTitle("Import into current database")); + putValue(Action.ACCELERATOR_KEY, Globals.getKeyPrefs().getKey(KeyBinding.IMPORT_INTO_CURRENT_DATABASE)); + } } @Override public void actionPerformed(ActionEvent e) { - JFileChooser fileChooser = createImportFileChooser( - Globals.prefs.get(JabRefPreferences.IMPORT_WORKING_DIRECTORY)); - int result = fileChooser.showOpenDialog(frame); - - if (result != JFileChooser.APPROVE_OPTION) { - return; - } - - File file = fileChooser.getSelectedFile(); - if (file == null) { - return; - } - - FileFilter ff = fileChooser.getFileFilter(); - ImportFormat format = null; - if (ff instanceof ImportFileFilter) { - format = ((ImportFileFilter) ff).getImportFormat(); - } - - try { - if (!file.exists()) { - // Warn that the file doesn't exists: - JOptionPane.showMessageDialog(frame, - Localization.lang("File not found") + ": '" + file.getName() + "'.", - Localization.lang("Import"), JOptionPane.ERROR_MESSAGE); - return; + SortedSet importers = Globals.IMPORT_FORMAT_READER.getImportFormats(); + List extensions = importers.stream().map(p -> p.getExtensions()).collect(Collectors.toList()); + FileDialog dialog = new FileDialog(frame, Globals.prefs.get(JabRefPreferences.IMPORT_WORKING_DIRECTORY)); + // Add file filter for all supported types + List flatExtensions = extensions.stream().flatMap(extList -> Stream.of(extList.getExtensions())).collect(Collectors.toList()); + dialog.setFileFiler(new FileNameExtensionFilter(Localization.lang("Available import formats"), flatExtensions.toArray(new String[flatExtensions.size()]))); + // Add filters for extensions + dialog.withExtensions(extensions); + + Optional selectedFile = dialog.showDialogAndGetSelectedFile(); + + selectedFile.ifPresent(sel -> { + try { + File file = sel.toFile(); + + if (!file.exists()) { + JOptionPane.showMessageDialog(frame, + Localization.lang("File not found") + ": '" + file.getName() + "'.", + Localization.lang("Import"), JOptionPane.ERROR_MESSAGE); + return; + } + + Optional format = importers.stream() + .filter(i -> Objects.equals(i.getExtensions().getDescription(), dialog.getFileFilter().getDescription())) + .findFirst(); + ImportMenuItem importMenu = new ImportMenuItem(frame, newDatabase, format.orElse(null)); + importMenu.automatedImport(Collections.singletonList(file.getAbsolutePath())); + // Set last working dir for import + Globals.prefs.put(JabRefPreferences.IMPORT_WORKING_DIRECTORY, file.getParent()); + } catch (Exception ex) { + LOGGER.warn("Cannot import file", ex); } - ImportMenuItem imi = new ImportMenuItem(frame, openInNew, format); - imi.automatedImport(Collections.singletonList(file.getAbsolutePath())); - - // Make sure we remember which filter was used, to set the default - // for next time: - if (format == null) { - Globals.prefs.put(JabRefPreferences.LAST_USED_IMPORT, "__all"); - } else { - Globals.prefs.put(JabRefPreferences.LAST_USED_IMPORT, format.getFormatName()); - } - Globals.prefs.put(JabRefPreferences.IMPORT_WORKING_DIRECTORY, file.getParent()); - } catch (Exception ex) { - LOGGER.warn("Problem with import format", ex); - } - + }); } } diff --git a/src/main/java/net/sf/jabref/gui/importer/ImportMenuItem.java b/src/main/java/net/sf/jabref/gui/importer/ImportMenuItem.java index da8b3c83513..f250bc48b4c 100644 --- a/src/main/java/net/sf/jabref/gui/importer/ImportMenuItem.java +++ b/src/main/java/net/sf/jabref/gui/importer/ImportMenuItem.java @@ -47,7 +47,6 @@ /* * TODO: could separate the "menu item" functionality from the importing functionality - * */ public class ImportMenuItem extends JMenuItem implements ActionListener { @@ -56,7 +55,6 @@ public class ImportMenuItem extends JMenuItem implements ActionListener { private final ImportFormat importer; private IOException importError; - public ImportMenuItem(JabRefFrame frame, boolean openInNew) { this(frame, openInNew, null); } @@ -98,7 +96,6 @@ class MyWorker extends AbstractWorker { private ParserResult bibtexResult; // Contains the merged import results private boolean fileOk; - @Override public void init() { importError = null; @@ -134,10 +131,6 @@ public void run() { frame.output(Localization.lang("Importing in %0 format", importer.getFormatName()) + "..."); // Specific importer: ParserResult pr = importer.importDatabase(file, Globals.prefs.getDefaultEncoding()); - if (pr.hasWarnings()) { - frame.showMessage(pr.getErrorMessage()); - } - imports.add(new ImportFormatReader.UnknownFormatImport(importer.getFormatName(), pr)); } } catch (IOException e) { diff --git a/src/main/java/net/sf/jabref/gui/journals/ManageJournalsPanel.java b/src/main/java/net/sf/jabref/gui/journals/ManageJournalsPanel.java index 9b4bc61e3c5..9a4247f9632 100644 --- a/src/main/java/net/sf/jabref/gui/journals/ManageJournalsPanel.java +++ b/src/main/java/net/sf/jabref/gui/journals/ManageJournalsPanel.java @@ -209,7 +209,7 @@ public ManageJournalsPanel(final JabRefFrame frame) { }); browseOld.addActionListener(e -> { - Optional path = new FileDialog(frame, personalFile.getText()).openDialogAndGetSelectedFile(); + Optional path = new FileDialog(frame, personalFile.getText()).showDialogAndGetSelectedFile(); path.ifPresent(fileName -> { personalFile.setText(fileName.toString()); diff --git a/src/main/java/net/sf/jabref/gui/plaintextimport/TextInputDialog.java b/src/main/java/net/sf/jabref/gui/plaintextimport/TextInputDialog.java index 3e30cd57aa3..73462b21234 100644 --- a/src/main/java/net/sf/jabref/gui/plaintextimport/TextInputDialog.java +++ b/src/main/java/net/sf/jabref/gui/plaintextimport/TextInputDialog.java @@ -595,7 +595,7 @@ public LoadAction() { public void actionPerformed(ActionEvent e) { try { Optional path = new FileDialog(frame).withExtension(FileExtensions.TXT) - .openDialogAndGetSelectedFile(); + .showDialogAndGetSelectedFile(); if (path.isPresent()) { File newFile = path.get().toFile(); document.remove(0, document.getLength()); diff --git a/src/main/java/net/sf/jabref/gui/preftabs/PreferencesDialog.java b/src/main/java/net/sf/jabref/gui/preftabs/PreferencesDialog.java index f694ae8136e..46f8723e201 100644 --- a/src/main/java/net/sf/jabref/gui/preftabs/PreferencesDialog.java +++ b/src/main/java/net/sf/jabref/gui/preftabs/PreferencesDialog.java @@ -183,7 +183,7 @@ public PreferencesDialog(JabRefFrame parent) { importPreferences.addActionListener(e -> { FileDialog dialog = new FileDialog(frame, System.getProperty("user.home")).withExtension(FileExtensions.XML); dialog.setDefaultExtension(FileExtensions.XML); - Optional fileName = dialog.openDialogAndGetSelectedFile(); + Optional fileName = dialog.showDialogAndGetSelectedFile(); if (fileName.isPresent()) { try { diff --git a/src/main/java/net/sf/jabref/logic/importer/ImportFormatReader.java b/src/main/java/net/sf/jabref/logic/importer/ImportFormatReader.java index acd4746b3db..151d54cfa8e 100644 --- a/src/main/java/net/sf/jabref/logic/importer/ImportFormatReader.java +++ b/src/main/java/net/sf/jabref/logic/importer/ImportFormatReader.java @@ -52,6 +52,7 @@ import org.apache.commons.logging.LogFactory; public class ImportFormatReader { + private static final Log LOGGER = LogFactory.getLog(ImportFormatReader.class); public static final String BIBTEX_FORMAT = "BibTeX"; @@ -61,8 +62,6 @@ public class ImportFormatReader { */ private final SortedSet formats = new TreeSet<>(); - private static final Log LOGGER = LogFactory.getLog(ImportFormatReader.class); - private ImportFormatPreferences importFormatPreferences; diff --git a/src/main/java/net/sf/jabref/preferences/JabRefPreferences.java b/src/main/java/net/sf/jabref/preferences/JabRefPreferences.java index 44adf006bac..ec6e5f2bcc3 100644 --- a/src/main/java/net/sf/jabref/preferences/JabRefPreferences.java +++ b/src/main/java/net/sf/jabref/preferences/JabRefPreferences.java @@ -303,7 +303,6 @@ public class JabRefPreferences { public static final String SHOW_FILE_LINKS_UPGRADE_WARNING = "showFileLinksUpgradeWarning"; public static final String SIDE_PANE_WIDTH = "sidePaneWidth"; public static final String LAST_USED_EXPORT = "lastUsedExport"; - public static final String LAST_USED_IMPORT = "lastUsedImport"; public static final String FLOAT_MARKED_ENTRIES = "floatMarkedEntries"; public static final String CITE_COMMAND = "citeCommand"; public static final String EXTERNAL_JOURNAL_LISTS = "externalJournalLists"; From e1bea42d55246528c782818f3b0d96e782650a93 Mon Sep 17 00:00:00 2001 From: Stefan Kolb Date: Thu, 18 Aug 2016 16:10:12 +0200 Subject: [PATCH 02/14] Optimize imports --- src/main/java/net/sf/jabref/gui/FileDialog.java | 1 - src/main/java/net/sf/jabref/gui/importer/ImportFormats.java | 1 - 2 files changed, 2 deletions(-) diff --git a/src/main/java/net/sf/jabref/gui/FileDialog.java b/src/main/java/net/sf/jabref/gui/FileDialog.java index 6dc06588f01..e7d99862d7d 100644 --- a/src/main/java/net/sf/jabref/gui/FileDialog.java +++ b/src/main/java/net/sf/jabref/gui/FileDialog.java @@ -3,7 +3,6 @@ import java.io.File; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; diff --git a/src/main/java/net/sf/jabref/gui/importer/ImportFormats.java b/src/main/java/net/sf/jabref/gui/importer/ImportFormats.java index 7214fc1101a..2af3bf3672d 100644 --- a/src/main/java/net/sf/jabref/gui/importer/ImportFormats.java +++ b/src/main/java/net/sf/jabref/gui/importer/ImportFormats.java @@ -29,7 +29,6 @@ import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.JOptionPane; -import javax.swing.filechooser.FileFilter; import javax.swing.filechooser.FileNameExtensionFilter; import net.sf.jabref.Globals; From a3656a640c1ebb6b43447152a25fbed7b90a1a66 Mon Sep 17 00:00:00 2001 From: Stefan Kolb Date: Thu, 18 Aug 2016 17:10:48 +0200 Subject: [PATCH 03/14] Fix typo --- src/main/java/net/sf/jabref/gui/FileDialog.java | 2 +- src/main/java/net/sf/jabref/gui/importer/ImportFormats.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/sf/jabref/gui/FileDialog.java b/src/main/java/net/sf/jabref/gui/FileDialog.java index e7d99862d7d..7781bfc4143 100644 --- a/src/main/java/net/sf/jabref/gui/FileDialog.java +++ b/src/main/java/net/sf/jabref/gui/FileDialog.java @@ -143,7 +143,7 @@ public FileFilter getFileFilter() { * * @param filter the custom file filter */ - public void setFileFiler(FileFilter filter) { + public void setFileFilter(FileFilter filter) { fileChooser.setFileFilter(filter); } diff --git a/src/main/java/net/sf/jabref/gui/importer/ImportFormats.java b/src/main/java/net/sf/jabref/gui/importer/ImportFormats.java index 2af3bf3672d..540ac83e47b 100644 --- a/src/main/java/net/sf/jabref/gui/importer/ImportFormats.java +++ b/src/main/java/net/sf/jabref/gui/importer/ImportFormats.java @@ -81,7 +81,7 @@ public void actionPerformed(ActionEvent e) { FileDialog dialog = new FileDialog(frame, Globals.prefs.get(JabRefPreferences.IMPORT_WORKING_DIRECTORY)); // Add file filter for all supported types List flatExtensions = extensions.stream().flatMap(extList -> Stream.of(extList.getExtensions())).collect(Collectors.toList()); - dialog.setFileFiler(new FileNameExtensionFilter(Localization.lang("Available import formats"), flatExtensions.toArray(new String[flatExtensions.size()]))); + dialog.setFileFilter(new FileNameExtensionFilter(Localization.lang("Available import formats"), flatExtensions.toArray(new String[flatExtensions.size()]))); // Add filters for extensions dialog.withExtensions(extensions); From d366903fc2ae3aa7acad9efaf43647ee01aca97f Mon Sep 17 00:00:00 2001 From: Oscar Gustafsson Date: Thu, 18 Aug 2016 20:42:28 +0200 Subject: [PATCH 04/14] Added UpdateFieldPreferences (#1773) * Added UpdateFieldPreferences * Moved method to JabRefPreferences --- .../java/net/sf/jabref/gui/BasePanel.java | 10 ++-- .../gui/importer/ImportInspectionDialog.java | 3 +- .../jabref/gui/importer/ImportMenuItem.java | 3 +- .../actions/AppendDatabaseAction.java | 3 +- .../gui/plaintextimport/TextInputDialog.java | 2 +- .../net/sf/jabref/logic/util/UpdateField.java | 34 ++++++----- .../logic/util/UpdateFieldPreferences.java | 56 +++++++++++++++++++ .../logic/util/date/EasyDateFormat.java | 3 + .../net/sf/jabref/pdfimport/PdfImporter.java | 2 +- .../jabref/preferences/JabRefPreferences.java | 7 +++ 10 files changed, 96 insertions(+), 27 deletions(-) create mode 100644 src/main/java/net/sf/jabref/logic/util/UpdateFieldPreferences.java diff --git a/src/main/java/net/sf/jabref/gui/BasePanel.java b/src/main/java/net/sf/jabref/gui/BasePanel.java index 5a29dfc05f7..3d29e339253 100644 --- a/src/main/java/net/sf/jabref/gui/BasePanel.java +++ b/src/main/java/net/sf/jabref/gui/BasePanel.java @@ -634,7 +634,8 @@ public void update() { tidialog.setVisible(true); if (tidialog.okPressed()) { - UpdateField.setAutomaticFields(Collections.singletonList(bibEntry), false, false, Globals.prefs); + UpdateField.setAutomaticFields(Collections.singletonList(bibEntry), false, false, + Globals.prefs.getUpdateFieldPreferences()); insertEntry(bibEntry); } }); @@ -832,8 +833,7 @@ private void paste() { if (firstBE == null) { firstBE = be; } - UpdateField.setAutomaticFields(be, Globals.prefs.getBoolean(JabRefPreferences.OVERWRITE_OWNER), - Globals.prefs.getBoolean(JabRefPreferences.OVERWRITE_TIME_STAMP), Globals.prefs); + UpdateField.setAutomaticFields(be, Globals.prefs.getUpdateFieldPreferences()); // We have to clone the // entries, since the pasted @@ -1155,7 +1155,7 @@ public BibEntry newEntry(EntryType type) { // Set owner/timestamp if options are enabled: List list = new ArrayList<>(); list.add(be); - UpdateField.setAutomaticFields(list, true, true, Globals.prefs); + UpdateField.setAutomaticFields(list, true, true, Globals.prefs.getUpdateFieldPreferences()); // Create an UndoableInsertEntry object. getUndoManager().addEdit(new UndoableInsertEntry(bibDatabaseContext.getDatabase(), be, BasePanel.this)); @@ -1308,7 +1308,7 @@ public void insertEntry(final BibEntry bibEntry) { bibDatabaseContext.getDatabase().insertEntry(bibEntry); if (Globals.prefs.getBoolean(JabRefPreferences.USE_OWNER)) { // Set owner field to default value - UpdateField.setAutomaticFields(bibEntry, true, true, Globals.prefs); + UpdateField.setAutomaticFields(bibEntry, true, true, Globals.prefs.getUpdateFieldPreferences()); } // Create an UndoableInsertEntry object. getUndoManager() diff --git a/src/main/java/net/sf/jabref/gui/importer/ImportInspectionDialog.java b/src/main/java/net/sf/jabref/gui/importer/ImportInspectionDialog.java index 36ac7ce7ef7..4232197ad89 100644 --- a/src/main/java/net/sf/jabref/gui/importer/ImportInspectionDialog.java +++ b/src/main/java/net/sf/jabref/gui/importer/ImportInspectionDialog.java @@ -723,8 +723,7 @@ private void addSelectedEntries(NamedCompound ce, final List selected) boolean groupingCanceled = false; // Set owner/timestamp if options are enabled: - UpdateField.setAutomaticFields(selected, Globals.prefs.getBoolean(JabRefPreferences.OVERWRITE_OWNER), - Globals.prefs.getBoolean(JabRefPreferences.OVERWRITE_TIME_STAMP), Globals.prefs); + UpdateField.setAutomaticFields(selected, Globals.prefs.getUpdateFieldPreferences()); // Mark entries if we should if (EntryMarker.shouldMarkEntries()) { diff --git a/src/main/java/net/sf/jabref/gui/importer/ImportMenuItem.java b/src/main/java/net/sf/jabref/gui/importer/ImportMenuItem.java index da8b3c83513..2c755de75c9 100644 --- a/src/main/java/net/sf/jabref/gui/importer/ImportMenuItem.java +++ b/src/main/java/net/sf/jabref/gui/importer/ImportMenuItem.java @@ -248,8 +248,7 @@ private ParserResult mergeImportResults(List updateField(BibEntry be, String field, Strin * @param overwriteTimestamp Indicates whether timestamp should be set if it is already set. */ public static void setAutomaticFields(BibEntry entry, boolean overwriteOwner, boolean overwriteTimestamp, - JabRefPreferences prefs) { - String defaultOwner = prefs.get(JabRefPreferences.DEFAULT_OWNER); - String timestamp = EasyDateFormat.fromPreferences(prefs).getCurrentDate(); - String timeStampField = prefs.get(JabRefPreferences.TIME_STAMP_FIELD); - boolean setOwner = prefs.getBoolean(JabRefPreferences.USE_OWNER) - && (overwriteOwner || (!entry.hasField(FieldName.OWNER))); - boolean setTimeStamp = prefs.getBoolean(JabRefPreferences.USE_TIME_STAMP) - && (overwriteTimestamp || (!entry.hasField(timeStampField))); + UpdateFieldPreferences prefs) { + String defaultOwner = prefs.getDefaultOwner(); + String timestamp = EasyDateFormat.fromTimeStampFormat(prefs.getTimeStampFormat()).getCurrentDate(); + String timeStampField = prefs.getTimeStampField(); + boolean setOwner = prefs.isUseOwner() && (overwriteOwner || (!entry.hasField(FieldName.OWNER))); + boolean setTimeStamp = prefs.isUseTimeStamp() && (overwriteTimestamp || (!entry.hasField(timeStampField))); setAutomaticFields(entry, setOwner, defaultOwner, setTimeStamp, timeStampField, timestamp); } + public static void setAutomaticFields(BibEntry entry, UpdateFieldPreferences prefs) { + UpdateField.setAutomaticFields(entry, prefs.isOverwriteOwner(), prefs.isOverwriteTimeStamp(), prefs); + } + private static void setAutomaticFields(BibEntry entry, boolean setOwner, String owner, boolean setTimeStamp, String timeStampField, String timeStamp) { @@ -118,19 +119,19 @@ private static void setAutomaticFields(BibEntry entry, boolean setOwner, String * @param bibs List of bibtex entries */ public static void setAutomaticFields(Collection bibs, boolean overwriteOwner, - boolean overwriteTimestamp, JabRefPreferences prefs) { + boolean overwriteTimestamp, UpdateFieldPreferences prefs) { - boolean globalSetOwner = prefs.getBoolean(JabRefPreferences.USE_OWNER); - boolean globalSetTimeStamp = prefs.getBoolean(JabRefPreferences.USE_TIME_STAMP); + boolean globalSetOwner = prefs.isUseOwner(); + boolean globalSetTimeStamp = prefs.isUseTimeStamp(); // Do not need to do anything if all options are disabled if (!(globalSetOwner || globalSetTimeStamp)) { return; } - String timeStampField = prefs.get(JabRefPreferences.TIME_STAMP_FIELD); - String defaultOwner = prefs.get(JabRefPreferences.DEFAULT_OWNER); - String timestamp = EasyDateFormat.fromPreferences(prefs).getCurrentDate(); + String timeStampField = prefs.getTimeStampField(); + String defaultOwner = prefs.getDefaultOwner(); + String timestamp = EasyDateFormat.fromTimeStampFormat(prefs.getTimeStampFormat()).getCurrentDate(); // Iterate through all entries for (BibEntry curEntry : bibs) { @@ -140,4 +141,7 @@ public static void setAutomaticFields(Collection bibs, boolean overwri } } + public static void setAutomaticFields(Collection bibs, UpdateFieldPreferences prefs) { + UpdateField.setAutomaticFields(bibs, prefs.isOverwriteOwner(), prefs.isOverwriteTimeStamp(), prefs); + } } diff --git a/src/main/java/net/sf/jabref/logic/util/UpdateFieldPreferences.java b/src/main/java/net/sf/jabref/logic/util/UpdateFieldPreferences.java new file mode 100644 index 00000000000..cca77feb71c --- /dev/null +++ b/src/main/java/net/sf/jabref/logic/util/UpdateFieldPreferences.java @@ -0,0 +1,56 @@ +package net.sf.jabref.logic.util; + +public class UpdateFieldPreferences { + + private final boolean useOwner; + private final boolean useTimeStamp; + private final boolean overwriteOwner; + private final boolean overwriteTimeStamp; + private final String timeStampField; + private final String timeStampFormat; + private final String defaultOwner; + + + public UpdateFieldPreferences(boolean useOwner, boolean overwriteOwner, String defaultOwner, boolean useTimeStamp, + boolean overwriteTimeStamp, String timeStampField, + String timeStampFormat) { + this.useOwner = useOwner; + this.overwriteOwner = overwriteOwner; + this.defaultOwner = defaultOwner; + this.useTimeStamp = useTimeStamp; + this.overwriteTimeStamp = overwriteTimeStamp; + this.timeStampField = timeStampField; + this.timeStampFormat = timeStampFormat; + } + + public boolean isUseOwner() { + return useOwner; + } + + + public boolean isUseTimeStamp() { + return useTimeStamp; + } + + + public String getTimeStampField() { + return timeStampField; + } + + + public String getDefaultOwner() { + return defaultOwner; + } + + public String getTimeStampFormat() { + return timeStampFormat; + } + + public boolean isOverwriteOwner() { + return overwriteOwner; + } + + public boolean isOverwriteTimeStamp() { + return overwriteTimeStamp; + } +} diff --git a/src/main/java/net/sf/jabref/logic/util/date/EasyDateFormat.java b/src/main/java/net/sf/jabref/logic/util/date/EasyDateFormat.java index cbef4f15af0..896d47e2a6b 100644 --- a/src/main/java/net/sf/jabref/logic/util/date/EasyDateFormat.java +++ b/src/main/java/net/sf/jabref/logic/util/date/EasyDateFormat.java @@ -55,6 +55,9 @@ public String getDateAt(ZonedDateTime dateTime) { return dateTime.format(dateFormatter); } + public static EasyDateFormat fromTimeStampFormat(String timeStampFormat) { + return new EasyDateFormat(timeStampFormat); + } public static EasyDateFormat fromPreferences(JabRefPreferences preferences) { return new EasyDateFormat(preferences.get(JabRefPreferences.TIME_STAMP_FORMAT)); diff --git a/src/main/java/net/sf/jabref/pdfimport/PdfImporter.java b/src/main/java/net/sf/jabref/pdfimport/PdfImporter.java index dac786cbf35..6e38925bc36 100644 --- a/src/main/java/net/sf/jabref/pdfimport/PdfImporter.java +++ b/src/main/java/net/sf/jabref/pdfimport/PdfImporter.java @@ -284,7 +284,7 @@ private BibEntry createNewEntry() { // Set owner/timestamp if options are enabled: List list = new ArrayList<>(); list.add(be); - UpdateField.setAutomaticFields(list, true, true, Globals.prefs); + UpdateField.setAutomaticFields(list, true, true, Globals.prefs.getUpdateFieldPreferences()); // Create an UndoableInsertEntry object. panel.getUndoManager().addEdit(new UndoableInsertEntry(panel.getDatabase(), be, panel)); diff --git a/src/main/java/net/sf/jabref/preferences/JabRefPreferences.java b/src/main/java/net/sf/jabref/preferences/JabRefPreferences.java index 44adf006bac..5b68b26774f 100644 --- a/src/main/java/net/sf/jabref/preferences/JabRefPreferences.java +++ b/src/main/java/net/sf/jabref/preferences/JabRefPreferences.java @@ -70,6 +70,7 @@ import net.sf.jabref.logic.protectedterms.ProtectedTermsLoader; import net.sf.jabref.logic.remote.RemotePreferences; import net.sf.jabref.logic.util.OS; +import net.sf.jabref.logic.util.UpdateFieldPreferences; import net.sf.jabref.logic.util.VersionPreferences; import net.sf.jabref.logic.util.strings.StringUtil; import net.sf.jabref.model.bibtexkeypattern.AbstractBibtexKeyPattern; @@ -1380,4 +1381,10 @@ private static void insertCleanupPreset(Map storage, CleanupPres storage.put(CLEANUP_FORMATTERS, convertListToString(preset.getFormatterCleanups().getAsStringList())); } + public UpdateFieldPreferences getUpdateFieldPreferences() { + return new UpdateFieldPreferences(getBoolean(USE_OWNER), getBoolean(OVERWRITE_OWNER), get(DEFAULT_OWNER), + getBoolean(USE_TIME_STAMP), getBoolean(OVERWRITE_TIME_STAMP), get(TIME_STAMP_FIELD), + get(TIME_STAMP_FORMAT)); + } + } From a55b3ebfe642158d3769e8338bc6cd5b97ea436e Mon Sep 17 00:00:00 2001 From: Oscar Gustafsson Date: Thu, 18 Aug 2016 20:52:11 +0200 Subject: [PATCH 05/14] Injected LayoutFormatterPreferences in ExportFormat (#1695) * Injected LayoutFormatterPreferences in ExportFormat * Injected SavePreferences * Fixed comments --- src/main/java/net/sf/jabref/JabRefMain.java | 11 +++- .../net/sf/jabref/cli/ArgumentProcessor.java | 10 +++- .../sf/jabref/gui/exporter/ExportAction.java | 9 ++- .../exporter/ExportCustomizationDialog.java | 10 +++- .../gui/preftabs/PreferencesDialog.java | 12 +++- .../logic/exporter/CustomExportList.java | 28 +++++---- .../jabref/logic/exporter/ExportFormat.java | 51 ++++++++++------ .../jabref/logic/exporter/ExportFormats.java | 58 +++++++++++-------- .../sf/jabref/logic/layout/LayoutEntry.java | 2 +- .../layout/LayoutFormatterPreferences.java | 8 +-- .../jabref/preferences/JabRefPreferences.java | 4 -- .../logic/exporter/ExportFormatTest.java | 13 ++++- .../logic/exporter/HtmlExportFormatTest.java | 12 +++- 13 files changed, 156 insertions(+), 72 deletions(-) diff --git a/src/main/java/net/sf/jabref/JabRefMain.java b/src/main/java/net/sf/jabref/JabRefMain.java index ca6ed9e7d26..93764994f47 100644 --- a/src/main/java/net/sf/jabref/JabRefMain.java +++ b/src/main/java/net/sf/jabref/JabRefMain.java @@ -16,17 +16,21 @@ package net.sf.jabref; import java.net.Authenticator; +import java.util.Map; import javax.swing.SwingUtilities; import net.sf.jabref.cli.ArgumentProcessor; import net.sf.jabref.gui.remote.JabRefMessageHandler; import net.sf.jabref.logic.CustomEntryTypesManager; +import net.sf.jabref.logic.exporter.ExportFormat; import net.sf.jabref.logic.exporter.ExportFormats; +import net.sf.jabref.logic.exporter.SavePreferences; import net.sf.jabref.logic.formatter.casechanger.ProtectTermsFormatter; import net.sf.jabref.logic.importer.ImportFormatPreferences; import net.sf.jabref.logic.journals.JournalAbbreviationLoader; import net.sf.jabref.logic.l10n.Localization; +import net.sf.jabref.logic.layout.LayoutFormatterPreferences; import net.sf.jabref.logic.net.ProxyAuthenticator; import net.sf.jabref.logic.net.ProxyPreferences; import net.sf.jabref.logic.net.ProxyRegisterer; @@ -78,7 +82,12 @@ private static void start(String[] args) { Globals.IMPORT_FORMAT_READER.resetImportFormats(ImportFormatPreferences.fromPreferences(Globals.prefs), XMPPreferences.fromPreferences(Globals.prefs)); CustomEntryTypesManager.loadCustomEntryTypes(preferences); - ExportFormats.initAllExports(Globals.prefs.customExports.getCustomExportFormats(Globals.prefs)); + Map customFormats = Globals.prefs.customExports.getCustomExportFormats(Globals.prefs, + Globals.journalAbbreviationLoader); + LayoutFormatterPreferences layoutPreferences = LayoutFormatterPreferences.fromPreferences(Globals.prefs, + Globals.journalAbbreviationLoader); + SavePreferences savePreferences = SavePreferences.loadForExportFromPreferences(Globals.prefs); + ExportFormats.initAllExports(customFormats, layoutPreferences, savePreferences); // Read list(s) of journal names and abbreviations Globals.journalAbbreviationLoader = new JournalAbbreviationLoader(); diff --git a/src/main/java/net/sf/jabref/cli/ArgumentProcessor.java b/src/main/java/net/sf/jabref/cli/ArgumentProcessor.java index c63c04adf84..cdc1355bad1 100644 --- a/src/main/java/net/sf/jabref/cli/ArgumentProcessor.java +++ b/src/main/java/net/sf/jabref/cli/ArgumentProcessor.java @@ -9,6 +9,7 @@ import java.util.Collections; import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.Optional; import java.util.prefs.BackingStoreException; @@ -25,6 +26,7 @@ import net.sf.jabref.logic.bibtexkeypattern.BibtexKeyPatternUtil; import net.sf.jabref.logic.exporter.BibDatabaseWriter; import net.sf.jabref.logic.exporter.BibtexDatabaseWriter; +import net.sf.jabref.logic.exporter.ExportFormat; import net.sf.jabref.logic.exporter.ExportFormats; import net.sf.jabref.logic.exporter.FileSaveSession; import net.sf.jabref.logic.exporter.IExportFormat; @@ -37,6 +39,7 @@ import net.sf.jabref.logic.importer.OutputPrinter; import net.sf.jabref.logic.importer.ParserResult; import net.sf.jabref.logic.l10n.Localization; +import net.sf.jabref.logic.layout.LayoutFormatterPreferences; import net.sf.jabref.logic.logging.JabRefLogger; import net.sf.jabref.logic.search.DatabaseSearcher; import net.sf.jabref.logic.search.SearchQuery; @@ -390,7 +393,12 @@ private void importPreferences() { try { Globals.prefs.importPreferences(cli.getPreferencesImport()); CustomEntryTypesManager.loadCustomEntryTypes(Globals.prefs); - ExportFormats.initAllExports(Globals.prefs.customExports.getCustomExportFormats(Globals.prefs)); + Map customFormats = Globals.prefs.customExports.getCustomExportFormats(Globals.prefs, + Globals.journalAbbreviationLoader); + LayoutFormatterPreferences layoutPreferences = LayoutFormatterPreferences.fromPreferences(Globals.prefs, + Globals.journalAbbreviationLoader); + SavePreferences savePreferences = SavePreferences.loadForExportFromPreferences(Globals.prefs); + ExportFormats.initAllExports(customFormats, layoutPreferences, savePreferences); } catch (JabRefException ex) { LOGGER.error("Cannot import preferences", ex); } diff --git a/src/main/java/net/sf/jabref/gui/exporter/ExportAction.java b/src/main/java/net/sf/jabref/gui/exporter/ExportAction.java index bef252b3c06..730a375a75d 100644 --- a/src/main/java/net/sf/jabref/gui/exporter/ExportAction.java +++ b/src/main/java/net/sf/jabref/gui/exporter/ExportAction.java @@ -17,9 +17,12 @@ import net.sf.jabref.gui.JabRefFrame; import net.sf.jabref.gui.actions.MnemonicAwareAction; import net.sf.jabref.gui.worker.AbstractWorker; +import net.sf.jabref.logic.exporter.ExportFormat; import net.sf.jabref.logic.exporter.ExportFormats; import net.sf.jabref.logic.exporter.IExportFormat; +import net.sf.jabref.logic.exporter.SavePreferences; import net.sf.jabref.logic.l10n.Localization; +import net.sf.jabref.logic.layout.LayoutFormatterPreferences; import net.sf.jabref.model.entry.BibEntry; import net.sf.jabref.preferences.JabRefPreferences; @@ -59,7 +62,11 @@ public InternalExportAction(JabRefFrame frame, boolean selectedOnly) { @Override public void actionPerformed(ActionEvent e) { - ExportFormats.initAllExports(Globals.prefs.customExports.getCustomExportFormats(Globals.prefs)); + Map customFormats = Globals.prefs.customExports.getCustomExportFormats(Globals.prefs, + Globals.journalAbbreviationLoader); + LayoutFormatterPreferences layoutPreferences = LayoutFormatterPreferences.fromPreferences(Globals.prefs, Globals.journalAbbreviationLoader); + SavePreferences savePreferences = SavePreferences.loadForExportFromPreferences(Globals.prefs); + ExportFormats.initAllExports(customFormats, layoutPreferences, savePreferences); JFileChooser fc = ExportAction .createExportFileChooser(Globals.prefs.get(JabRefPreferences.EXPORT_WORKING_DIRECTORY)); fc.showSaveDialog(frame); diff --git a/src/main/java/net/sf/jabref/gui/exporter/ExportCustomizationDialog.java b/src/main/java/net/sf/jabref/gui/exporter/ExportCustomizationDialog.java index a57d686e0f9..24f849ec4f5 100644 --- a/src/main/java/net/sf/jabref/gui/exporter/ExportCustomizationDialog.java +++ b/src/main/java/net/sf/jabref/gui/exporter/ExportCustomizationDialog.java @@ -43,8 +43,10 @@ import net.sf.jabref.gui.keyboard.KeyBinding; import net.sf.jabref.gui.util.FocusRequester; import net.sf.jabref.gui.util.GUIUtil; +import net.sf.jabref.logic.exporter.SavePreferences; import net.sf.jabref.logic.help.HelpFile; import net.sf.jabref.logic.l10n.Localization; +import net.sf.jabref.logic.layout.LayoutFormatterPreferences; import ca.odell.glazedlists.gui.TableFormat; import ca.odell.glazedlists.swing.DefaultEventTableModel; @@ -92,7 +94,9 @@ public ExportCustomizationDialog(final JabRefFrame frame) { ecd.setVisible(true); if (ecd.okPressed()) { List newFormat = Arrays.asList(ecd.name(), ecd.layoutFile(), ecd.extension()); - Globals.prefs.customExports.addFormat(newFormat); + Globals.prefs.customExports.addFormat(newFormat, + LayoutFormatterPreferences.fromPreferences(Globals.prefs, Globals.journalAbbreviationLoader), + SavePreferences.loadForExportFromPreferences(Globals.prefs)); Globals.prefs.customExports.store(Globals.prefs); } }); @@ -126,8 +130,10 @@ public ExportCustomizationDialog(final JabRefFrame frame) { for (int i = 0; i < rows.length; i++) { entries.add(Globals.prefs.customExports.getSortedList().get(rows[i])); } + LayoutFormatterPreferences layoutPreferences = LayoutFormatterPreferences.fromPreferences(Globals.prefs, Globals.journalAbbreviationLoader); + SavePreferences savePreferences = SavePreferences.loadForExportFromPreferences(Globals.prefs); for (List list : entries) { - Globals.prefs.customExports.remove(list); + Globals.prefs.customExports.remove(list, layoutPreferences, savePreferences); } Globals.prefs.customExports.store(Globals.prefs); }); diff --git a/src/main/java/net/sf/jabref/gui/preftabs/PreferencesDialog.java b/src/main/java/net/sf/jabref/gui/preftabs/PreferencesDialog.java index f694ae8136e..0c44774559e 100644 --- a/src/main/java/net/sf/jabref/gui/preftabs/PreferencesDialog.java +++ b/src/main/java/net/sf/jabref/gui/preftabs/PreferencesDialog.java @@ -23,6 +23,7 @@ import java.nio.file.Path; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.prefs.BackingStoreException; @@ -42,8 +43,11 @@ import net.sf.jabref.gui.JabRefFrame; import net.sf.jabref.gui.keyboard.KeyBinder; import net.sf.jabref.gui.maintable.MainTable; +import net.sf.jabref.logic.exporter.ExportFormat; import net.sf.jabref.logic.exporter.ExportFormats; +import net.sf.jabref.logic.exporter.SavePreferences; import net.sf.jabref.logic.l10n.Localization; +import net.sf.jabref.logic.layout.LayoutFormatterPreferences; import net.sf.jabref.logic.util.FileExtensions; import net.sf.jabref.preferences.JabRefPreferences; import net.sf.jabref.preferences.JabRefPreferencesFilter; @@ -228,7 +232,13 @@ public PreferencesDialog(JabRefFrame parent) { private void updateAfterPreferenceChanges() { setValues(); - ExportFormats.initAllExports(Globals.prefs.customExports.getCustomExportFormats(Globals.prefs)); + Map customFormats = Globals.prefs.customExports.getCustomExportFormats(Globals.prefs, + Globals.journalAbbreviationLoader); + LayoutFormatterPreferences layoutPreferences = LayoutFormatterPreferences.fromPreferences(Globals.prefs, + Globals.journalAbbreviationLoader); + SavePreferences savePreferences = SavePreferences.loadForExportFromPreferences(Globals.prefs); + ExportFormats.initAllExports(customFormats, layoutPreferences, savePreferences); + frame.removeCachedEntryEditors(); Globals.prefs.updateEntryEditorTabList(); } diff --git a/src/main/java/net/sf/jabref/logic/exporter/CustomExportList.java b/src/main/java/net/sf/jabref/logic/exporter/CustomExportList.java index 855c41fad37..0aea3d2cf36 100644 --- a/src/main/java/net/sf/jabref/logic/exporter/CustomExportList.java +++ b/src/main/java/net/sf/jabref/logic/exporter/CustomExportList.java @@ -21,6 +21,8 @@ import java.util.Optional; import java.util.TreeMap; +import net.sf.jabref.logic.journals.JournalAbbreviationLoader; +import net.sf.jabref.logic.layout.LayoutFormatterPreferences; import net.sf.jabref.preferences.JabRefPreferences; import ca.odell.glazedlists.BasicEventList; @@ -51,9 +53,10 @@ public CustomExportList(Comparator> comp) { sorted = new SortedList<>(list, comp); } - public Map getCustomExportFormats(JabRefPreferences prefs) { + public Map getCustomExportFormats(JabRefPreferences prefs, + JournalAbbreviationLoader loader) { formats.clear(); - readPrefs(prefs); + readPrefs(prefs, loader); return formats; } @@ -65,13 +68,15 @@ public EventList> getSortedList() { return sorted; } - private void readPrefs(JabRefPreferences prefs) { + private void readPrefs(JabRefPreferences prefs, JournalAbbreviationLoader loader) { formats.clear(); list.clear(); int i = 0; List s; + LayoutFormatterPreferences layoutPreferences = LayoutFormatterPreferences.fromPreferences(prefs, loader); + SavePreferences savePreferences = SavePreferences.loadForExportFromPreferences(prefs); while (!((s = prefs.getStringList(JabRefPreferences.CUSTOM_EXPORT_FORMAT + i)).isEmpty())) { - Optional format = createFormat(s); + Optional format = createFormat(s, layoutPreferences, savePreferences); if (format.isPresent()) { formats.put(format.get().getConsoleName(), format.get()); list.add(s); @@ -83,7 +88,8 @@ private void readPrefs(JabRefPreferences prefs) { } } - private Optional createFormat(List s) { + private Optional createFormat(List s, LayoutFormatterPreferences layoutPreferences, + SavePreferences savePreferences) { if (s.size() < 3) { return Optional.empty(); } @@ -93,20 +99,22 @@ private Optional createFormat(List s) { } else { lfFileName = s.get(1); } - ExportFormat format = new ExportFormat(s.get(0), s.get(0), lfFileName, null, s.get(2)); + ExportFormat format = new ExportFormat(s.get(0), s.get(0), lfFileName, null, s.get(2), layoutPreferences, + savePreferences); format.setCustomExport(true); return Optional.of(format); } - public void addFormat(List s) { - createFormat(s).ifPresent(format -> { + public void addFormat(List s, LayoutFormatterPreferences layoutPreferences, SavePreferences savePreferences) { + createFormat(s, layoutPreferences, savePreferences).ifPresent(format -> { formats.put(format.getConsoleName(), format); list.add(s); }); } - public void remove(List toRemove) { - createFormat(toRemove).ifPresent(format -> { + public void remove(List toRemove, LayoutFormatterPreferences layoutPreferences, + SavePreferences savePreferences) { + createFormat(toRemove, layoutPreferences, savePreferences).ifPresent(format -> { formats.remove(format.getConsoleName()); list.remove(toRemove); }); diff --git a/src/main/java/net/sf/jabref/logic/exporter/ExportFormat.java b/src/main/java/net/sf/jabref/logic/exporter/ExportFormat.java index 013d66205a5..6476926bb83 100644 --- a/src/main/java/net/sf/jabref/logic/exporter/ExportFormat.java +++ b/src/main/java/net/sf/jabref/logic/exporter/ExportFormat.java @@ -53,6 +53,8 @@ public class ExportFormat implements IExportFormat { private String extension; private Charset encoding; // If this value is set, it will be used to override // the default encoding for the getCurrentBasePanel. + private LayoutFormatterPreferences layoutPreferences; + private SavePreferences savePreferences; private boolean customExport; private static final String LAYOUT_PREFIX = "/resource/layout/"; @@ -77,10 +79,29 @@ public ExportFormat(String displayName, String consoleName, String lfFileName, S this.extension = extension; } + /** + * Initialize another export format based on templates stored in dir with + * layoutFile lfFilename. + * + * @param displayName Name to display to the user. + * @param consoleName Name to call this format in the console. + * @param lfFileName Name of the main layout file. + * @param directory Directory in which to find the layout file. + * @param extension Should contain the . (for instance .txt). + * @param layoutPreferences Preferences for layout + * @param savePreferences Preferences for saving + */ + public ExportFormat(String displayName, String consoleName, String lfFileName, String directory, String extension, + LayoutFormatterPreferences layoutPreferences, SavePreferences savePreferences) { + this(displayName, consoleName, lfFileName, directory, extension); + this.layoutPreferences = layoutPreferences; + this.savePreferences = savePreferences; + } + /** * Empty default constructor for subclasses */ - ExportFormat() { + protected ExportFormat() { // intentionally empty } @@ -213,15 +234,14 @@ public void performExport(final BibDatabaseContext databaseContext, final String Layout beginLayout = null; // Check if this export filter has bundled name formatters: - // Set a global field, so all layouts have access to the custom name formatters: - Globals.prefs.customExportNameFormatters = readFormatterFile(lfFileName); + // Add these to the preferences, so all layouts have access to the custom name formatters: + readFormatterFile(); List missingFormatters = new ArrayList<>(1); // Print header try (Reader reader = getReader(lfFileName + ".begin.layout")) { - LayoutHelper layoutHelper = new LayoutHelper(reader, - LayoutFormatterPreferences.fromPreferences(Globals.prefs, Globals.journalAbbreviationLoader)); + LayoutHelper layoutHelper = new LayoutHelper(reader, layoutPreferences); beginLayout = layoutHelper.getLayoutFromText(); } catch (IOException ex) { // If an exception was cast, export filter doesn't have a begin @@ -240,15 +260,13 @@ public void performExport(final BibDatabaseContext databaseContext, final String * be non-null, and be used to choose entries. Otherwise, it will be * null, and be ignored. */ - SavePreferences savePrefs = SavePreferences.loadForExportFromPreferences(Globals.prefs); - List sorted = BibDatabaseWriter.getSortedEntries(databaseContext, entries, savePrefs); + List sorted = BibDatabaseWriter.getSortedEntries(databaseContext, entries, savePreferences); // Load default layout Layout defLayout; LayoutHelper layoutHelper; try (Reader reader = getReader(lfFileName + ".layout")) { - layoutHelper = new LayoutHelper(reader, - LayoutFormatterPreferences.fromPreferences(Globals.prefs, Globals.journalAbbreviationLoader)); + layoutHelper = new LayoutHelper(reader,layoutPreferences); defLayout = layoutHelper.getLayoutFromText(); } if (defLayout != null) { @@ -270,8 +288,7 @@ public void performExport(final BibDatabaseContext databaseContext, final String } else { try (Reader reader = getReader(lfFileName + '.' + type + ".layout")) { // We try to get a type-specific layout for this entry. - layoutHelper = new LayoutHelper(reader, LayoutFormatterPreferences - .fromPreferences(Globals.prefs, Globals.journalAbbreviationLoader)); + layoutHelper = new LayoutHelper(reader, layoutPreferences); layout = layoutHelper.getLayoutFromText(); layouts.put(type, layout); if (layout != null) { @@ -295,8 +312,7 @@ public void performExport(final BibDatabaseContext databaseContext, final String // changed section - begin (arudert) Layout endLayout = null; try (Reader reader = getReader(lfFileName + ".end.layout")) { - layoutHelper = new LayoutHelper(reader, - LayoutFormatterPreferences.fromPreferences(Globals.prefs, Globals.journalAbbreviationLoader)); + layoutHelper = new LayoutHelper(reader, layoutPreferences); endLayout = layoutHelper.getLayoutFromText(); } catch (IOException ex) { // If an exception was thrown, export filter doesn't have an end @@ -310,7 +326,7 @@ public void performExport(final BibDatabaseContext databaseContext, final String } // Clear custom name formatters: - Globals.prefs.customExportNameFormatters = null; + layoutPreferences.getCustomExportNameFormatters().clear(); if (!missingFormatters.isEmpty()) { StringBuilder sb = new StringBuilder("The following formatters could not be found: "); @@ -332,10 +348,8 @@ public void performExport(final BibDatabaseContext databaseContext, Path file, f * See if there is a name formatter file bundled with this export format. If so, read * all the name formatters so they can be used by the filter layouts. * - * @param lfFileName The layout filename. */ - private static Map readFormatterFile(String lfFileName) { - Map formatters = new HashMap<>(); + private void readFormatterFile() { File formatterFile = new File(lfFileName + ".formatters"); if (formatterFile.exists()) { try (Reader in = new FileReader(formatterFile)) { @@ -357,7 +371,7 @@ private static Map readFormatterFile(String lfFileName) { if ((index > 0) && ((index + 1) < line.length())) { String formatterName = line.substring(0, index); String contents = line.substring(index + 1); - formatters.put(formatterName, contents); + layoutPreferences.getCustomExportNameFormatters().put(formatterName, contents); } } @@ -366,7 +380,6 @@ private static Map readFormatterFile(String lfFileName) { LOGGER.warn("Problem opening formatter file.", ex); } } - return formatters; } public void finalizeSaveSession(final SaveSession ss, Path file) throws SaveException, IOException { diff --git a/src/main/java/net/sf/jabref/logic/exporter/ExportFormats.java b/src/main/java/net/sf/jabref/logic/exporter/ExportFormats.java index 94f2a582fa3..813918983fd 100644 --- a/src/main/java/net/sf/jabref/logic/exporter/ExportFormats.java +++ b/src/main/java/net/sf/jabref/logic/exporter/ExportFormats.java @@ -21,6 +21,7 @@ import java.util.TreeMap; import net.sf.jabref.logic.l10n.Localization; +import net.sf.jabref.logic.layout.LayoutFormatterPreferences; public class ExportFormats { @@ -30,34 +31,45 @@ public class ExportFormats { public static int entryNumber; - public static void initAllExports(Map customFormats) { + public static void initAllExports(Map customFormats, + LayoutFormatterPreferences layoutPreferences, SavePreferences savePreferences) { ExportFormats.EXPORT_FORMATS.clear(); // Initialize Build-In Export Formats - ExportFormats.putFormat(new ExportFormat("HTML", "html", "html", null, ".html")); - ExportFormats.putFormat(new ExportFormat(Localization.lang("Simple HTML"), "simplehtml", "simplehtml", null, ".html")); - ExportFormats.putFormat(new ExportFormat("DocBook 4.4", "docbook", "docbook", null, ".xml")); - ExportFormats.putFormat(new ExportFormat("DIN 1505", "din1505", "din1505winword", "din1505", ".rtf")); - ExportFormats.putFormat(new ExportFormat("BibTeXML", "bibtexml", "bibtexml", null, ".xml")); - ExportFormats.putFormat(new ExportFormat("BibO RDF", "bibordf", "bibordf", null, ".rdf")); - ExportFormats.putFormat(new ModsExportFormat()); - ExportFormats.putFormat(new ExportFormat(Localization.lang("HTML table"), "tablerefs", "tablerefs", "tablerefs", ".html")); - ExportFormats.putFormat(new ExportFormat(Localization.lang("HTML list"), - "listrefs", "listrefs", "listrefs", ".html")); + ExportFormats + .putFormat(new ExportFormat("HTML", "html", "html", null, ".html", layoutPreferences, savePreferences)); + ExportFormats.putFormat(new ExportFormat(Localization.lang("Simple HTML"), "simplehtml", "simplehtml", null, + ".html", layoutPreferences, savePreferences)); + ExportFormats.putFormat(new ExportFormat("DocBook 4.4", "docbook", "docbook", null, ".xml", layoutPreferences, + savePreferences)); + ExportFormats.putFormat(new ExportFormat("DIN 1505", "din1505", "din1505winword", "din1505", ".rtf", + layoutPreferences, savePreferences)); + ExportFormats.putFormat( + new ExportFormat("BibTeXML", "bibtexml", "bibtexml", null, ".xml", layoutPreferences, savePreferences)); + ExportFormats.putFormat( + new ExportFormat("BibO RDF", "bibordf", "bibordf", null, ".rdf", layoutPreferences, savePreferences)); + ExportFormats.putFormat(new ExportFormat(Localization.lang("HTML table"), "tablerefs", "tablerefs", "tablerefs", + ".html", layoutPreferences, savePreferences)); + ExportFormats.putFormat(new ExportFormat(Localization.lang("HTML list"), "listrefs", "listrefs", "listrefs", + ".html", layoutPreferences, savePreferences)); ExportFormats.putFormat(new ExportFormat(Localization.lang("HTML table (with Abstract & BibTeX)"), - "tablerefsabsbib", "tablerefsabsbib", "tablerefsabsbib", ".html")); - ExportFormats.putFormat(new ExportFormat("Harvard RTF", "harvard", "harvard", - "harvard", ".rtf")); - ExportFormats.putFormat(new ExportFormat("ISO 690", "iso690rtf", "iso690RTF", "iso690rtf", ".rtf")); - ExportFormats.putFormat(new ExportFormat("ISO 690", "iso690txt", "iso690", "iso690txt", ".txt")); - ExportFormats.putFormat(new ExportFormat("Endnote", "endnote", "EndNote", "endnote", ".txt")); - ExportFormats.putFormat(new ExportFormat("OpenOffice/LibreOffice CSV", "oocsv", "openoffice-csv", - "openoffice", ".csv")); - ExportFormat ef = new ExportFormat("RIS", "ris", "ris", "ris", ".ris"); + "tablerefsabsbib", "tablerefsabsbib", "tablerefsabsbib", ".html", layoutPreferences, savePreferences)); + ExportFormats.putFormat(new ExportFormat("Harvard RTF", "harvard", "harvard", "harvard", ".rtf", + layoutPreferences, savePreferences)); + ExportFormats.putFormat(new ExportFormat("ISO 690", "iso690rtf", "iso690RTF", "iso690rtf", ".rtf", + layoutPreferences, savePreferences)); + ExportFormats.putFormat(new ExportFormat("ISO 690", "iso690txt", "iso690", "iso690txt", ".txt", + layoutPreferences, savePreferences)); + ExportFormats.putFormat(new ExportFormat("Endnote", "endnote", "EndNote", "endnote", ".txt", layoutPreferences, + savePreferences)); + ExportFormats.putFormat(new ExportFormat("OpenOffice/LibreOffice CSV", "oocsv", "openoffice-csv", "openoffice", + ".csv", layoutPreferences, savePreferences)); + ExportFormat ef = new ExportFormat("RIS", "ris", "ris", "ris", ".ris", layoutPreferences, savePreferences); ef.setEncoding(StandardCharsets.UTF_8); ExportFormats.putFormat(ef); - ExportFormats.putFormat(new ExportFormat("MIS Quarterly", "misq", "misq", "misq", ".rtf")); + ExportFormats.putFormat( + new ExportFormat("MIS Quarterly", "misq", "misq", "misq", ".rtf", layoutPreferences, savePreferences)); ExportFormats.putFormat(new OpenOfficeDocumentCreator()); ExportFormats.putFormat(new OpenDocumentSpreadsheetCreator()); @@ -80,8 +92,7 @@ public static void initAllExports(Map customFormats) { * beginning of the next line. * @return The string describing available formats. */ - public static String getConsoleExportList(int maxLineLength, int firstLineSubtr, - String linePrefix) { + public static String getConsoleExportList(int maxLineLength, int firstLineSubtr, String linePrefix) { StringBuilder sb = new StringBuilder(); int lastBreak = -firstLineSubtr; @@ -120,7 +131,6 @@ public static IExportFormat getExportFormat(String consoleName) { return ExportFormats.EXPORT_FORMATS.get(consoleName); } - private static void putFormat(IExportFormat format) { ExportFormats.EXPORT_FORMATS.put(format.getConsoleName(), format); } diff --git a/src/main/java/net/sf/jabref/logic/layout/LayoutEntry.java b/src/main/java/net/sf/jabref/logic/layout/LayoutEntry.java index c6245dcc9b9..2d5c981e1ba 100644 --- a/src/main/java/net/sf/jabref/logic/layout/LayoutEntry.java +++ b/src/main/java/net/sf/jabref/logic/layout/LayoutEntry.java @@ -585,7 +585,7 @@ private List getOptionalLayout(String formatterName) { String className = strings.get(0).trim(); // Check if this is a name formatter defined by this export filter: - if (prefs.getCustomExportNameFormatters() != null) { + if (!prefs.getCustomExportNameFormatters().isEmpty()) { String contents = prefs.getCustomExportNameFormatters().get(className); if (contents != null) { NameFormatter nf = new NameFormatter(); diff --git a/src/main/java/net/sf/jabref/logic/layout/LayoutFormatterPreferences.java b/src/main/java/net/sf/jabref/logic/layout/LayoutFormatterPreferences.java index 76fd6cc9900..c0ecaa967d5 100644 --- a/src/main/java/net/sf/jabref/logic/layout/LayoutFormatterPreferences.java +++ b/src/main/java/net/sf/jabref/logic/layout/LayoutFormatterPreferences.java @@ -1,5 +1,6 @@ package net.sf.jabref.logic.layout; +import java.util.HashMap; import java.util.Map; import java.util.Objects; @@ -14,15 +15,14 @@ public class LayoutFormatterPreferences { private final NameFormatterPreferences nameFormatterPreferences; private final JournalAbbreviationPreferences journalAbbreviationPreferences; private final FileLinkPreferences fileLinkPreferences; - private final Map customExportNameFormatters; + private final Map customExportNameFormatters = new HashMap<>(); private final JournalAbbreviationLoader journalAbbreviationLoader; public LayoutFormatterPreferences(NameFormatterPreferences nameFormatterPreferences, JournalAbbreviationPreferences journalAbbreviationPreferences, FileLinkPreferences fileLinkPreferences, - Map customExportNameFormatters, JournalAbbreviationLoader journalAbbreviationLoader) { + JournalAbbreviationLoader journalAbbreviationLoader) { this.nameFormatterPreferences = nameFormatterPreferences; this.journalAbbreviationPreferences = journalAbbreviationPreferences; - this.customExportNameFormatters = customExportNameFormatters; this.fileLinkPreferences = fileLinkPreferences; this.journalAbbreviationLoader = journalAbbreviationLoader; } @@ -34,7 +34,7 @@ public static LayoutFormatterPreferences fromPreferences(JabRefPreferences jabRe return new LayoutFormatterPreferences(NameFormatterPreferences.fromPreferences(jabRefPreferences), JournalAbbreviationPreferences.fromPreferences(jabRefPreferences), FileLinkPreferences.fromPreferences(jabRefPreferences), - jabRefPreferences.customExportNameFormatters, journalAbbreviationLoader); + journalAbbreviationLoader); } public NameFormatterPreferences getNameFormatterPreferences() { diff --git a/src/main/java/net/sf/jabref/preferences/JabRefPreferences.java b/src/main/java/net/sf/jabref/preferences/JabRefPreferences.java index 5b68b26774f..d779a93ddf3 100644 --- a/src/main/java/net/sf/jabref/preferences/JabRefPreferences.java +++ b/src/main/java/net/sf/jabref/preferences/JabRefPreferences.java @@ -454,10 +454,6 @@ public class JabRefPreferences { // string to be formatted and possible formatter arguments. public List fileDirForDatabase; - // The following field is used as a global variable during the export of a database. - // It is used to hold custom name formatters defined by a custom export filter. - // It is set before the export starts: - public Map customExportNameFormatters; // The only instance of this class: private static JabRefPreferences singleton; diff --git a/src/test/java/net/sf/jabref/logic/exporter/ExportFormatTest.java b/src/test/java/net/sf/jabref/logic/exporter/ExportFormatTest.java index 364df725d93..9a531b78fab 100644 --- a/src/test/java/net/sf/jabref/logic/exporter/ExportFormatTest.java +++ b/src/test/java/net/sf/jabref/logic/exporter/ExportFormatTest.java @@ -7,10 +7,12 @@ import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Map; import net.sf.jabref.BibDatabaseContext; import net.sf.jabref.Globals; import net.sf.jabref.logic.journals.JournalAbbreviationLoader; +import net.sf.jabref.logic.layout.LayoutFormatterPreferences; import net.sf.jabref.model.entry.BibEntry; import net.sf.jabref.preferences.JabRefPreferences; @@ -44,7 +46,6 @@ public ExportFormatTest(IExportFormat format, String name) { @Before public void setUp() { - Globals.journalAbbreviationLoader = new JournalAbbreviationLoader(); databaseContext = new BibDatabaseContext(); charset = Charsets.UTF_8; entries = Collections.emptyList(); @@ -76,7 +77,15 @@ public void testExportingNullEntriesThrowsNPE() throws Exception { public static Collection exportFormats() { Collection result = new ArrayList<>(); Globals.prefs = JabRefPreferences.getInstance(); - ExportFormats.initAllExports(Globals.prefs.customExports.getCustomExportFormats(Globals.prefs)); + JournalAbbreviationLoader journalAbbreviationLoader = new JournalAbbreviationLoader(); + + Map customFormats = Globals.prefs.customExports.getCustomExportFormats(Globals.prefs, + journalAbbreviationLoader); + LayoutFormatterPreferences layoutPreferences = LayoutFormatterPreferences.fromPreferences(Globals.prefs, + journalAbbreviationLoader); + SavePreferences savePreferences = SavePreferences.loadForExportFromPreferences(Globals.prefs); + ExportFormats.initAllExports(customFormats, layoutPreferences, savePreferences); + for (IExportFormat format : ExportFormats.getExportFormats().values()) { result.add(new Object[] {format, format.getDisplayName()}); } diff --git a/src/test/java/net/sf/jabref/logic/exporter/HtmlExportFormatTest.java b/src/test/java/net/sf/jabref/logic/exporter/HtmlExportFormatTest.java index 7e69b96b7f9..3e56fc58409 100644 --- a/src/test/java/net/sf/jabref/logic/exporter/HtmlExportFormatTest.java +++ b/src/test/java/net/sf/jabref/logic/exporter/HtmlExportFormatTest.java @@ -5,10 +5,12 @@ import java.nio.file.Files; import java.util.Arrays; import java.util.List; +import java.util.Map; import net.sf.jabref.BibDatabaseContext; import net.sf.jabref.Globals; import net.sf.jabref.logic.journals.JournalAbbreviationLoader; +import net.sf.jabref.logic.layout.LayoutFormatterPreferences; import net.sf.jabref.model.entry.BibEntry; import net.sf.jabref.preferences.JabRefPreferences; @@ -33,10 +35,16 @@ public class HtmlExportFormatTest { @Before public void setUp() { Globals.prefs = JabRefPreferences.getInstance(); - ExportFormats.initAllExports(Globals.prefs.customExports.getCustomExportFormats(Globals.prefs)); + JournalAbbreviationLoader journalAbbreviationLoader = new JournalAbbreviationLoader(); + Map customFormats = Globals.prefs.customExports.getCustomExportFormats(Globals.prefs, + journalAbbreviationLoader); + LayoutFormatterPreferences layoutPreferences = LayoutFormatterPreferences.fromPreferences(Globals.prefs, + journalAbbreviationLoader); + SavePreferences savePreferences = SavePreferences.loadForExportFromPreferences(Globals.prefs); + ExportFormats.initAllExports(customFormats, layoutPreferences, savePreferences); + exportFormat = ExportFormats.getExportFormat("html"); - Globals.journalAbbreviationLoader = new JournalAbbreviationLoader(); databaseContext = new BibDatabaseContext(); charset = Charsets.UTF_8; BibEntry entry = new BibEntry(); From 0c16669dbc7d572b022f606d7da953e87814c37e Mon Sep 17 00:00:00 2001 From: Admir Obralija Date: Thu, 18 Aug 2016 22:59:14 +0200 Subject: [PATCH 06/14] Add isPresentLocalBibEntry (#1777) --- src/main/java/net/sf/jabref/shared/DBMSSynchronizer.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/sf/jabref/shared/DBMSSynchronizer.java b/src/main/java/net/sf/jabref/shared/DBMSSynchronizer.java index 6ed23a8ce17..daefebf4669 100644 --- a/src/main/java/net/sf/jabref/shared/DBMSSynchronizer.java +++ b/src/main/java/net/sf/jabref/shared/DBMSSynchronizer.java @@ -94,7 +94,7 @@ public void listen(EntryAddedEvent event) { public void listen(FieldChangedEvent event) { // While synchronizing the local database (see synchronizeLocalDatabase() below), some EntryEvents may be posted. // In this case DBSynchronizer should not try to update the bibEntry entry again (but it would not harm). - if (isEventSourceAccepted(event) && checkCurrentConnection()) { + if (isPresentLocalBibEntry(event.getBibEntry()) && isEventSourceAccepted(event) && checkCurrentConnection()) { synchronizeLocalMetaData(); BibEntry bibEntry = event.getBibEntry(); synchronizeSharedEntry(bibEntry); @@ -348,6 +348,10 @@ public void openSharedDatabase(DBMSConnectionProperties properties) throws Class openSharedDatabase(DBMSConnector.getNewConnection(properties), properties.getType(), properties.getDatabase()); } + private boolean isPresentLocalBibEntry(BibEntry bibEntry) { + return bibDatabase.getEntries().contains(bibEntry); + } + public String getDBName() { return dbName; } From 63c9fff787ecc01ba4b5bfe9c6b4aa8ce6cf83f9 Mon Sep 17 00:00:00 2001 From: Oscar Gustafsson Date: Thu, 18 Aug 2016 23:20:02 +0200 Subject: [PATCH 07/14] Fixed startup problem --- src/main/java/net/sf/jabref/JabRefMain.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/sf/jabref/JabRefMain.java b/src/main/java/net/sf/jabref/JabRefMain.java index 93764994f47..42e9b0f947a 100644 --- a/src/main/java/net/sf/jabref/JabRefMain.java +++ b/src/main/java/net/sf/jabref/JabRefMain.java @@ -78,6 +78,9 @@ private static void start(String[] args) { // Update which fields should be treated as numeric, based on preferences: InternalBibtexFields.setNumericFields(Globals.prefs.getStringList(JabRefPreferences.NUMERIC_FIELDS)); + // Read list(s) of journal names and abbreviations + Globals.journalAbbreviationLoader = new JournalAbbreviationLoader(); + /* Build list of Import and Export formats */ Globals.IMPORT_FORMAT_READER.resetImportFormats(ImportFormatPreferences.fromPreferences(Globals.prefs), XMPPreferences.fromPreferences(Globals.prefs)); @@ -89,9 +92,6 @@ private static void start(String[] args) { SavePreferences savePreferences = SavePreferences.loadForExportFromPreferences(Globals.prefs); ExportFormats.initAllExports(customFormats, layoutPreferences, savePreferences); - // Read list(s) of journal names and abbreviations - Globals.journalAbbreviationLoader = new JournalAbbreviationLoader(); - // Initialize protected terms loader Globals.protectedTermsLoader = new ProtectedTermsLoader( ProtectedTermsPreferences.fromPreferences(Globals.prefs)); From 43a4ee231e843a457f0a5cb367f0474b901cf9ef Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Thu, 18 Aug 2016 23:24:18 +0200 Subject: [PATCH 08/14] Add some more Objects.requireNonNull checks --- .../java/net/sf/jabref/logic/exporter/CustomExportList.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/net/sf/jabref/logic/exporter/CustomExportList.java b/src/main/java/net/sf/jabref/logic/exporter/CustomExportList.java index 0aea3d2cf36..fb41935d2d3 100644 --- a/src/main/java/net/sf/jabref/logic/exporter/CustomExportList.java +++ b/src/main/java/net/sf/jabref/logic/exporter/CustomExportList.java @@ -18,6 +18,7 @@ import java.util.Comparator; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.TreeMap; @@ -55,6 +56,8 @@ public CustomExportList(Comparator> comp) { public Map getCustomExportFormats(JabRefPreferences prefs, JournalAbbreviationLoader loader) { + Objects.requireNonNull(prefs); + Objects.requireNonNull(loader); formats.clear(); readPrefs(prefs, loader); return formats; @@ -69,6 +72,8 @@ public EventList> getSortedList() { } private void readPrefs(JabRefPreferences prefs, JournalAbbreviationLoader loader) { + Objects.requireNonNull(prefs); + Objects.requireNonNull(loader); formats.clear(); list.clear(); int i = 0; From fc0129e0f89ee9d3143f6ea7f21a895f4397696e Mon Sep 17 00:00:00 2001 From: Sascha Zeller Date: Fri, 19 Aug 2016 05:04:50 +0200 Subject: [PATCH 09/14] GvkFetcher (#1656) * implement gvk fetcher * make fetcher usable * refactor gvk parser * fix codacy and refactor test ressources * use entryfetcher wrapper * First Version of GVKFetcher using URIBuilder * begin tests * edit exceptions * resolve conflicts * improve tests * include feedback * use foreach loop * cleanup and additional test * include internal feedback * include feedback and add copyright * remove globals.prefs in test --- .../gui/importer/fetcher/EntryFetchers.java | 4 +- .../gui/importer/fetcher/GVKFetcher.java | 184 ------------------ .../gui/importer/fetcher/GeneralFetcher.java | 27 +-- .../importer/{util => fetcher}/GVKParser.java | 10 +- .../logic/importer/fetcher/GvkFetcher.java | 123 ++++++++++++ .../{util => fetcher}/GVKParserTest.java | 2 +- .../importer/fetcher/GvkFetcherTest.java | 119 +++++++++++ .../gvk_artificial_subtitle_test.xml | 0 .../gvk_empty_result_becaue_of_bad_query.xml | 0 .../importer/{util => fetcher}/gvk_gmp.1.bib | 0 .../importer/{util => fetcher}/gvk_gmp.2.bib | 0 .../importer/{util => fetcher}/gvk_gmp.xml | 0 .../gvk_result_for_797485368.bib | 0 .../gvk_result_for_797485368.xml | 0 14 files changed, 251 insertions(+), 218 deletions(-) delete mode 100644 src/main/java/net/sf/jabref/gui/importer/fetcher/GVKFetcher.java rename src/main/java/net/sf/jabref/logic/importer/{util => fetcher}/GVKParser.java (98%) create mode 100644 src/main/java/net/sf/jabref/logic/importer/fetcher/GvkFetcher.java rename src/test/java/net/sf/jabref/logic/importer/{util => fetcher}/GVKParserTest.java (98%) create mode 100644 src/test/java/net/sf/jabref/logic/importer/fetcher/GvkFetcherTest.java rename src/test/resources/net/sf/jabref/logic/importer/{util => fetcher}/gvk_artificial_subtitle_test.xml (100%) rename src/test/resources/net/sf/jabref/logic/importer/{util => fetcher}/gvk_empty_result_becaue_of_bad_query.xml (100%) rename src/test/resources/net/sf/jabref/logic/importer/{util => fetcher}/gvk_gmp.1.bib (100%) rename src/test/resources/net/sf/jabref/logic/importer/{util => fetcher}/gvk_gmp.2.bib (100%) rename src/test/resources/net/sf/jabref/logic/importer/{util => fetcher}/gvk_gmp.xml (100%) rename src/test/resources/net/sf/jabref/logic/importer/{util => fetcher}/gvk_result_for_797485368.bib (100%) rename src/test/resources/net/sf/jabref/logic/importer/{util => fetcher}/gvk_result_for_797485368.xml (100%) diff --git a/src/main/java/net/sf/jabref/gui/importer/fetcher/EntryFetchers.java b/src/main/java/net/sf/jabref/gui/importer/fetcher/EntryFetchers.java index ffa805e166f..9a274d9054f 100644 --- a/src/main/java/net/sf/jabref/gui/importer/fetcher/EntryFetchers.java +++ b/src/main/java/net/sf/jabref/gui/importer/fetcher/EntryFetchers.java @@ -20,6 +20,7 @@ import java.util.List; import net.sf.jabref.logic.importer.fetcher.ArXiv; +import net.sf.jabref.logic.importer.fetcher.GvkFetcher; import net.sf.jabref.logic.journals.JournalAbbreviationLoader; public class EntryFetchers { @@ -33,7 +34,6 @@ public EntryFetchers(JournalAbbreviationLoader abbreviationLoader) { entryFetchers.add(new DBLPFetcher()); entryFetchers.add(new DiVAtoBibTeXFetcher()); entryFetchers.add(new DOItoBibTeXFetcher()); - entryFetchers.add(new GVKFetcher()); entryFetchers.add(new IEEEXploreFetcher(abbreviationLoader)); entryFetchers.add(new INSPIREFetcher()); entryFetchers.add(new ISBNtoBibTeXFetcher()); @@ -44,7 +44,9 @@ public EntryFetchers(JournalAbbreviationLoader abbreviationLoader) { entryFetchers.add(new GoogleScholarFetcher()); entryFetchers.add(new DOAJFetcher()); entryFetchers.add(new SpringerFetcher()); + entryFetchers.add(new SearchBasedEntryFetcher(new ArXiv())); + entryFetchers.add(new SearchBasedEntryFetcher(new GvkFetcher())); } public List getEntryFetchers() { diff --git a/src/main/java/net/sf/jabref/gui/importer/fetcher/GVKFetcher.java b/src/main/java/net/sf/jabref/gui/importer/fetcher/GVKFetcher.java deleted file mode 100644 index fef8b7a4ef2..00000000000 --- a/src/main/java/net/sf/jabref/gui/importer/fetcher/GVKFetcher.java +++ /dev/null @@ -1,184 +0,0 @@ -/** - * License: GPLv2, but Jan Frederik Maas agreed to change license upon request - */ -package net.sf.jabref.gui.importer.fetcher; - -import java.io.IOException; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.swing.JPanel; -import javax.xml.parsers.ParserConfigurationException; - -import net.sf.jabref.logic.help.HelpFile; -import net.sf.jabref.logic.importer.ImportInspector; -import net.sf.jabref.logic.importer.OutputPrinter; -import net.sf.jabref.logic.importer.util.GVKParser; -import net.sf.jabref.logic.l10n.Localization; -import net.sf.jabref.model.entry.BibEntry; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.xml.sax.SAXException; - -/** - * Fetch or search from GVK http://gso.gbv.de/sru/DB=2.1/ - */ -public class GVKFetcher implements EntryFetcher { - - private static final Log LOGGER = LogFactory.getLog(GVKFetcher.class); - - private final Map searchKeys = new HashMap<>(); - - - public GVKFetcher() { - searchKeys.put("all", "pica.all%3D"); - searchKeys.put("tit", "pica.tit%3D"); - searchKeys.put("per", "pica.per%3D"); - searchKeys.put("thm", "pica.thm%3D"); - searchKeys.put("slw", "pica.slw%3D"); - searchKeys.put("txt", "pica.txt%3D"); - searchKeys.put("num", "pica.num%3D"); - searchKeys.put("kon", "pica.kon%3D"); - searchKeys.put("ppn", "pica.ppn%3D"); - searchKeys.put("bkl", "pica.bkl%3D"); - searchKeys.put("erj", "pica.erj%3D"); - } - - /** - * Necessary for JabRef - */ - @Override - public void stopFetching() { - // not supported - } - - @Override - public HelpFile getHelpPage() { - return HelpFile.FETCHER_GVK; - } - - @Override - public JPanel getOptionsPanel() { - return null; - } - - @Override - public String getTitle() { - return "GVK (Gemeinsamer Verbundkatalog)"; - } - - @Override - public boolean processQuery(String query, ImportInspector dialog, OutputPrinter frame) { - - query = query.trim(); - - String[] qterms = query.split("\\s"); - - // Null abfangen! - if (qterms.length == 0) { - return false; - } - - // Jeden einzelnen Suchbegriff URL-Encodieren - for (int x = 0; x < qterms.length; x++) { - try { - qterms[x] = URLEncoder.encode(qterms[x], StandardCharsets.UTF_8.name()); - } catch (UnsupportedEncodingException e) { - LOGGER.error("Unsupported encoding", e); - } - } - - String gvkQuery; - if (searchKeys.containsKey(qterms[0])) { - gvkQuery = processComplexQuery(qterms); - } else { - gvkQuery = "pica.all%3D"; - gvkQuery = gvkQuery.concat(qterms[0]); - - for (int x = 1; x < qterms.length; x++) { - gvkQuery = gvkQuery.concat("%20"); - gvkQuery = gvkQuery.concat(qterms[x]); - } - } - - List bibs = fetchGVK(gvkQuery); - - for (BibEntry entry : bibs) { - dialog.addEntry(entry); - } - - if (bibs.isEmpty()) { - frame.showMessage(Localization.lang("No references found")); - } - - return true; - } - - private String processComplexQuery(String[] s) { - String result = ""; - boolean lastWasKey = false; - - for (int x = 0; x < s.length; x++) { - if (searchKeys.containsKey(s[x])) { - if (x == 0) { - result = searchKeys.get(s[x]); - } else { - result = result.concat("%20and%20" + searchKeys.get(s[x])); - } - lastWasKey = true; - } else { - if (!lastWasKey) { - result = result.concat("%20"); - } - String encoded = s[x]; - encoded = encoded.replace(",", "%2C").replace("?", "%3F"); - - result = result.concat(encoded); - lastWasKey = false; - } - } - return result; - } - - private List fetchGVK(String query) { - List result; - - String urlPrefix = "http://sru.gbv.de/gvk?version=1.1&operation=searchRetrieve&query="; - String urlSuffix = "&maximumRecords=50&recordSchema=picaxml&sortKeys=Year%2C%2C1"; - - String searchstring = urlPrefix + query + urlSuffix; - LOGGER.debug(searchstring); - try { - URI uri = new URI(searchstring); - URL url = uri.toURL(); - try (InputStream is = url.openStream()) { - result = (new GVKParser()).parseEntries(is); - } - } catch (URISyntaxException e) { - LOGGER.error("URI malformed error", e); - return Collections.emptyList(); - } catch (IOException e) { - LOGGER.error("GVK: An I/O exception occurred", e); - return Collections.emptyList(); - } catch (ParserConfigurationException e) { - LOGGER.error("GVK: An internal parser error occurred", e); - return Collections.emptyList(); - } catch (SAXException e) { - LOGGER.error("An internal parser error occurred", e); - return Collections.emptyList(); - } - - return result; - } - -} diff --git a/src/main/java/net/sf/jabref/gui/importer/fetcher/GeneralFetcher.java b/src/main/java/net/sf/jabref/gui/importer/fetcher/GeneralFetcher.java index 7cc9bb8ed27..58f260fed95 100644 --- a/src/main/java/net/sf/jabref/gui/importer/fetcher/GeneralFetcher.java +++ b/src/main/java/net/sf/jabref/gui/importer/fetcher/GeneralFetcher.java @@ -77,12 +77,6 @@ public GeneralFetcher(SidePaneManager p0, JabRefFrame frame) { String[] choices = new String[fetcherArray.length]; for (int i = 0; i < fetcherArray.length; i++) { choices[i] = fetcherArray[i].getTitle(); - //choices[i] = new JLabel(fetchers.get(i).getTitle(), new ImageIcon(fetchers.get(i).getIcon()), - // JLabel.HORIZONTAL); - /*if (fetchers.get(i).getOptionsPanel() != null) - optionsPanel.add(fetchers.get(i).getOptionsPanel(), String.valueOf(i)); - else - optionsPanel.add(new JPanel(), String.valueOf(i));*/ } JComboBox fetcherChoice = new JComboBox<>(choices); int defaultFetcher = Globals.prefs.getInt(JabRefPreferences.SELECTED_FETCHER_INDEX); @@ -97,26 +91,7 @@ public GeneralFetcher(SidePaneManager p0, JabRefFrame frame) { HelpAction help = new HelpAction(activeFetcher.getHelpPage()); JButton helpBut = help.getHelpButton(); helpBut.setEnabled(activeFetcher.getHelpPage() != null); - - //optionsCards.show(optionsPanel, String.valueOf(defaultFetcher)); - - /*fetcherChoice.setRenderer(new ListCellRenderer() { - JLabel label = new JLabel(); - public Component getListCellRendererComponent(JList jList, Object o, int i, boolean isSelected, - boolean cellHasFocus) { - JLabel theLab = (JLabel)o; - label.setIcon(theLab.getIcon()); - label.setText(theLab.getText()); - if (cellHasFocus) { - label.setBackground(UIManager.getDefaults().getColor("ComboBox.selectionBackground").darker()); - label.setForeground(UIManager.getDefaults().getColor("ComboBox.foreground")); - } else { - label.setBackground(UIManager.getDefaults().getColor("ComboBox.background")); - label.setForeground(UIManager.getDefaults().getColor("ComboBox.foreground")); - } - return label; - } - });*/ + fetcherChoice.addActionListener(actionEvent -> { activeFetcher = fetcherArray[fetcherChoice.getSelectedIndex()]; Globals.prefs.putInt(JabRefPreferences.SELECTED_FETCHER_INDEX, fetcherChoice.getSelectedIndex()); diff --git a/src/main/java/net/sf/jabref/logic/importer/util/GVKParser.java b/src/main/java/net/sf/jabref/logic/importer/fetcher/GVKParser.java similarity index 98% rename from src/main/java/net/sf/jabref/logic/importer/util/GVKParser.java rename to src/main/java/net/sf/jabref/logic/importer/fetcher/GVKParser.java index 940e87b78ab..da64703e46e 100644 --- a/src/main/java/net/sf/jabref/logic/importer/util/GVKParser.java +++ b/src/main/java/net/sf/jabref/logic/importer/fetcher/GVKParser.java @@ -1,7 +1,7 @@ /** * License: GPLv2, but Jan Frederik Maas agreed to change license upon request */ -package net.sf.jabref.logic.importer.util; +package net.sf.jabref.logic.importer.fetcher; import java.io.IOException; import java.io.InputStream; @@ -25,17 +25,17 @@ import org.w3c.dom.NodeList; import org.xml.sax.SAXException; -public class GVKParser { +class GVKParser { private static final Log LOGGER = LogFactory.getLog(GVKParser.class); - public List parseEntries(InputStream is) + List parseEntries(InputStream is) throws ParserConfigurationException, SAXException, IOException { DocumentBuilder dbuild = DocumentBuilderFactory.newInstance().newDocumentBuilder(); Document content = dbuild.parse(is); return this.parseEntries(content); } - public List parseEntries(Document content) { + List parseEntries(Document content) { List result = new LinkedList<>(); // used for creating test cases @@ -186,8 +186,6 @@ private BibEntry parseEntry(Element e) { if (title.startsWith("@")) { // "@" indicates a number title = title.substring(1); - } else { - // we nevertheless keep the old title data } number = title; } diff --git a/src/main/java/net/sf/jabref/logic/importer/fetcher/GvkFetcher.java b/src/main/java/net/sf/jabref/logic/importer/fetcher/GvkFetcher.java new file mode 100644 index 00000000000..7e7e7db1233 --- /dev/null +++ b/src/main/java/net/sf/jabref/logic/importer/fetcher/GvkFetcher.java @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2003-2016 JabRef contributors. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +package net.sf.jabref.logic.importer.fetcher; + +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +import javax.xml.parsers.ParserConfigurationException; + +import net.sf.jabref.logic.help.HelpFile; +import net.sf.jabref.logic.importer.FetcherException; +import net.sf.jabref.logic.importer.SearchBasedFetcher; +import net.sf.jabref.model.entry.BibEntry; + +import org.apache.http.client.utils.URIBuilder; +import org.jsoup.helper.StringUtil; +import org.xml.sax.SAXException; + +public class GvkFetcher implements SearchBasedFetcher { + + private static final String URL_PATTERN = "http://sru.gbv.de/gvk?"; + + /** + * Searchkeys are used to specify a search request. For example "tit" stands for "title". + * If no searchkey is used, the default searchkey "all" is used. + */ + private final Collection searchKeys = Arrays.asList("all", "tit", "per", "thm", "slw", "txt", "num", "kon", "ppn", "bkl", "erj"); + + @Override + public String getName() { + return "GVK"; + } + + @Override + public HelpFile getHelpPage() { + return HelpFile.FETCHER_GVK; + } + + private String getSearchQueryStringForComplexQuery(List queryList) throws FetcherException { + String query = ""; + boolean lastWasNoKey = false; + + for (String key : queryList) { + if (searchKeys.contains(key)) { + if (lastWasNoKey) { + query = query + "and "; + } + query = query + "pica." + key + "="; + } else { + query = query + key + " "; + lastWasNoKey = true; + } + } + return query.trim(); + } + + protected String getSearchQueryString(String query) throws FetcherException { + Objects.requireNonNull(query); + LinkedList queryList = new LinkedList(Arrays.asList(query.split("\\s"))); + + if (searchKeys.contains(queryList.get(0))) { + return getSearchQueryStringForComplexQuery(queryList); + } else { + // query as pica.all + return queryList.stream().collect(Collectors.joining(" ", "pica.all=", "")); + } + } + + protected URL getQueryURL(String query) throws URISyntaxException, MalformedURLException, FetcherException { + String gvkQuery = getSearchQueryString(query); + URIBuilder uriBuilder = new URIBuilder(URL_PATTERN); + uriBuilder.addParameter("version", "1.1"); + uriBuilder.addParameter("operation", "searchRetrieve"); + uriBuilder.addParameter("query", gvkQuery); + uriBuilder.addParameter("maximumRecords", "50"); + uriBuilder.addParameter("recordSchema", "picaxml"); + uriBuilder.addParameter("sortKeys", "Year,,1"); + return uriBuilder.build().toURL(); + } + + + @Override + public List performSearch(String query) throws FetcherException { + if (StringUtil.isBlank(query)) { + return Collections.emptyList(); + } + + try (InputStream is = getQueryURL(query).openStream()) { + return (new GVKParser()).parseEntries(is); + } catch (URISyntaxException e) { + throw new FetcherException("URI malformed error", e); + } catch (IOException e) { + throw new FetcherException("An I/O exception occurred", e); + } catch (SAXException | ParserConfigurationException e) { + throw new FetcherException("An internal parser error occurred", e); + } + } +} diff --git a/src/test/java/net/sf/jabref/logic/importer/util/GVKParserTest.java b/src/test/java/net/sf/jabref/logic/importer/fetcher/GVKParserTest.java similarity index 98% rename from src/test/java/net/sf/jabref/logic/importer/util/GVKParserTest.java rename to src/test/java/net/sf/jabref/logic/importer/fetcher/GVKParserTest.java index 9e12ee02d6c..6d30fa27d1a 100644 --- a/src/test/java/net/sf/jabref/logic/importer/util/GVKParserTest.java +++ b/src/test/java/net/sf/jabref/logic/importer/fetcher/GVKParserTest.java @@ -1,4 +1,4 @@ -package net.sf.jabref.logic.importer.util; +package net.sf.jabref.logic.importer.fetcher; import java.io.IOException; import java.io.InputStream; diff --git a/src/test/java/net/sf/jabref/logic/importer/fetcher/GvkFetcherTest.java b/src/test/java/net/sf/jabref/logic/importer/fetcher/GvkFetcherTest.java new file mode 100644 index 00000000000..285b9cee6af --- /dev/null +++ b/src/test/java/net/sf/jabref/logic/importer/fetcher/GvkFetcherTest.java @@ -0,0 +1,119 @@ +package net.sf.jabref.logic.importer.fetcher; + +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.Collections; +import java.util.List; + +import net.sf.jabref.logic.importer.FetcherException; +import net.sf.jabref.model.entry.BibEntry; +import net.sf.jabref.model.entry.BibLatexEntryTypes; + +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class GvkFetcherTest { + + private GvkFetcher fetcher; + private BibEntry bibEntryPPN591166003; + private BibEntry bibEntryPPN66391437X; + + @Before + public void setUp() { + fetcher = new GvkFetcher(); + + bibEntryPPN591166003 = new BibEntry(); + bibEntryPPN591166003.setType(BibLatexEntryTypes.BOOK); + bibEntryPPN591166003.setField("title", "Effective Java"); + bibEntryPPN591166003.setField("publisher", "Addison-Wesley"); + bibEntryPPN591166003.setField("year", "2008"); + bibEntryPPN591166003.setField("author", "Joshua Bloch"); + bibEntryPPN591166003.setField("series", "The @Java series"); + bibEntryPPN591166003.setField("address", "Upper Saddle River, NJ [u.a.]"); + bibEntryPPN591166003.setField("edition", "2. ed., 5. print."); + bibEntryPPN591166003.setField("note", "Literaturverz. S. 321 - 325"); + bibEntryPPN591166003.setField("isbn", "9780321356680"); + bibEntryPPN591166003.setField("pagetotal", "XXI, 346"); + bibEntryPPN591166003.setField("ppn_gvk", "591166003"); + bibEntryPPN591166003.setField("subtitle", "[revised and updated for JAVA SE 6]"); + + bibEntryPPN66391437X = new BibEntry(); + bibEntryPPN66391437X.setType(BibLatexEntryTypes.BOOK); + bibEntryPPN66391437X.setField("title", "Effective unit testing"); + bibEntryPPN66391437X.setField("publisher", "Manning"); + bibEntryPPN66391437X.setField("year", "2013"); + bibEntryPPN66391437X.setField("author", "Lasse Koskela"); + bibEntryPPN66391437X.setField("address", "Shelter Island, NY"); + bibEntryPPN66391437X.setField("isbn", "9781935182573"); + bibEntryPPN66391437X.setField("pagetotal", "XXIV, 223"); + bibEntryPPN66391437X.setField("ppn_gvk", "66391437X"); + bibEntryPPN66391437X.setField("subtitle", "A guide for Java developers"); + } + + @Test + public void testGetName() { + assertEquals("GVK", fetcher.getName()); + } + + @Test + public void testGetHelpPage() { + assertEquals("GVKHelp", fetcher.getHelpPage().getPageName()); + } + + @Test + public void simpleSearchQueryStringCorrect() throws FetcherException { + String query = "java jdk"; + String result = fetcher.getSearchQueryString(query); + assertEquals("pica.all=java jdk", result); + } + + @Test + public void simpleSearchQueryURLCorrect() throws MalformedURLException, URISyntaxException, FetcherException { + String query = "java jdk"; + URL url = fetcher.getQueryURL(query); + assertEquals("http://sru.gbv.de/gvk?version=1.1&operation=searchRetrieve&query=pica.all%3Djava+jdk&maximumRecords=50&recordSchema=picaxml&sortKeys=Year%2C%2C1", url.toString()); + } + + @Test + public void complexSearchQueryStringCorrect() throws FetcherException { + String query = "kon java tit jdk"; + String result = fetcher.getSearchQueryString(query); + assertEquals("pica.kon=java and pica.tit=jdk", result); + } + + @Test + public void complexSearchQueryURLCorrect() throws MalformedURLException, URISyntaxException, FetcherException { + String query = "kon java tit jdk"; + URL url = fetcher.getQueryURL(query); + assertEquals("http://sru.gbv.de/gvk?version=1.1&operation=searchRetrieve&query=pica.kon%3Djava+and+pica.tit%3Djdk&maximumRecords=50&recordSchema=picaxml&sortKeys=Year%2C%2C1", url.toString()); + } + + @Test + public void testPerformSearchMatchingMultipleEntries() throws FetcherException { + List searchResult = fetcher.performSearch("tit effective java"); + assertTrue(searchResult.contains(bibEntryPPN591166003)); + assertTrue(searchResult.contains(bibEntryPPN66391437X)); + } + + @Test + public void testPerformSearch591166003() throws FetcherException { + List searchResult = fetcher.performSearch("ppn 591166003"); + assertEquals(Collections.singletonList(bibEntryPPN591166003), searchResult); + } + + @Test + public void testPerformSearch66391437X() throws FetcherException { + List searchResult = fetcher.performSearch("ppn 66391437X"); + assertEquals(Collections.singletonList(bibEntryPPN66391437X), searchResult); + } + + @Test + public void testPerformSearchEmpty() throws FetcherException { + List searchResult = fetcher.performSearch(""); + assertEquals(Collections.emptyList(), searchResult); + } +} diff --git a/src/test/resources/net/sf/jabref/logic/importer/util/gvk_artificial_subtitle_test.xml b/src/test/resources/net/sf/jabref/logic/importer/fetcher/gvk_artificial_subtitle_test.xml similarity index 100% rename from src/test/resources/net/sf/jabref/logic/importer/util/gvk_artificial_subtitle_test.xml rename to src/test/resources/net/sf/jabref/logic/importer/fetcher/gvk_artificial_subtitle_test.xml diff --git a/src/test/resources/net/sf/jabref/logic/importer/util/gvk_empty_result_becaue_of_bad_query.xml b/src/test/resources/net/sf/jabref/logic/importer/fetcher/gvk_empty_result_becaue_of_bad_query.xml similarity index 100% rename from src/test/resources/net/sf/jabref/logic/importer/util/gvk_empty_result_becaue_of_bad_query.xml rename to src/test/resources/net/sf/jabref/logic/importer/fetcher/gvk_empty_result_becaue_of_bad_query.xml diff --git a/src/test/resources/net/sf/jabref/logic/importer/util/gvk_gmp.1.bib b/src/test/resources/net/sf/jabref/logic/importer/fetcher/gvk_gmp.1.bib similarity index 100% rename from src/test/resources/net/sf/jabref/logic/importer/util/gvk_gmp.1.bib rename to src/test/resources/net/sf/jabref/logic/importer/fetcher/gvk_gmp.1.bib diff --git a/src/test/resources/net/sf/jabref/logic/importer/util/gvk_gmp.2.bib b/src/test/resources/net/sf/jabref/logic/importer/fetcher/gvk_gmp.2.bib similarity index 100% rename from src/test/resources/net/sf/jabref/logic/importer/util/gvk_gmp.2.bib rename to src/test/resources/net/sf/jabref/logic/importer/fetcher/gvk_gmp.2.bib diff --git a/src/test/resources/net/sf/jabref/logic/importer/util/gvk_gmp.xml b/src/test/resources/net/sf/jabref/logic/importer/fetcher/gvk_gmp.xml similarity index 100% rename from src/test/resources/net/sf/jabref/logic/importer/util/gvk_gmp.xml rename to src/test/resources/net/sf/jabref/logic/importer/fetcher/gvk_gmp.xml diff --git a/src/test/resources/net/sf/jabref/logic/importer/util/gvk_result_for_797485368.bib b/src/test/resources/net/sf/jabref/logic/importer/fetcher/gvk_result_for_797485368.bib similarity index 100% rename from src/test/resources/net/sf/jabref/logic/importer/util/gvk_result_for_797485368.bib rename to src/test/resources/net/sf/jabref/logic/importer/fetcher/gvk_result_for_797485368.bib diff --git a/src/test/resources/net/sf/jabref/logic/importer/util/gvk_result_for_797485368.xml b/src/test/resources/net/sf/jabref/logic/importer/fetcher/gvk_result_for_797485368.xml similarity index 100% rename from src/test/resources/net/sf/jabref/logic/importer/util/gvk_result_for_797485368.xml rename to src/test/resources/net/sf/jabref/logic/importer/fetcher/gvk_result_for_797485368.xml From 81d51a9f679a3c5a48a0e4d434b8f9031274eeac Mon Sep 17 00:00:00 2001 From: Christian Bartsch Date: Fri, 19 Aug 2016 10:49:15 +0200 Subject: [PATCH 10/14] Some OS didn't show directories when a file type was selected in the import dialog --- .../java/net/sf/jabref/gui/importer/ImportFileFilter.java | 6 +++--- src/main/java/net/sf/jabref/gui/importer/ImportFormats.java | 1 - src/main/java/net/sf/jabref/logic/util/FileExtensions.java | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/main/java/net/sf/jabref/gui/importer/ImportFileFilter.java b/src/main/java/net/sf/jabref/gui/importer/ImportFileFilter.java index e880b18d34b..ea7d7622513 100644 --- a/src/main/java/net/sf/jabref/gui/importer/ImportFileFilter.java +++ b/src/main/java/net/sf/jabref/gui/importer/ImportFileFilter.java @@ -27,14 +27,14 @@ class ImportFileFilter extends FileFilter implements Comparable Date: Fri, 19 Aug 2016 13:29:16 +0200 Subject: [PATCH 11/14] Move logic to ImportFileFilter --- .../jabref/gui/importer/ImportFileFilter.java | 33 +++++++++++-------- .../sf/jabref/gui/importer/ImportFormats.java | 4 +-- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/main/java/net/sf/jabref/gui/importer/ImportFileFilter.java b/src/main/java/net/sf/jabref/gui/importer/ImportFileFilter.java index e880b18d34b..781413ed4d2 100644 --- a/src/main/java/net/sf/jabref/gui/importer/ImportFileFilter.java +++ b/src/main/java/net/sf/jabref/gui/importer/ImportFileFilter.java @@ -16,6 +16,10 @@ package net.sf.jabref.gui.importer; import java.io.File; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; import javax.swing.filechooser.FileFilter; import javax.swing.filechooser.FileNameExtensionFilter; @@ -25,35 +29,36 @@ class ImportFileFilter extends FileFilter implements Comparable { - private final ImportFormat format; - private final String name; - private final FileNameExtensionFilter filextFilter; - + private final String description; + private final FileNameExtensionFilter fileFilter; public ImportFileFilter(ImportFormat format) { - this.format = format; FileExtensions extensions = format.getExtensions(); - this.name = extensions.getDescription(); - filextFilter = new FileNameExtensionFilter(extensions.getDescription(), extensions.getExtensions()); + this.description = extensions.getDescription(); + fileFilter = new FileNameExtensionFilter(extensions.getDescription(), extensions.getExtensions()); } - public ImportFormat getImportFormat() { - return format; + public ImportFileFilter(String description, Collection formats) { + this.description = description; + + List extensions = formats.stream().map(p -> p.getExtensions()).collect(Collectors.toList()); + List flatExtensions = extensions.stream().flatMap(extList -> Stream.of(extList.getExtensions())).collect(Collectors.toList()); + fileFilter = new FileNameExtensionFilter(description, flatExtensions.toArray(new String[flatExtensions.size()])); } @Override public boolean accept(File file) { - return filextFilter.accept(file); + return fileFilter.accept(file); } @Override public String getDescription() { - return name; + return description; } @Override public int compareTo(ImportFileFilter o) { - return name.compareTo(o.name); + return description.compareTo(o.description); } @Override @@ -62,14 +67,14 @@ public boolean equals(Object o) { return true; } if (o instanceof ImportFileFilter) { - return name.equals(((ImportFileFilter) o).name); + return description.equals(((ImportFileFilter) o).description); } return false; } @Override public int hashCode() { - return name.hashCode(); + return description.hashCode(); } } diff --git a/src/main/java/net/sf/jabref/gui/importer/ImportFormats.java b/src/main/java/net/sf/jabref/gui/importer/ImportFormats.java index 540ac83e47b..f4882df21a4 100644 --- a/src/main/java/net/sf/jabref/gui/importer/ImportFormats.java +++ b/src/main/java/net/sf/jabref/gui/importer/ImportFormats.java @@ -80,8 +80,8 @@ public void actionPerformed(ActionEvent e) { List extensions = importers.stream().map(p -> p.getExtensions()).collect(Collectors.toList()); FileDialog dialog = new FileDialog(frame, Globals.prefs.get(JabRefPreferences.IMPORT_WORKING_DIRECTORY)); // Add file filter for all supported types - List flatExtensions = extensions.stream().flatMap(extList -> Stream.of(extList.getExtensions())).collect(Collectors.toList()); - dialog.setFileFilter(new FileNameExtensionFilter(Localization.lang("Available import formats"), flatExtensions.toArray(new String[flatExtensions.size()]))); + ImportFileFilter allImports = new ImportFileFilter(Localization.lang("Available import formats"), importers); + dialog.setFileFilter(allImports); // Add filters for extensions dialog.withExtensions(extensions); From 758364c68945d1e6c6bcaed65ada0e6fc200fde2 Mon Sep 17 00:00:00 2001 From: Stefan Kolb Date: Fri, 19 Aug 2016 13:38:00 +0200 Subject: [PATCH 12/14] Fix Imports --- src/main/java/net/sf/jabref/gui/importer/ImportFormats.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/net/sf/jabref/gui/importer/ImportFormats.java b/src/main/java/net/sf/jabref/gui/importer/ImportFormats.java index f4882df21a4..aecf54a731c 100644 --- a/src/main/java/net/sf/jabref/gui/importer/ImportFormats.java +++ b/src/main/java/net/sf/jabref/gui/importer/ImportFormats.java @@ -24,12 +24,10 @@ import java.util.Optional; import java.util.SortedSet; import java.util.stream.Collectors; -import java.util.stream.Stream; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.JOptionPane; -import javax.swing.filechooser.FileNameExtensionFilter; import net.sf.jabref.Globals; import net.sf.jabref.gui.FileDialog; From e1515995aa8af7b9823d8d4dc4ad534930a447d0 Mon Sep 17 00:00:00 2001 From: Oscar Gustafsson Date: Fri, 19 Aug 2016 18:58:42 +0200 Subject: [PATCH 13/14] Updated java-string-similarity to 0.16 (#1784) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 26eae64014f..31952c52f69 100644 --- a/build.gradle +++ b/build.gradle @@ -112,7 +112,7 @@ dependencies { compile 'org.jsoup:jsoup:1.9.2' compile 'com.mashape.unirest:unirest-java:1.4.9' - compile 'info.debatty:java-string-similarity:0.14' + compile 'info.debatty:java-string-similarity:0.16' compile 'org.apache.logging.log4j:log4j-jcl:2.6.2' compile 'org.apache.logging.log4j:log4j-api:2.6.2' From 8b20e691edffe562fb77b1bee1b5163ffb77ce22 Mon Sep 17 00:00:00 2001 From: Oscar Gustafsson Date: Fri, 19 Aug 2016 19:37:52 +0200 Subject: [PATCH 14/14] Fix NPE when closing the last tab (#1783) --- src/main/java/net/sf/jabref/gui/SidePaneManager.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/sf/jabref/gui/SidePaneManager.java b/src/main/java/net/sf/jabref/gui/SidePaneManager.java index 996e8621bc5..6492c5ec1f9 100644 --- a/src/main/java/net/sf/jabref/gui/SidePaneManager.java +++ b/src/main/java/net/sf/jabref/gui/SidePaneManager.java @@ -101,13 +101,15 @@ public synchronized void show(String name) { public synchronized void hide(String name) { SidePaneComponent sidePaneComponent = components.get(name); - MainTable mainTable = frame.getCurrentBasePanel().getMainTable(); if (sidePaneComponent == null) { LOGGER.warn("Side pane component '" + name + "' unknown."); } else { hideComponent(sidePaneComponent); - mainTable.setSelected(mainTable.getSelectedRow()); - mainTable.requestFocus(); + if (frame.getCurrentBasePanel() != null) { + MainTable mainTable = frame.getCurrentBasePanel().getMainTable(); + mainTable.setSelected(mainTable.getSelectedRow()); + mainTable.requestFocus(); + } } }