From 4b65c3bbd61553d5879f54480fcdbb6bc508589d Mon Sep 17 00:00:00 2001 From: Christoph Date: Fri, 20 Jan 2017 16:22:32 +0100 Subject: [PATCH 01/14] Remove html code from ACM fetcher before calling parser to prevent junk in bib file (#2473) --- CHANGELOG.md | 2 +- .../importer/fetcher/ACMPortalFetcher.java | 37 ++++++++++++------- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 421eecee770..8097db34217 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,7 +20,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - When pressing Ctrl + F and the searchbar is already focused the text will be selected. - LaTeX symbols are now displayed as Unicode for the author column in the main table. "'n" and "\'{n}" are parsed correctly. Fixes [#2458](https://github.com/JabRef/jabref/issues/2458). - If one deleted the current query it was not saved (every basepanel can have it's own query). Fixes [#2468](https://github.com/JabRef/jabref/issues/2468). - +- The ACM fetcher does no longer add HTML code to the bib-file. Fixes [#2472](https://github.com/JabRef/jabref/issues/2472) ### Removed diff --git a/src/main/java/net/sf/jabref/gui/importer/fetcher/ACMPortalFetcher.java b/src/main/java/net/sf/jabref/gui/importer/fetcher/ACMPortalFetcher.java index 8ff338d2a26..91481b67b62 100644 --- a/src/main/java/net/sf/jabref/gui/importer/fetcher/ACMPortalFetcher.java +++ b/src/main/java/net/sf/jabref/gui/importer/fetcher/ACMPortalFetcher.java @@ -16,6 +16,7 @@ import java.util.Optional; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; import javax.swing.ButtonGroup; import javax.swing.JCheckBox; @@ -32,9 +33,11 @@ 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.ParseException; import net.sf.jabref.logic.importer.fileformat.BibtexParser; import net.sf.jabref.logic.l10n.Localization; import net.sf.jabref.logic.net.URLDownload; +import net.sf.jabref.logic.protectedterms.ProtectedTermsLoader; import net.sf.jabref.model.entry.BibEntry; import net.sf.jabref.model.entry.FieldName; import net.sf.jabref.preferences.JabRefPreferences; @@ -47,7 +50,8 @@ public class ACMPortalFetcher implements PreviewEntryFetcher { private static final Log LOGGER = LogFactory.getLog(ACMPortalFetcher.class); private final HtmlToLatexFormatter htmlToLatexFormatter = new HtmlToLatexFormatter(); - private final ProtectTermsFormatter protectTermsFormatter = new ProtectTermsFormatter(); + private final ProtectTermsFormatter protectTermsFormatter = new ProtectTermsFormatter( + new ProtectedTermsLoader(Globals.prefs.getProtectedTermsPreferences())); private final UnitsToLatexFormatter unitsToLatexFormatter = new UnitsToLatexFormatter(); private String terms; @@ -68,6 +72,9 @@ public class ACMPortalFetcher implements PreviewEntryFetcher { private static final String RESULTS_FOUND_PATTERN = "
"; private static final String PAGE_RANGE_PATTERN = "
"; + private static final String START_BIBTEX_ENTRY = "@"; + private static final String END_BIBTEX_ENTRY_HTML = ""; + private final JRadioButton acmButton = new JRadioButton(Localization.lang("The ACM Digital Library")); private final JRadioButton guideButton = new JRadioButton(Localization.lang("The Guide to Computing Literature")); private final JCheckBox absCheckBox = new JCheckBox(Localization.lang("Include abstracts"), false); @@ -95,7 +102,6 @@ public class ACMPortalFetcher implements PreviewEntryFetcher { private static final Pattern ABSTRACT_PATTERN = Pattern.compile("
(.*?)
"); private static final Pattern SOURCE_PATTERN = Pattern.compile("([^<]*)"); - @Override public JPanel getOptionsPanel() { JPanel pan = new JPanel(); @@ -169,7 +175,7 @@ public void getEntries(Map selection, ImportInspector inspector break; } if (selentry.getValue()) { - downloadEntryBibTeX(selentry.getKey(), fetchAbstract).ifPresent(entry -> { + downloadEntryBibTeX(selentry.getKey(), fetchAbstract).ifPresent(entry -> { // Convert from HTML and optionally add curly brackets around key words to keep the case entry.getField(FieldName.TITLE).ifPresent(title -> { title = title.replace("\\&", "&").replace("\\#", "#"); @@ -223,8 +229,6 @@ private String makeUrl() { return sb.toString(); } - - private void parse(String text, int hits, Map entries) { int entryNumber = 1; while (getNextEntryURL(text, entryNumber, entries) && (entryNumber <= hits)) { @@ -251,8 +255,7 @@ private boolean getNextEntryURL(String allText, int entryNumber, if (index >= 0) { String text = allText.substring(index, endIndex); // Always try RIS import first - Matcher fullCitation = - ACMPortalFetcher.FULL_CITATION_PATTERN.matcher(text); + Matcher fullCitation = ACMPortalFetcher.FULL_CITATION_PATTERN.matcher(text); String item; if (fullCitation.find()) { String link = getEntryBibTeXURL(fullCitation.group(1)); @@ -305,17 +308,23 @@ private boolean getNextEntryURL(String allText, int entryNumber, private static Optional downloadEntryBibTeX(String id, boolean downloadAbstract) { try { - URL url = new URL(ACMPortalFetcher.START_URL + ACMPortalFetcher.BIBTEX_URL + id + ACMPortalFetcher.BIBTEX_URL_END); + URL url = new URL( + ACMPortalFetcher.START_URL + ACMPortalFetcher.BIBTEX_URL + id + ACMPortalFetcher.BIBTEX_URL_END); URLConnection connection = url.openConnection(); // set user-agent to avoid being blocked as a crawler - connection.addRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 5.1; rv:31.0) Gecko/20100101 Firefox/31.0"); + connection.addRequestProperty("User-Agent", + "Mozilla/5.0 (Windows NT 5.1; rv:31.0) Gecko/20100101 Firefox/31.0"); Collection items = null; + try (BufferedReader in = new BufferedReader( new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8))) { - items = new BibtexParser(Globals.prefs.getImportFormatPreferences()).parse(in).getDatabase() - .getEntries(); - } catch (IOException e) { + String htmlCode = in.lines().filter(s -> !s.isEmpty()).collect(Collectors.joining()); + String bibtexString = htmlCode.substring(htmlCode.indexOf(START_BIBTEX_ENTRY), + htmlCode.indexOf(END_BIBTEX_ENTRY_HTML)); + items = new BibtexParser(Globals.prefs.getImportFormatPreferences()).parseEntries(bibtexString); + + } catch (IOException | ParseException e) { LOGGER.info("Download of BibTeX information from ACM Portal failed.", e); } if ((items == null) || items.isEmpty()) { @@ -338,7 +347,8 @@ private static Optional downloadEntryBibTeX(String id, boolean downloa return Optional.of(entry); } catch (NoSuchElementException e) { - LOGGER.info("Bad BibTeX record read at: " + ACMPortalFetcher.BIBTEX_URL + id + ACMPortalFetcher.BIBTEX_URL_END, + LOGGER.info( + "Bad BibTeX record read at: " + ACMPortalFetcher.BIBTEX_URL + id + ACMPortalFetcher.BIBTEX_URL_END, e); } catch (MalformedURLException e) { LOGGER.info("Malformed URL.", e); @@ -393,7 +403,6 @@ public HelpFile getHelpPage() { return HelpFile.FETCHER_ACM; } - // This method is called by the dialog when the user has canceled or //signaled a stop. It is expected that any long-running fetch operations //will stop after this method is called. From f1c6b8f2214f3e5a903e1ba6f8a03fa0ef0174ff Mon Sep 17 00:00:00 2001 From: milleratotago Date: Sat, 14 Jan 2017 12:02:18 +1300 Subject: [PATCH 02/14] Fixed bug when assigning refs to groups. Program hung if user clicked ExpandAll or CollapseAll dialog button when assigning refs to groups. Also changed CollapseAll to show 1st-level children of AllEntries node. --- .../gui/groups/GroupAddRemoveDialog.java | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/main/java/net/sf/jabref/gui/groups/GroupAddRemoveDialog.java b/src/main/java/net/sf/jabref/gui/groups/GroupAddRemoveDialog.java index ddd03359d5f..57c3be67af0 100644 --- a/src/main/java/net/sf/jabref/gui/groups/GroupAddRemoveDialog.java +++ b/src/main/java/net/sf/jabref/gui/groups/GroupAddRemoveDialog.java @@ -4,7 +4,6 @@ import java.awt.Color; import java.awt.Component; import java.awt.event.ActionEvent; -import java.util.Enumeration; import java.util.List; import java.util.Optional; @@ -136,31 +135,33 @@ public void actionPerformed(ActionEvent e) { // If "expand" is true, all nodes in the tree area expanded // otherwise all nodes in the tree are collapsed: - private void expandAll(final JTree tree, final boolean expand) { + private void expandAll(final JTree subtree, final boolean expand) { SwingUtilities.invokeLater(() -> { - TreeNode root = ((TreeNode) tree.getModel().getRoot()); + TreeNode root = ((TreeNode) subtree.getModel().getRoot()); // walk through the tree, beginning at the root: - expandAll(tree, new TreePath(((DefaultTreeModel) tree.getModel()).getPathToRoot(root)), expand); + expandAll(subtree, new TreePath(((DefaultTreeModel) subtree.getModel()).getPathToRoot(root)), expand); tree.requestFocusInWindow(); }); } - private void expandAll(final JTree tree, final TreePath parent, final boolean expand) { + private void expandAll(final JTree subtree, final TreePath parent, final boolean expand) { // walk through the children: TreeNode node = (TreeNode) parent.getLastPathComponent(); - if (node.getChildCount() >= 0) { - for (Enumeration e = node.children(); e.hasMoreElements();) { - TreeNode n = (TreeNode) e.nextElement(); - TreePath path = parent.pathByAddingChild(n); - expandAll(tree, path, expand); + int numChildren = node.getChildCount(); + if (numChildren > 0) { + for (int i = 0; i < numChildren; i++) { + TreeNode child = node.getChildAt(i); + TreePath path = parent.pathByAddingChild(child); + expandAll(subtree, path, expand); } - } // "expand" / "collapse" occurs from bottom to top: if (expand) { tree.expandPath(parent); } else { - tree.collapsePath(parent); + if (node.getParent() != null) { + tree.collapsePath(parent); + } } } From f1d97c6d0bf72f2158fc7fd10f666aeb966089dc Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Fri, 20 Jan 2017 17:13:01 +0100 Subject: [PATCH 03/14] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8097db34217..d8d95f47ea5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,8 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - LaTeX symbols are now displayed as Unicode for the author column in the main table. "'n" and "\'{n}" are parsed correctly. Fixes [#2458](https://github.com/JabRef/jabref/issues/2458). - If one deleted the current query it was not saved (every basepanel can have it's own query). Fixes [#2468](https://github.com/JabRef/jabref/issues/2468). - The ACM fetcher does no longer add HTML code to the bib-file. Fixes [#2472](https://github.com/JabRef/jabref/issues/2472) +- Collapse and expand all buttons in the group assignment dialog no longer lead to a crash of JabRef. + ### Removed From d2b555dde65bf2eb289fa77fce5abf01dca84099 Mon Sep 17 00:00:00 2001 From: Stefan Kolb Date: Fri, 30 Dec 2016 18:29:50 +0100 Subject: [PATCH 04/14] Resolves #2309 JabRef freezes when importing unlinked PDF files into Database --- .../net/sf/jabref/gui/FindUnlinkedFilesDialog.java | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/main/java/net/sf/jabref/gui/FindUnlinkedFilesDialog.java b/src/main/java/net/sf/jabref/gui/FindUnlinkedFilesDialog.java index 5677ab974b4..7519388564a 100644 --- a/src/main/java/net/sf/jabref/gui/FindUnlinkedFilesDialog.java +++ b/src/main/java/net/sf/jabref/gui/FindUnlinkedFilesDialog.java @@ -472,10 +472,10 @@ public void stateChanged(ChangeEvent e) { } else { message = Localization.lang("%0 files found", Integer.toString(counter)); } - SwingUtilities.invokeLater(() -> progressBarSearching.setString(message)); + progressBarSearching.setString(message); } }); - SwingUtilities.invokeLater(() -> searchFinishedHandler(rootNode)); + searchFinishedHandler(rootNode); }); } @@ -532,14 +532,12 @@ entryType, checkBoxWhyIsThereNoGetSelectedStupidSwing, new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { counter++; - SwingUtilities.invokeLater(() -> { - progressBarImporting.setValue(counter); - progressBarImporting.setString(Localization.lang("%0 of %1", Integer.toString(counter), - Integer.toString(progressBarImporting.getMaximum()))); - }); + progressBarImporting.setValue(counter); + progressBarImporting.setString(Localization.lang("%0 of %1", Integer.toString(counter), + Integer.toString(progressBarImporting.getMaximum()))); } }, errors); - SwingUtilities.invokeLater(() -> importFinishedHandler(errors)); + importFinishedHandler(errors); }); } From c62374967d6eb26c013c17039fb31047f928a7ea Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Fri, 20 Jan 2017 18:32:35 +0100 Subject: [PATCH 05/14] Add CHANGELOG entry (and one more link) --- CHANGELOG.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d8d95f47ea5..d72e17e393d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,7 +20,8 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - When pressing Ctrl + F and the searchbar is already focused the text will be selected. - LaTeX symbols are now displayed as Unicode for the author column in the main table. "'n" and "\'{n}" are parsed correctly. Fixes [#2458](https://github.com/JabRef/jabref/issues/2458). - If one deleted the current query it was not saved (every basepanel can have it's own query). Fixes [#2468](https://github.com/JabRef/jabref/issues/2468). -- The ACM fetcher does no longer add HTML code to the bib-file. Fixes [#2472](https://github.com/JabRef/jabref/issues/2472) +- The [ACM fetcher](https://help.jabref.org/en/ACMPortal) does no longer add HTML code to the bib-file. Fixes [#2472](https://github.com/JabRef/jabref/issues/2472) +- When [finding unlinked files](https://help.jabref.org/en/FindUnlinkedFiles), JabRef does not freeze any more. Fixes [#2309]()https://github.com/JabRef/jabref/issues/2309) - Collapse and expand all buttons in the group assignment dialog no longer lead to a crash of JabRef. ### Removed @@ -64,11 +65,6 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - - - - - From 0ff9a119f9981bb6ce1afffdbdddff25c3ff0f50 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Fri, 20 Jan 2017 18:38:13 +0100 Subject: [PATCH 06/14] Remove obsolete import --- src/main/java/net/sf/jabref/gui/FindUnlinkedFilesDialog.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/net/sf/jabref/gui/FindUnlinkedFilesDialog.java b/src/main/java/net/sf/jabref/gui/FindUnlinkedFilesDialog.java index 7519388564a..f27d1553006 100644 --- a/src/main/java/net/sf/jabref/gui/FindUnlinkedFilesDialog.java +++ b/src/main/java/net/sf/jabref/gui/FindUnlinkedFilesDialog.java @@ -54,7 +54,6 @@ import javax.swing.JTree; import javax.swing.KeyStroke; import javax.swing.SwingConstants; -import javax.swing.SwingUtilities; import javax.swing.WindowConstants; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; From 60905fcd6b19971f82bba143ee46c2ce9ef8abbf Mon Sep 17 00:00:00 2001 From: Christian Bartsch Date: Sat, 21 Jan 2017 20:41:15 +0100 Subject: [PATCH 07/14] add update from DOI to the entryeditor sidebar (#2476) --- CHANGELOG.md | 1 + .../jabref/gui/importer/fetcher/EntryFetchers.java | 5 +++-- .../jabref/logic/importer/fetcher/DoiFetcher.java | 14 +++++++++++++- .../gui/importer/fetcher/EntryFetchersTest.java | 5 ++--- 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d72e17e393d..a529a0aed02 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# ## [Unreleased] ### Changed +- Added the option to update bibliographic information from DOI to the sidebar of the entryeditor. Implements [#2432](https://github.com/JabRef/jabref/issues/2432). ### Fixed - The formatter for normalizing pages now also can treat ACM pages such as `2:1--2:33`. 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 103df8a4df1..6e09dd2cfb0 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 @@ -53,7 +53,7 @@ public List getEntryFetchers() { return Collections.unmodifiableList(this.entryFetchers); } - public static ArrayList getIdFetchers(ImportFormatPreferences importFormatPreferences) { + public static List getIdFetchers(ImportFormatPreferences importFormatPreferences) { ArrayList list = new ArrayList<>(); list.add(new ArXiv(importFormatPreferences)); list.add(new AstrophysicsDataSystem(importFormatPreferences)); @@ -66,9 +66,10 @@ public static ArrayList getIdFetchers(ImportFormatPreferences im return list; } - public static ArrayList getEntryBasedFetchers(ImportFormatPreferences importFormatPreferences) { + public static List getEntryBasedFetchers(ImportFormatPreferences importFormatPreferences) { ArrayList list = new ArrayList<>(); list.add(new AstrophysicsDataSystem(importFormatPreferences)); + list.add(new DoiFetcher(importFormatPreferences)); list.add(new MathSciNet(importFormatPreferences)); list.sort(Comparator.comparing(WebFetcher::getName)); return list; diff --git a/src/main/java/net/sf/jabref/logic/importer/fetcher/DoiFetcher.java b/src/main/java/net/sf/jabref/logic/importer/fetcher/DoiFetcher.java index d4dcd7b4409..835bcc33c19 100644 --- a/src/main/java/net/sf/jabref/logic/importer/fetcher/DoiFetcher.java +++ b/src/main/java/net/sf/jabref/logic/importer/fetcher/DoiFetcher.java @@ -3,11 +3,14 @@ import java.io.IOException; import java.net.URL; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; import java.util.Optional; import net.sf.jabref.logic.formatter.bibtexfields.ClearFormatter; import net.sf.jabref.logic.formatter.bibtexfields.NormalizePagesFormatter; import net.sf.jabref.logic.help.HelpFile; +import net.sf.jabref.logic.importer.EntryBasedFetcher; import net.sf.jabref.logic.importer.FetcherException; import net.sf.jabref.logic.importer.IdBasedFetcher; import net.sf.jabref.logic.importer.ImportFormatPreferences; @@ -20,7 +23,7 @@ import net.sf.jabref.model.entry.BibEntry; import net.sf.jabref.model.entry.FieldName; -public class DoiFetcher implements IdBasedFetcher { +public class DoiFetcher implements IdBasedFetcher, EntryBasedFetcher { private final ImportFormatPreferences preferences; @@ -69,4 +72,13 @@ private void doPostCleanup(BibEntry entry) { new FieldFormatterCleanup(FieldName.PAGES, new NormalizePagesFormatter()).cleanup(entry); new FieldFormatterCleanup(FieldName.URL, new ClearFormatter()).cleanup(entry); } + + @Override + public List performSearch(BibEntry entry) throws FetcherException { + Optional bibEntry = performSearchById(entry.getField(FieldName.DOI).orElse("")); + List list = new ArrayList<>(); + bibEntry.ifPresent(list::add); + return list; + } + } diff --git a/src/test/java/net/sf/jabref/gui/importer/fetcher/EntryFetchersTest.java b/src/test/java/net/sf/jabref/gui/importer/fetcher/EntryFetchersTest.java index 8864c5695aa..f6395680c29 100644 --- a/src/test/java/net/sf/jabref/gui/importer/fetcher/EntryFetchersTest.java +++ b/src/test/java/net/sf/jabref/gui/importer/fetcher/EntryFetchersTest.java @@ -1,6 +1,5 @@ package net.sf.jabref.gui.importer.fetcher; -import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.stream.Collectors; @@ -33,7 +32,7 @@ public void setUp() throws Exception { @Test public void getIdFetchersReturnsAllFetcherDerivingFromIdFetcher() throws Exception { - ArrayList idFetchers = EntryFetchers.getIdFetchers(importFormatPreferences); + List idFetchers = EntryFetchers.getIdFetchers(importFormatPreferences); Set> expected = reflections.getSubTypesOf(IdBasedFetcher.class); expected.remove(AbstractIsbnFetcher.class); @@ -46,7 +45,7 @@ public void getIdFetchersReturnsAllFetcherDerivingFromIdFetcher() throws Excepti @Test public void getEntryBasedFetchersReturnsAllFetcherDerivingFromEntryBasedFetcher() throws Exception { - ArrayList idFetchers = EntryFetchers.getEntryBasedFetchers(importFormatPreferences); + List idFetchers = EntryFetchers.getEntryBasedFetchers(importFormatPreferences); Set> expected = reflections.getSubTypesOf(EntryBasedFetcher.class); expected.remove(EntryBasedParserFetcher.class); From d615880f91a0e8d0164b69c41d956f2e7718f4eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Lenhard?= Date: Mon, 23 Jan 2017 20:07:48 +0100 Subject: [PATCH 08/14] Fix aux duplicates (#2480) * Do not add duplicates of entry that have already been found via crossref * Add Changelog entry --- CHANGELOG.md | 3 ++- src/main/java/net/sf/jabref/logic/auxparser/AuxParser.java | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a529a0aed02..8cb29dad226 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,7 +23,8 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - If one deleted the current query it was not saved (every basepanel can have it's own query). Fixes [#2468](https://github.com/JabRef/jabref/issues/2468). - The [ACM fetcher](https://help.jabref.org/en/ACMPortal) does no longer add HTML code to the bib-file. Fixes [#2472](https://github.com/JabRef/jabref/issues/2472) - When [finding unlinked files](https://help.jabref.org/en/FindUnlinkedFiles), JabRef does not freeze any more. Fixes [#2309]()https://github.com/JabRef/jabref/issues/2309) -- Collapse and expand all buttons in the group assignment dialog no longer lead to a crash of JabRef. +- Collapse and expand all buttons in the group assignment dialog no longer lead to a crash of JabRef. +- Fixes [#2475](https://github.com/JabRef/jabref/issues/2475): The aux export command line function does no longer add duplicates of references that were resolved via crossref ### Removed diff --git a/src/main/java/net/sf/jabref/logic/auxparser/AuxParser.java b/src/main/java/net/sf/jabref/logic/auxparser/AuxParser.java index 656f04b0279..f622fcf47a3 100644 --- a/src/main/java/net/sf/jabref/logic/auxparser/AuxParser.java +++ b/src/main/java/net/sf/jabref/logic/auxparser/AuxParser.java @@ -133,7 +133,9 @@ private void resolveTags(AuxParserResult result) { for (String key : result.getUniqueKeys()) { Optional entry = masterDatabase.getEntryByKey(key); - if (entry.isPresent()) { + if(result.getGeneratedBibDatabase().getEntryByKey(key).isPresent()) { + // do nothing, key has already been processed + } else if (entry.isPresent()) { insertEntry(entry.get(), result); resolveCrossReferences(entry.get(), result); } else { From 1c9c4707a9b448e58fe2d02ad6672283d3210add Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Tue, 24 Jan 2017 08:22:46 +0100 Subject: [PATCH 09/14] Update guava from 20.0 to 21.0 and mockito-core from 2.5.5 to 2.6.2 --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 2b259dc8872..d7fe2342f3f 100644 --- a/build.gradle +++ b/build.gradle @@ -107,7 +107,7 @@ dependencies { compile 'net.java.dev.glazedlists:glazedlists_java15:1.9.1' compile fileTree(dir: 'lib', includes: ['*.jar']) - compile 'com.google.guava:guava:20.0' + compile 'com.google.guava:guava:21.0' compile 'commons-logging:commons-logging:1.2' @@ -131,7 +131,7 @@ dependencies { compile 'com.github.lgooddatepicker:LGoodDatePicker:8.3.0' testCompile 'junit:junit:4.12' - testCompile 'org.mockito:mockito-core:2.5.5' + testCompile 'org.mockito:mockito-core:2.6.2' testCompile 'com.github.tomakehurst:wiremock:2.5.0' testCompile 'org.assertj:assertj-swing-junit:3.5.0' testCompile 'org.reflections:reflections:0.9.10' From 172fdeb1ce4c43c096b85ce5d924b1f64c82fc01 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Tue, 24 Jan 2017 08:30:07 +0100 Subject: [PATCH 10/14] Improve CHANGELOG formatting --- CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8cb29dad226..12e85e98aa8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,10 +21,10 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - When pressing Ctrl + F and the searchbar is already focused the text will be selected. - LaTeX symbols are now displayed as Unicode for the author column in the main table. "'n" and "\'{n}" are parsed correctly. Fixes [#2458](https://github.com/JabRef/jabref/issues/2458). - If one deleted the current query it was not saved (every basepanel can have it's own query). Fixes [#2468](https://github.com/JabRef/jabref/issues/2468). -- The [ACM fetcher](https://help.jabref.org/en/ACMPortal) does no longer add HTML code to the bib-file. Fixes [#2472](https://github.com/JabRef/jabref/issues/2472) -- When [finding unlinked files](https://help.jabref.org/en/FindUnlinkedFiles), JabRef does not freeze any more. Fixes [#2309]()https://github.com/JabRef/jabref/issues/2309) +- The [ACM fetcher](https://help.jabref.org/en/ACMPortal) does no longer add HTML code to the bib-file. Fixes [#2472](https://github.com/JabRef/jabref/issues/2472). +- When [finding unlinked files](https://help.jabref.org/en/FindUnlinkedFiles), JabRef does not freeze any more. Fixes [#2309]()https://github.com/JabRef/jabref/issues/2309). - Collapse and expand all buttons in the group assignment dialog no longer lead to a crash of JabRef. -- Fixes [#2475](https://github.com/JabRef/jabref/issues/2475): The aux export command line function does no longer add duplicates of references that were resolved via crossref +- The aux export command line function does no longer add duplicates of references that were resolved via `crossref`. Fixes [#2475](https://github.com/JabRef/jabref/issues/2475). ### Removed From e61279b7dcb9aa6ce6ae57a85cf95e0ef4fe8ca4 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Thu, 26 Jan 2017 13:02:12 +0100 Subject: [PATCH 11/14] Catch NumberFormatException if context can't be parsed in groups (#2488) * Catch NumberFormatException if context can't be parsed in groups * Remove null parser result * Fix test --- CHANGELOG.md | 1 + src/main/java/net/sf/jabref/JabRefGUI.java | 2 +- .../net/sf/jabref/cli/ArgumentProcessor.java | 168 +++++++++--------- .../importer/actions/OpenDatabaseAction.java | 2 +- .../jabref/logic/importer/OpenDatabase.java | 10 +- .../jabref/logic/importer/ParserResult.java | 79 ++++---- .../importer/fileformat/BibTeXMLImporter.java | 2 +- .../importer/fileformat/BibtexParser.java | 13 +- .../importer/fileformat/MedlineImporter.java | 10 +- .../importer/fileformat/ModsImporter.java | 2 +- .../fileformat/PdfContentImporter.java | 9 +- .../importer/fileformat/PdfXmpImporter.java | 2 +- .../logic/importer/util/GroupsParser.java | 24 +-- .../jabref/logic/bibtex/BibEntryAssert.java | 2 +- .../logic/importer/util/GroupsParserTest.java | 5 + 15 files changed, 159 insertions(+), 172 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 12e85e98aa8..a7ac32dbe0b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - When [finding unlinked files](https://help.jabref.org/en/FindUnlinkedFiles), JabRef does not freeze any more. Fixes [#2309]()https://github.com/JabRef/jabref/issues/2309). - Collapse and expand all buttons in the group assignment dialog no longer lead to a crash of JabRef. - The aux export command line function does no longer add duplicates of references that were resolved via `crossref`. Fixes [#2475](https://github.com/JabRef/jabref/issues/2475). +- Parsing of damaged metadata is now more robust and reports a more detailed error message. Fixes [#2477](https://github.com/JabRef/jabref/issues/2477). ### Removed diff --git a/src/main/java/net/sf/jabref/JabRefGUI.java b/src/main/java/net/sf/jabref/JabRefGUI.java index e5b29d588cc..ae661261c62 100644 --- a/src/main/java/net/sf/jabref/JabRefGUI.java +++ b/src/main/java/net/sf/jabref/JabRefGUI.java @@ -210,7 +210,7 @@ private void openLastEditedDatabases() { ParserResult parsedDatabase = OpenDatabase.loadDatabase(fileName, Globals.prefs.getImportFormatPreferences()); - if (parsedDatabase.isNullResult()) { + if (parsedDatabase.isEmpty()) { LOGGER.error(Localization.lang("Error opening file") + " '" + dbFile.getPath() + "'"); } else { bibDatabases.add(parsedDatabase); diff --git a/src/main/java/net/sf/jabref/cli/ArgumentProcessor.java b/src/main/java/net/sf/jabref/cli/ArgumentProcessor.java index d5512f3abcb..11c03690ba2 100644 --- a/src/main/java/net/sf/jabref/cli/ArgumentProcessor.java +++ b/src/main/java/net/sf/jabref/cli/ArgumentProcessor.java @@ -58,26 +58,89 @@ public class ArgumentProcessor { private static final Log LOGGER = LogFactory.getLog(ArgumentProcessor.class); + private final JabRefCLI cli; + private final List parserResults; + private final Mode startupMode; + private boolean noGUINeeded; + public ArgumentProcessor(String[] args, Mode startupMode) { + cli = new JabRefCLI(args); + this.startupMode = startupMode; + parserResults = processArguments(); + } - public enum Mode { - INITIAL_START, REMOTE_START + /** + * Will open a file (like importFile), but will also request JabRef to focus on this database + * + * @param argument See importFile. + * @return ParserResult with setToOpenTab(true) + */ + private static Optional importToOpenBase(String argument) { + Optional result = importFile(argument); + + result.ifPresent(ParserResult::setToOpenTab); + + return result; } + private static Optional importFile(String argument) { + String[] data = argument.split(","); - private final JabRefCLI cli; + String address = data[0]; + Path file; + if (address.startsWith("http://") || address.startsWith("https://") || address.startsWith("ftp://")) { + // Download web resource to temporary file + try { + file = new URLDownload(address).downloadToTemporaryFile(); + } catch (IOException e) { + System.err.println(Localization.lang("Problem downloading from %1", address) + e.getLocalizedMessage()); + return Optional.empty(); + } + } else { + if (OS.WINDOWS) { + file = Paths.get(address); + } else { + file = Paths.get(address.replace("~", System.getProperty("user.home"))); + } + } - private final List parserResults; + String importFormat; + if (data.length > 1) { + importFormat = data[1]; + } else { + importFormat = "*"; + } - private final Mode startupMode; + Optional importResult = importFile(file, importFormat); + importResult.ifPresent(result -> { + OutputPrinter printer = new SystemOutputPrinter(); + if (result.hasWarnings()) { + printer.showMessage(result.getErrorMessage()); + } + }); + return importResult; + } - private boolean noGUINeeded; + private static Optional importFile(Path file, String importFormat) { + try { + if (!"*".equals(importFormat)) { + System.out.println(Localization.lang("Importing") + ": " + file); + ParserResult result = Globals.IMPORT_FORMAT_READER.importFromFile(importFormat, file); + return Optional.of(result); + } else { + // * means "guess the format": + System.out.println(Localization.lang("Importing in unknown format") + ": " + file); + ImportFormatReader.UnknownFormatImport importResult = Globals.IMPORT_FORMAT_READER.importUnknownFormat(file); - public ArgumentProcessor(String[] args, Mode startupMode) { - cli = new JabRefCLI(args); - this.startupMode = startupMode; - parserResults = processArguments(); + System.out.println(Localization.lang("Format used") + ": " + importResult.format); + return Optional.of(importResult.parserResult); + } + } catch (ImportException ex) { + System.err + .println(Localization.lang("Error opening file") + " '" + file + "': " + ex.getLocalizedMessage()); + return Optional.empty(); + } } public List getParserResults() { @@ -244,12 +307,12 @@ private List importAndOpenFiles() { // BIB files to open. Other files, and files that could not be opened // as bib, we try to import instead. boolean bibExtension = aLeftOver.toLowerCase(Locale.ENGLISH).endsWith("bib"); - ParserResult pr = ParserResult.getNullResult(); + ParserResult pr = new ParserResult(); if (bibExtension) { pr = OpenDatabase.loadDatabase(aLeftOver, Globals.prefs.getImportFormatPreferences()); } - if (!bibExtension || (pr.isNullResult())) { + if (!bibExtension || (pr.isEmpty())) { // We will try to import this file. Normally we // will import it into a new tab, but if this import has // been initiated by another instance through the remote @@ -259,7 +322,7 @@ private List importAndOpenFiles() { if (startupMode == Mode.INITIAL_START) { toImport.add(aLeftOver); } else { - loaded.add(importToOpenBase(aLeftOver).orElse(ParserResult.getNullResult())); + loaded.add(importToOpenBase(aLeftOver).orElse(new ParserResult())); } } else { loaded.add(pr); @@ -518,83 +581,12 @@ public boolean isBlank() { return cli.isBlank(); } - /** - * Will open a file (like importFile), but will also request JabRef to focus on this database - * - * @param argument See importFile. - * @return ParserResult with setToOpenTab(true) - */ - private static Optional importToOpenBase(String argument) { - Optional result = importFile(argument); - - result.ifPresent(x -> x.setToOpenTab(true)); - - return result; - } - - private static Optional importFile(String argument) { - String[] data = argument.split(","); - - String address = data[0]; - Path file; - if (address.startsWith("http://") || address.startsWith("https://") || address.startsWith("ftp://")) { - // Download web resource to temporary file - try { - file = new URLDownload(address).downloadToTemporaryFile(); - } catch (IOException e) { - System.err.println(Localization.lang("Problem downloading from %1", address) + e.getLocalizedMessage()); - return Optional.empty(); - } - } else { - if (OS.WINDOWS) { - file = Paths.get(address); - } else { - file = Paths.get(address.replace("~", System.getProperty("user.home"))); - } - } - - String importFormat; - if (data.length > 1) { - importFormat = data[1]; - } else { - importFormat = "*"; - } - - Optional importResult = importFile(file, importFormat); - importResult.ifPresent(result -> { - OutputPrinter printer = new SystemOutputPrinter(); - if (result.hasWarnings()) { - printer.showMessage(result.getErrorMessage()); - } - }); - return importResult; - } - - private static Optional importFile(Path file, String importFormat) { - try { - if (!"*".equals(importFormat)) { - System.out.println(Localization.lang("Importing") + ": " + file); - ParserResult result = Globals.IMPORT_FORMAT_READER.importFromFile(importFormat, file); - return Optional.of(result); - } else { - // * means "guess the format": - System.out.println(Localization.lang("Importing in unknown format") + ": " + file); - - ImportFormatReader.UnknownFormatImport importResult; - importResult = Globals.IMPORT_FORMAT_READER.importUnknownFormat(file); - - System.out.println(Localization.lang("Format used") + ": " + importResult.format); - return Optional.of(importResult.parserResult); - } - } catch (ImportException ex) { - System.err - .println(Localization.lang("Error opening file") + " '" + file + "': " + ex.getLocalizedMessage()); - return Optional.empty(); - } - } - public boolean shouldShutDown() { return cli.isDisableGui() || cli.isShowVersion() || noGUINeeded; } + public enum Mode { + INITIAL_START, REMOTE_START + } + } diff --git a/src/main/java/net/sf/jabref/gui/importer/actions/OpenDatabaseAction.java b/src/main/java/net/sf/jabref/gui/importer/actions/OpenDatabaseAction.java index 9bcf5713f6f..ce1537be49f 100644 --- a/src/main/java/net/sf/jabref/gui/importer/actions/OpenDatabaseAction.java +++ b/src/main/java/net/sf/jabref/gui/importer/actions/OpenDatabaseAction.java @@ -212,7 +212,7 @@ private void openTheFile(File file, boolean raisePanel) { result = OpenDatabase.loadDatabase(fileToLoad, Globals.prefs.getImportFormatPreferences()); } catch (IOException ex) { LOGGER.error("Error loading database " + fileToLoad, ex); - result = ParserResult.getNullResult(); + result = new ParserResult(); JOptionPane.showMessageDialog(null, Localization.lang("Error opening file") + " '" + fileName + "'", Localization.lang("Error"), JOptionPane.ERROR_MESSAGE); } diff --git a/src/main/java/net/sf/jabref/logic/importer/OpenDatabase.java b/src/main/java/net/sf/jabref/logic/importer/OpenDatabase.java index b8a885d2606..5bc6217e3e4 100644 --- a/src/main/java/net/sf/jabref/logic/importer/OpenDatabase.java +++ b/src/main/java/net/sf/jabref/logic/importer/OpenDatabase.java @@ -26,9 +26,9 @@ public static ParserResult loadDatabase(String name, ImportFormatPreferences imp LOGGER.info("Opening: " + name); if (!file.exists()) { - ParserResult pr = new ParserResult(null, null, null); + ParserResult pr = ParserResult.fromErrorMessage(Localization.lang("File not found")); pr.setFile(file); - pr.setInvalid(true); + LOGGER.error(Localization.lang("Error") + ": " + Localization.lang("File not found")); return pr; } @@ -37,7 +37,7 @@ public static ParserResult loadDatabase(String name, ImportFormatPreferences imp if (!FileBasedLock.waitForFileLock(file.toPath())) { LOGGER.error(Localization.lang("Error opening file") + " '" + name + "'. " + "File is locked by another JabRef instance."); - return ParserResult.getNullResult(); + return new ParserResult(); } ParserResult pr = OpenDatabase.loadDatabase(file, importFormatPreferences); @@ -49,10 +49,8 @@ public static ParserResult loadDatabase(String name, ImportFormatPreferences imp } return pr; } catch (IOException ex) { - ParserResult pr = new ParserResult(null, null, null); + ParserResult pr = ParserResult.fromError(ex); pr.setFile(file); - pr.setInvalid(true); - pr.setErrorMessage(ex.getMessage()); LOGGER.error("Problem opening .bib-file", ex); return pr; } diff --git a/src/main/java/net/sf/jabref/logic/importer/ParserResult.java b/src/main/java/net/sf/jabref/logic/importer/ParserResult.java index d8edd7fb780..ac95bd2a2d5 100644 --- a/src/main/java/net/sf/jabref/logic/importer/ParserResult.java +++ b/src/main/java/net/sf/jabref/logic/importer/ParserResult.java @@ -9,6 +9,7 @@ import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.stream.Collectors; import net.sf.jabref.model.database.BibDatabase; import net.sf.jabref.model.database.BibDatabaseContext; @@ -19,18 +20,12 @@ public class ParserResult { - private static final ParserResult NULL_RESULT = new ParserResult(null, null, null); - private final BibDatabase base; - private MetaData metaData; private final Map entryTypes; - private BibDatabaseContext bibDatabaseContext; - - private File file; private final List warnings = new ArrayList<>(); private final List duplicateKeys = new ArrayList<>(); - - private String errorMessage; - + private BibDatabase database; + private MetaData metaData = new MetaData(); + private File file; private boolean invalid; private boolean toOpenTab; @@ -46,36 +41,44 @@ public ParserResult(BibDatabase database) { this(database, new MetaData(), new HashMap<>()); } - public ParserResult(BibDatabase base, MetaData metaData, Map entryTypes) { - this.base = base; - this.metaData = metaData; - this.entryTypes = entryTypes; - if (Objects.nonNull(base) && Objects.nonNull(metaData)) { - this.bibDatabaseContext = new BibDatabaseContext(base, metaData, file); - } + public ParserResult(BibDatabase database, MetaData metaData, Map entryTypes) { + this.database = Objects.requireNonNull(database); + this.metaData = Objects.requireNonNull(metaData); + this.entryTypes = Objects.requireNonNull(entryTypes); } public static ParserResult fromErrorMessage(String message) { ParserResult parserResult = new ParserResult(); parserResult.addWarning(message); + parserResult.setInvalid(true); return parserResult; } + private static String getErrorMessage(Exception exception) { + String errorMessage = exception.getLocalizedMessage(); + if (exception.getCause() != null) { + errorMessage += " Caused by: " + exception.getCause().getLocalizedMessage(); + } + return errorMessage; + } + + public static ParserResult fromError(Exception exception) { + return fromErrorMessage(getErrorMessage(exception)); + } + /** - * Check if this base is marked to be added to the currently open tab. Default is false. - * - * @return + * Check if this database is marked to be added to the currently open tab. Default is false. */ public boolean toOpenTab() { return toOpenTab; } - public void setToOpenTab(boolean toOpenTab) { - this.toOpenTab = toOpenTab; + public void setToOpenTab() { + this.toOpenTab = true; } public BibDatabase getDatabase() { - return base; + return database; } public MetaData getMetaData() { @@ -109,6 +112,11 @@ public void addWarning(String s) { } } + public void addException(Exception exception) { + String errorMessage = getErrorMessage(exception); + addWarning(errorMessage); + } + public boolean hasWarnings() { return !warnings.isEmpty(); } @@ -155,34 +163,21 @@ public void setInvalid(boolean invalid) { } public String getErrorMessage() { - return errorMessage; - } - - public void setErrorMessage(String errorMessage) { - this.errorMessage = errorMessage; + return warnings().stream().collect(Collectors.joining(" ")); } public BibDatabaseContext getDatabaseContext() { - if (this.bibDatabaseContext == null) { - this.bibDatabaseContext = new BibDatabaseContext(base, metaData, file); - } - return this.bibDatabaseContext; + return new BibDatabaseContext(database, metaData, file); } public void setDatabaseContext(BibDatabaseContext bibDatabaseContext) { Objects.requireNonNull(bibDatabaseContext); - this.bibDatabaseContext = bibDatabaseContext; - } - - public boolean hasDatabaseContext() { - return Objects.nonNull(this.bibDatabaseContext); - } - - public boolean isNullResult() { - return this == NULL_RESULT; + database = bibDatabaseContext.getDatabase(); + metaData = bibDatabaseContext.getMetaData(); + file = bibDatabaseContext.getDatabaseFile().orElse(null); } - public static ParserResult getNullResult() { - return NULL_RESULT; + public boolean isEmpty() { + return this == new ParserResult(); } } diff --git a/src/main/java/net/sf/jabref/logic/importer/fileformat/BibTeXMLImporter.java b/src/main/java/net/sf/jabref/logic/importer/fileformat/BibTeXMLImporter.java index d17d49f40e3..8ca9ab74e33 100644 --- a/src/main/java/net/sf/jabref/logic/importer/fileformat/BibTeXMLImporter.java +++ b/src/main/java/net/sf/jabref/logic/importer/fileformat/BibTeXMLImporter.java @@ -147,7 +147,7 @@ public ParserResult importDatabase(BufferedReader reader) throws IOException { } } catch (JAXBException e) { LOGGER.error("Error with XML parser configuration", e); - return ParserResult.fromErrorMessage(e.getLocalizedMessage()); + return ParserResult.fromError(e); } return new ParserResult(bibItems); } diff --git a/src/main/java/net/sf/jabref/logic/importer/fileformat/BibtexParser.java b/src/main/java/net/sf/jabref/logic/importer/fileformat/BibtexParser.java index 77abc4417b1..835418f193b 100644 --- a/src/main/java/net/sf/jabref/logic/importer/fileformat/BibtexParser.java +++ b/src/main/java/net/sf/jabref/logic/importer/fileformat/BibtexParser.java @@ -59,17 +59,16 @@ public class BibtexParser implements Parser { private static final Log LOGGER = LogFactory.getLog(BibtexParser.class); - + private static final Integer LOOKAHEAD = 64; + private final FieldContentParser fieldContentParser; + private final Deque pureTextFromFile = new LinkedList<>(); + private final ImportFormatPreferences importFormatPreferences; private PushbackReader pushbackReader; private BibDatabase database; private Map entryTypes; private boolean eof; private int line = 1; - private final FieldContentParser fieldContentParser; private ParserResult parserResult; - private static final Integer LOOKAHEAD = 64; - private final Deque pureTextFromFile = new LinkedList<>(); - private final ImportFormatPreferences importFormatPreferences; public BibtexParser(ImportFormatPreferences importFormatPreferences) { @@ -157,7 +156,7 @@ public ParserResult parse(Reader in) throws IOException { private void initializeParserResult() { database = new BibDatabase(); entryTypes = new HashMap<>(); // To store custom entry types parsed. - parserResult = new ParserResult(database, null, entryTypes); + parserResult = new ParserResult(database, new MetaData(), entryTypes); } @@ -218,7 +217,7 @@ private ParserResult parseFileContent() throws IOException { try { parserResult.setMetaData(MetaDataParser.parse(meta, importFormatPreferences.getKeywordSeparator())); } catch (ParseException exception) { - parserResult.addWarning(exception.getLocalizedMessage()); + parserResult.addException(exception); } parseRemainingContent(); diff --git a/src/main/java/net/sf/jabref/logic/importer/fileformat/MedlineImporter.java b/src/main/java/net/sf/jabref/logic/importer/fileformat/MedlineImporter.java index 25431438eef..aab11d8ed6f 100644 --- a/src/main/java/net/sf/jabref/logic/importer/fileformat/MedlineImporter.java +++ b/src/main/java/net/sf/jabref/logic/importer/fileformat/MedlineImporter.java @@ -94,6 +94,9 @@ public class MedlineImporter extends Importer implements Parser { private static final Locale ENGLISH = Locale.ENGLISH; + private static String join(List list, String string) { + return Joiner.on(string).join(list); + } @Override public String getName() { @@ -177,7 +180,7 @@ public ParserResult importDatabase(BufferedReader reader) throws IOException { } } catch (JAXBException | XMLStreamException e) { LOGGER.debug("could not parse document", e); - return ParserResult.fromErrorMessage(e.getLocalizedMessage()); + return ParserResult.fromError(e); } return new ParserResult(bibItems); } @@ -565,7 +568,6 @@ private void addArticleInformation(Map fields, List cont } } - private void addElocationID(Map fields, ELocationID eLocationID) { if (FieldName.DOI.equals(eLocationID.getEIdType())) { fields.put(FieldName.DOI, eLocationID.getContent()); @@ -646,10 +648,6 @@ private void handleAuthors(Map fields, AuthorList authors) { fields.put(FieldName.AUTHOR, join(authorNames, " and ")); } - private static String join(List list, String string) { - return Joiner.on(string).join(list); - } - private void addDateRevised(Map fields, DateRevised dateRevised) { if ((dateRevised.getDay() != null) && (dateRevised.getMonth() != null) && (dateRevised.getYear() != null)) { fields.put("revised", diff --git a/src/main/java/net/sf/jabref/logic/importer/fileformat/ModsImporter.java b/src/main/java/net/sf/jabref/logic/importer/fileformat/ModsImporter.java index e71be29b7be..2f0a1a1df9a 100644 --- a/src/main/java/net/sf/jabref/logic/importer/fileformat/ModsImporter.java +++ b/src/main/java/net/sf/jabref/logic/importer/fileformat/ModsImporter.java @@ -106,7 +106,7 @@ public ParserResult importDatabase(BufferedReader input) throws IOException { } } catch (JAXBException e) { LOGGER.debug("could not parse document", e); - return ParserResult.fromErrorMessage(e.getLocalizedMessage()); + return ParserResult.fromError(e); } return new ParserResult(bibItems); } diff --git a/src/main/java/net/sf/jabref/logic/importer/fileformat/PdfContentImporter.java b/src/main/java/net/sf/jabref/logic/importer/fileformat/PdfContentImporter.java index 75e0f05ec8f..88207991f1e 100644 --- a/src/main/java/net/sf/jabref/logic/importer/fileformat/PdfContentImporter.java +++ b/src/main/java/net/sf/jabref/logic/importer/fileformat/PdfContentImporter.java @@ -41,19 +41,14 @@ public class PdfContentImporter extends Importer { private static final Pattern YEAR_EXTRACT_PATTERN = Pattern.compile("\\d{4}"); - + private final ImportFormatPreferences importFormatPreferences; // input lines into several lines private String[] lines; - // current index in lines private int i; - private String curString; - private String year; - private final ImportFormatPreferences importFormatPreferences; - public PdfContentImporter(ImportFormatPreferences importFormatPreferences) { this.importFormatPreferences = importFormatPreferences; @@ -479,7 +474,7 @@ public ParserResult importDatabase(Path filePath, Charset defaultEncoding) { } catch (EncryptedPdfsNotSupportedException e) { return ParserResult.fromErrorMessage(Localization.lang("Decryption not supported.")); } catch(IOException exception) { - return ParserResult.fromErrorMessage(exception.getLocalizedMessage()); + return ParserResult.fromError(exception); } catch (FetcherException e) { return ParserResult.fromErrorMessage(e.getMessage()); } diff --git a/src/main/java/net/sf/jabref/logic/importer/fileformat/PdfXmpImporter.java b/src/main/java/net/sf/jabref/logic/importer/fileformat/PdfXmpImporter.java index 175081f1c84..b8daa2ac05f 100644 --- a/src/main/java/net/sf/jabref/logic/importer/fileformat/PdfXmpImporter.java +++ b/src/main/java/net/sf/jabref/logic/importer/fileformat/PdfXmpImporter.java @@ -49,7 +49,7 @@ public ParserResult importDatabase(Path filePath, Charset defaultEncoding) { try { return new ParserResult(XMPUtil.readXMP(filePath, xmpPreferences)); } catch (IOException exception) { - return ParserResult.fromErrorMessage(exception.getLocalizedMessage()); + return ParserResult.fromError(exception); } } diff --git a/src/main/java/net/sf/jabref/logic/importer/util/GroupsParser.java b/src/main/java/net/sf/jabref/logic/importer/util/GroupsParser.java index b539c38bd0d..944ff04d72c 100644 --- a/src/main/java/net/sf/jabref/logic/importer/util/GroupsParser.java +++ b/src/main/java/net/sf/jabref/logic/importer/util/GroupsParser.java @@ -113,18 +113,22 @@ private static KeywordGroup keywordGroupFromString(String s, Character keywordSe } } - public static ExplicitGroup explicitGroupFromString(String s, Character keywordSeparator) throws ParseException { - if (!s.startsWith(MetadataSerializationConfiguration.EXPLICIT_GROUP_ID)) { - throw new IllegalArgumentException("ExplicitGroup cannot be created from \"" + s + "\"."); + private static ExplicitGroup explicitGroupFromString(String input, Character keywordSeparator) throws ParseException { + if (!input.startsWith(MetadataSerializationConfiguration.EXPLICIT_GROUP_ID)) { + throw new IllegalArgumentException("ExplicitGroup cannot be created from \"" + input + "\"."); } - QuotedStringTokenizer tok = new QuotedStringTokenizer(s.substring(MetadataSerializationConfiguration.EXPLICIT_GROUP_ID.length()), + QuotedStringTokenizer tok = new QuotedStringTokenizer(input.substring(MetadataSerializationConfiguration.EXPLICIT_GROUP_ID.length()), MetadataSerializationConfiguration.GROUP_UNIT_SEPARATOR, MetadataSerializationConfiguration.GROUP_QUOTE_CHAR); String name = tok.nextToken(); - int context = Integer.parseInt(tok.nextToken()); - ExplicitGroup newGroup = new ExplicitGroup(name, GroupHierarchyType.getByNumberOrDefault(context), keywordSeparator); - GroupsParser.addLegacyEntryKeys(tok, newGroup); - return newGroup; + try { + int context = Integer.parseInt(tok.nextToken()); + ExplicitGroup newGroup = new ExplicitGroup(name, GroupHierarchyType.getByNumberOrDefault(context), keywordSeparator); + GroupsParser.addLegacyEntryKeys(tok, newGroup); + return newGroup; + } catch (NumberFormatException exception) { + throw new ParseException("Could not parse context in " + input); + } } /** @@ -140,7 +144,7 @@ private static void addLegacyEntryKeys(QuotedStringTokenizer tok, ExplicitGroup } } - public static AbstractGroup allEntriesGroupFromString(String s) { + private static AbstractGroup allEntriesGroupFromString(String s) { if (!s.startsWith(MetadataSerializationConfiguration.ALL_ENTRIES_GROUP_ID)) { throw new IllegalArgumentException("AllEntriesGroup cannot be created from \"" + s + "\"."); } @@ -153,7 +157,7 @@ public static AbstractGroup allEntriesGroupFromString(String s) { * @param s The String representation obtained from * SearchGroup.toString(), or null if incompatible */ - public static AbstractGroup searchGroupFromString(String s) { + private static AbstractGroup searchGroupFromString(String s) { if (!s.startsWith(MetadataSerializationConfiguration.SEARCH_GROUP_ID)) { throw new IllegalArgumentException("SearchGroup cannot be created from \"" + s + "\"."); } diff --git a/src/test/java/net/sf/jabref/logic/bibtex/BibEntryAssert.java b/src/test/java/net/sf/jabref/logic/bibtex/BibEntryAssert.java index e715167b09f..3fe315d8fcf 100644 --- a/src/test/java/net/sf/jabref/logic/bibtex/BibEntryAssert.java +++ b/src/test/java/net/sf/jabref/logic/bibtex/BibEntryAssert.java @@ -65,7 +65,7 @@ private static List getListFromInputStream(InputStream is) throws IOEx result = parser.parse(reader); } Assert.assertNotNull(result); - Assert.assertFalse(result.isNullResult()); + Assert.assertFalse(result.isEmpty()); return result.getDatabase().getEntries(); } diff --git a/src/test/java/net/sf/jabref/logic/importer/util/GroupsParserTest.java b/src/test/java/net/sf/jabref/logic/importer/util/GroupsParserTest.java index f6c9ac3c155..2db5b293100 100644 --- a/src/test/java/net/sf/jabref/logic/importer/util/GroupsParserTest.java +++ b/src/test/java/net/sf/jabref/logic/importer/util/GroupsParserTest.java @@ -1,5 +1,6 @@ package net.sf.jabref.logic.importer.util; +import net.sf.jabref.logic.importer.ParseException; import net.sf.jabref.model.groups.AbstractGroup; import net.sf.jabref.model.groups.ExplicitGroup; import net.sf.jabref.model.groups.GroupHierarchyType; @@ -19,4 +20,8 @@ public void fromStringParsesExplicitGroupWithEscapedCharacterInName() throws Exc assertEquals(expected, parsed); } + @Test(expected = ParseException.class) + public void fromStringThrowsParseExceptionForNotEscapedGroupName() throws Exception { + GroupsParser.fromString("ExplicitGroup:slit\\\\;0\\;mertsch_slit2_2007\\;;", ','); + } } From e781f5b568ce0ab9c181f878ec86c6302c0020c4 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Thu, 26 Jan 2017 13:21:26 +0100 Subject: [PATCH 12/14] Fix #2481: ClassCastException because of wrong cast (#2490) --- CHANGELOG.md | 1 + .../net/sf/jabref/gui/groups/GroupDialog.java | 59 +++++++++---------- 2 files changed, 29 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a7ac32dbe0b..b97d56b6608 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - Collapse and expand all buttons in the group assignment dialog no longer lead to a crash of JabRef. - The aux export command line function does no longer add duplicates of references that were resolved via `crossref`. Fixes [#2475](https://github.com/JabRef/jabref/issues/2475). - Parsing of damaged metadata is now more robust and reports a more detailed error message. Fixes [#2477](https://github.com/JabRef/jabref/issues/2477). +- Dynamic groups with regular expression can be edited again. Fixes [#2481](https://github.com/JabRef/jabref/issues/2481). ### Removed diff --git a/src/main/java/net/sf/jabref/gui/groups/GroupDialog.java b/src/main/java/net/sf/jabref/gui/groups/GroupDialog.java index 29a330580d9..ad83431b0bb 100644 --- a/src/main/java/net/sf/jabref/gui/groups/GroupDialog.java +++ b/src/main/java/net/sf/jabref/gui/groups/GroupDialog.java @@ -94,13 +94,10 @@ public Dimension getPreferredSize() { return d; } }; - + private final CardLayout optionsLayout = new CardLayout(); private boolean isOkPressed; - private AbstractGroup resultingGroup; - private final CardLayout optionsLayout = new CardLayout(); - /** * Shows a group add/edit dialog. * @@ -314,7 +311,7 @@ public void actionPerformed(ActionEvent e) { keywordsRadioButton.setSelected(true); setContext(editedGroup.getHierarchicalContext()); } else if ((editedGroup != null) && (editedGroup.getClass() == RegexKeywordGroup.class)) { - WordKeywordGroup group = (WordKeywordGroup) editedGroup; + RegexKeywordGroup group = (RegexKeywordGroup) editedGroup; nameField.setText(group.getName()); keywordGroupSearchField.setText(group.getSearchField()); keywordGroupSearchTerm.setText(group.getSearchExpression()); @@ -340,6 +337,32 @@ public void actionPerformed(ActionEvent e) { } } + private static String formatRegExException(String regExp, Exception e) { + String[] sa = e.getMessage().split("\\n"); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < sa.length; ++i) { + if (i > 0) { + sb.append("
"); + } + sb.append(StringUtil.quoteForHTML(sa[i])); + } + String s = Localization.lang( + "The regular expression %0 is invalid:", + StringUtil.quoteForHTML(regExp)) + + "

" + + sb + + ""; + if (!(e instanceof PatternSyntaxException)) { + return s; + } + int lastNewline = s.lastIndexOf("
"); + int hat = s.lastIndexOf('^'); + if ((lastNewline >= 0) && (hat >= 0) && (hat > lastNewline)) { + return s.substring(0, lastNewline + 4) + s.substring(lastNewline + 4).replace(" ", " "); + } + return s; + } + public boolean okPressed() { return isOkPressed; } @@ -433,32 +456,6 @@ private void setDescription(String description) { descriptionLabel.setText("" + description + ""); } - private static String formatRegExException(String regExp, Exception e) { - String[] sa = e.getMessage().split("\\n"); - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < sa.length; ++i) { - if (i > 0) { - sb.append("
"); - } - sb.append(StringUtil.quoteForHTML(sa[i])); - } - String s = Localization.lang( - "The regular expression %0 is invalid:", - StringUtil.quoteForHTML(regExp)) - + "

" - + sb - + ""; - if (!(e instanceof PatternSyntaxException)) { - return s; - } - int lastNewline = s.lastIndexOf("
"); - int hat = s.lastIndexOf('^'); - if ((lastNewline >= 0) && (hat >= 0) && (hat > lastNewline)) { - return s.substring(0, lastNewline + 4) + s.substring(lastNewline + 4).replace(" ", " "); - } - return s; - } - /** * Sets the font of the name entry field. */ From ed89bdae2230fdedfa66d4622ccd912bbce9ce75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Lenhard?= Date: Thu, 26 Jan 2017 13:35:39 +0100 Subject: [PATCH 13/14] =?UTF-8?q?Make=20sure=20that=20unregistered=20event?= =?UTF-8?q?=20sources=20do=20not=20stop=20JabRef=20from=20shu=E2=80=A6=20(?= =?UTF-8?q?#2487)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Make sure that unregistered event sources do not stop JabRef from shutting down * Catch unregistration exception at lowest possible level * Minor formatting improvements --- CHANGELOG.md | 3 ++- .../sf/jabref/logic/autosaveandbackup/AutosaveManager.java | 7 ++++++- .../logic/search/SearchQueryHighlightObservable.java | 6 +++++- .../java/net/sf/jabref/model/database/BibDatabase.java | 7 ++++++- src/main/java/net/sf/jabref/model/entry/BibEntry.java | 7 ++++++- src/main/java/net/sf/jabref/model/metadata/MetaData.java | 6 +++++- 6 files changed, 30 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b97d56b6608..0d068702b0e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,7 +24,8 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - The [ACM fetcher](https://help.jabref.org/en/ACMPortal) does no longer add HTML code to the bib-file. Fixes [#2472](https://github.com/JabRef/jabref/issues/2472). - When [finding unlinked files](https://help.jabref.org/en/FindUnlinkedFiles), JabRef does not freeze any more. Fixes [#2309]()https://github.com/JabRef/jabref/issues/2309). - Collapse and expand all buttons in the group assignment dialog no longer lead to a crash of JabRef. -- The aux export command line function does no longer add duplicates of references that were resolved via `crossref`. Fixes [#2475](https://github.com/JabRef/jabref/issues/2475). +- The aux export command line function does no longer add duplicates of references that were resolved via `crossref`. Fixes [#2475](https://github.com/JabRef/jabref/issues/2475). +- When the database is changed external, JabRef is no longer prevented from an orderly shutdown. Fixes [#2486](https://github.com/JabRef/jabref/issues/2486). - Parsing of damaged metadata is now more robust and reports a more detailed error message. Fixes [#2477](https://github.com/JabRef/jabref/issues/2477). - Dynamic groups with regular expression can be edited again. Fixes [#2481](https://github.com/JabRef/jabref/issues/2481). diff --git a/src/main/java/net/sf/jabref/logic/autosaveandbackup/AutosaveManager.java b/src/main/java/net/sf/jabref/logic/autosaveandbackup/AutosaveManager.java index 65908e2c971..323358afa9b 100644 --- a/src/main/java/net/sf/jabref/logic/autosaveandbackup/AutosaveManager.java +++ b/src/main/java/net/sf/jabref/logic/autosaveandbackup/AutosaveManager.java @@ -89,6 +89,11 @@ public void registerListener(Object listener) { } public void unregisterListener(Object listener) { - eventBus.unregister(listener); + try { + eventBus.unregister(listener); + } catch (IllegalArgumentException e) { + // occurs if the event source has not been registered, should not prevent shutdown + LOGGER.debug(e); + } } } diff --git a/src/main/java/net/sf/jabref/logic/search/SearchQueryHighlightObservable.java b/src/main/java/net/sf/jabref/logic/search/SearchQueryHighlightObservable.java index d7e4144e84a..2902fa749d5 100644 --- a/src/main/java/net/sf/jabref/logic/search/SearchQueryHighlightObservable.java +++ b/src/main/java/net/sf/jabref/logic/search/SearchQueryHighlightObservable.java @@ -31,7 +31,11 @@ public void addSearchListener(SearchQueryHighlightListener newListener) { public void removeSearchListener(SearchQueryHighlightListener listener) { Objects.requireNonNull(listener); - eventBus.unregister(listener); + try { + eventBus.unregister(listener); + } catch (IllegalArgumentException e) { + // occurs if the event source has not been registered, should not prevent shutdown + } } /** * Fires an event if a search was started (or cleared) diff --git a/src/main/java/net/sf/jabref/model/database/BibDatabase.java b/src/main/java/net/sf/jabref/model/database/BibDatabase.java index b19e3a66523..fdd4e1e3cda 100644 --- a/src/main/java/net/sf/jabref/model/database/BibDatabase.java +++ b/src/main/java/net/sf/jabref/model/database/BibDatabase.java @@ -530,7 +530,12 @@ public void registerListener(Object listener) { * @param listener listener (subscriber) to remove */ public void unregisterListener(Object listener) { - this.eventBus.unregister(listener); + try { + this.eventBus.unregister(listener); + } catch (IllegalArgumentException e) { + // occurs if the event source has not been registered, should not prevent shutdown + LOGGER.debug(e); + } } @Subscribe diff --git a/src/main/java/net/sf/jabref/model/entry/BibEntry.java b/src/main/java/net/sf/jabref/model/entry/BibEntry.java index f1e55b73751..7656456ff28 100644 --- a/src/main/java/net/sf/jabref/model/entry/BibEntry.java +++ b/src/main/java/net/sf/jabref/model/entry/BibEntry.java @@ -764,7 +764,12 @@ public void registerListener(Object object) { } public void unregisterListener(Object object) { - this.eventBus.unregister(object); + try { + this.eventBus.unregister(object); + } catch (IllegalArgumentException e) { + // occurs if the event source has not been registered, should not prevent shutdown + LOGGER.debug(e); + } } public BibEntry withField(String field, String value) { diff --git a/src/main/java/net/sf/jabref/model/metadata/MetaData.java b/src/main/java/net/sf/jabref/model/metadata/MetaData.java index c55e3d52718..c9be65a839f 100644 --- a/src/main/java/net/sf/jabref/model/metadata/MetaData.java +++ b/src/main/java/net/sf/jabref/model/metadata/MetaData.java @@ -254,7 +254,11 @@ public void registerListener(Object listener) { } public void unregisterListener(Object listener) { - this.eventBus.unregister(listener); + try { + this.eventBus.unregister(listener); + } catch (IllegalArgumentException e) { + // occurs if the event source has not been registered, should not prevent shutdown + } } private Optional getDefaultCiteKeyPattern() { From 8c5ed80227e3c8d05bbb2fb0387cf02f5f0d23e1 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Thu, 26 Jan 2017 19:33:34 +0100 Subject: [PATCH 14/14] Fix medline tests...again (#2492) --- .../sf/jabref/logic/importer/fetcher/MedlineFetcherTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/net/sf/jabref/logic/importer/fetcher/MedlineFetcherTest.java b/src/test/java/net/sf/jabref/logic/importer/fetcher/MedlineFetcherTest.java index 8328b914d4f..d7f99410f1d 100644 --- a/src/test/java/net/sf/jabref/logic/importer/fetcher/MedlineFetcherTest.java +++ b/src/test/java/net/sf/jabref/logic/importer/fetcher/MedlineFetcherTest.java @@ -30,7 +30,7 @@ public void setUp() { entryWijedasa = new BibEntry(); entryWijedasa.setType(BibLatexEntryTypes.ARTICLE); - entryWijedasa.setField("author","Wijedasa, Lahiru S and Jauhiainen, Jyrki and Önönen, Mari K and Lampela, Maija and Vasander, Harri and Leblanc, Marie-Claire and Evers, Stephanie and Smith, Thomas E L and Yule, Catherine M and Varkkey, Helena and Lupascu, Massimo and Parish, Faizal and Singleton, Ian and Clements, Gopalasamy R and Aziz, Sheema Abdul and Harrison, Mark E and Cheyne, Susan and Anshari, Gusti Z and Meijaard, Erik and Goldstein, Jenny E and Waldron, Susan and Hergoualc'h, Kristell and Dommain, Rene and Frolking, Steve and Evans, Christopher D and Posa, Mary Rose C and Glaser, Paul H and Suryadiputra, Nyoman and Lubis, Reza and Santika, Truly and Padfield, Rory and Kurnianto, Sofyan and Hadisiswoyo, Panut and Lim, Teck Wyn and Page, Susan E and Gauci, Vincent and Van Der Meer, Peter J and Buckland, Helen and Garnier, Fabien and Samuel, Marshall K and Choo, Liza Nuriati Lim Kim and O'Reilly, Patrick and Warren, Matthew and Suksuwan, Surin and Sumarga, Elham and Jain, Anuj and Laurance, William F and Couwenberg, John and Joosten, Hans and Vernimmen, Ronald and Hooijer, Aljosja and Malins, Chris and Cochrane, Mark A and Perumal, Balu and Siegert, Florian and Peh, Kelvin S-H and Comeau, Louis-Pierre and Verchot, Louis and Harvey, Charles F and Cobb, Alex and Jaafar, Zeehan and Wösten, Henk and Manuri, Solichin and Müller, Moritz and Giesen, Wim and Phelps, Jacob and Yong, Ding Li and Silvius, Marcel and Wedeux, Béatrice M M and Hoyt, Alison and Osaki, Mitsuru and Hirano, Takashi and Takahashi, Hidenori and Kohyama, Takashi S and Haraguchi, Akira and Nugroho, Nunung P and Coomes, David A and Quoi, Le Phat and Dohong, Alue and Gunawan, Haris and Gaveau, David L A and Langner, Andreas and Lim, Felix K S and Edwards, David P and Giam, Xingli and Van Der Werf, Guido and Carmenta, Rachel and Verwer, Caspar C and Gibson, Luke and Gandois, Laure and Graham, Laura Linda Bozena and Regalino, Jhanson and Wich, Serge A and Rieley, Jack and Kettridge, Nicholas and Brown, Chloe and Pirard, Romain and Moore, Sam and Capilla, B Ripoll and Ballhorn, Uwe and Ho, Hua Chew and Hoscilo, Agata and Lohberger, Sandra and Evans, Theodore A and Yulianti, Nina and Blackham, Grace and Onrizal and Husson, Simon and Murdiyarso, Daniel and Pangala, Sunita and Cole, Lydia E S and Tacconi, Luca and Segah, Hendrik and Tonoto, Prayoto and Lee, Janice S H and Schmilewski, Gerald and Wulffraat, Stephan and Putra, Erianto Indra and Cattau, Megan E and Clymo, R S and Morrison, Ross and Mujahid, Aazani and Miettinen, Jukka and Liew, Soo Chin and Valpola, Samu and Wilson, David and D'Arcy, Laura and Gerding, Michiel and Sundari, Siti and Thornton, Sara A and Kalisz, Barbara and Chapman, Stephen J and Su, Ahmad Suhaizi Mat and Basuki, Imam and Itoh, Masayuki and Traeholt, Carl and Sloan, Sean and Sayok, Alexander K and Andersen, Roxane"); + entryWijedasa.setField("author","Wijedasa, Lahiru S and Jauhiainen, Jyrki and Könönen, Mari and Lampela, Maija and Vasander, Harri and Leblanc, Marie-Claire and Evers, Stephanie and Smith, Thomas E L and Yule, Catherine M and Varkkey, Helena and Lupascu, Massimo and Parish, Faizal and Singleton, Ian and Clements, Gopalasamy R and Aziz, Sheema Abdul and Harrison, Mark E and Cheyne, Susan and Anshari, Gusti Z and Meijaard, Erik and Goldstein, Jenny E and Waldron, Susan and Hergoualc'h, Kristell and Dommain, Rene and Frolking, Steve and Evans, Christopher D and Posa, Mary Rose C and Glaser, Paul H and Suryadiputra, Nyoman and Lubis, Reza and Santika, Truly and Padfield, Rory and Kurnianto, Sofyan and Hadisiswoyo, Panut and Lim, Teck Wyn and Page, Susan E and Gauci, Vincent and Van Der Meer, Peter J and Buckland, Helen and Garnier, Fabien and Samuel, Marshall K and Choo, Liza Nuriati Lim Kim and O'Reilly, Patrick and Warren, Matthew and Suksuwan, Surin and Sumarga, Elham and Jain, Anuj and Laurance, William F and Couwenberg, John and Joosten, Hans and Vernimmen, Ronald and Hooijer, Aljosja and Malins, Chris and Cochrane, Mark A and Perumal, Balu and Siegert, Florian and Peh, Kelvin S-H and Comeau, Louis-Pierre and Verchot, Louis and Harvey, Charles F and Cobb, Alex and Jaafar, Zeehan and Wösten, Henk and Manuri, Solichin and Müller, Moritz and Giesen, Wim and Phelps, Jacob and Yong, Ding Li and Silvius, Marcel and Wedeux, Béatrice M M and Hoyt, Alison and Osaki, Mitsuru and Hirano, Takashi and Takahashi, Hidenori and Kohyama, Takashi S and Haraguchi, Akira and Nugroho, Nunung P and Coomes, David A and Quoi, Le Phat and Dohong, Alue and Gunawan, Haris and Gaveau, David L A and Langner, Andreas and Lim, Felix K S and Edwards, David P and Giam, Xingli and Van Der Werf, Guido and Carmenta, Rachel and Verwer, Caspar C and Gibson, Luke and Gandois, Laure and Graham, Laura Linda Bozena and Regalino, Jhanson and Wich, Serge A and Rieley, Jack and Kettridge, Nicholas and Brown, Chloe and Pirard, Romain and Moore, Sam and Capilla, B Ripoll and Ballhorn, Uwe and Ho, Hua Chew and Hoscilo, Agata and Lohberger, Sandra and Evans, Theodore A and Yulianti, Nina and Blackham, Grace and Onrizal and Husson, Simon and Murdiyarso, Daniel and Pangala, Sunita and Cole, Lydia E S and Tacconi, Luca and Segah, Hendrik and Tonoto, Prayoto and Lee, Janice S H and Schmilewski, Gerald and Wulffraat, Stephan and Putra, Erianto Indra and Cattau, Megan E and Clymo, R S and Morrison, Ross and Mujahid, Aazani and Miettinen, Jukka and Liew, Soo Chin and Valpola, Samu and Wilson, David and D'Arcy, Laura and Gerding, Michiel and Sundari, Siti and Thornton, Sara A and Kalisz, Barbara and Chapman, Stephen J and Su, Ahmad Suhaizi Mat and Basuki, Imam and Itoh, Masayuki and Traeholt, Carl and Sloan, Sean and Sayok, Alexander K and Andersen, Roxane"); entryWijedasa.setField("created", "2016-09-27"); entryWijedasa.setField("country", "England"); @@ -44,7 +44,7 @@ public void setUp() { entryWijedasa.setField("pmid", "27670948"); entryWijedasa.setField("pubmodel", "Print-Electronic"); entryWijedasa.setField("pubstatus", "aheadofprint"); - entryWijedasa.setField("revised", "2017-01-10"); + entryWijedasa.setField("revised", "2017-01-24"); entryWijedasa.setField("title", "Denial of long-term issues with agriculture on tropical peatlands will have devastating consequences."); entryWijedasa.setField("year", "2016");