From e09a749f858f03eecf4830451e098075443f7e44 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Mon, 2 Oct 2017 20:25:09 +0200 Subject: [PATCH 1/7] use crossref information when generating bibtexkeys --- .../jabref/gui/entryeditor/EntryEditor.java | 20 +-- .../BibtexKeyPatternUtil.java | 56 +++---- .../java/org/jabref/model/entry/BibEntry.java | 9 ++ .../BibtexKeyPatternUtilTest.java | 153 ++++++++++++++++++ .../org/jabref/model/entry/BibEntryTest.java | 74 +++++++++ 5 files changed, 275 insertions(+), 37 deletions(-) diff --git a/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java b/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java index b483727e305..4ff62fad14e 100644 --- a/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java +++ b/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java @@ -886,15 +886,17 @@ public void actionPerformed(ActionEvent e) { panel.getDatabase(), entry, Globals.prefs.getBibtexKeyPatternPreferences()); - // Store undo information: - panel.getUndoManager().addEdit( - new UndoableKeyChange(entry, oldValue.orElse(null), - entry.getCiteKeyOptional().get())); // Cite key always set here - - // here we update the field - String bibtexKeyData = entry.getCiteKeyOptional().get(); - entry.setField(BibEntry.KEY_FIELD, bibtexKeyData); - panel.markBaseChanged(); + if (entry.hasCiteKey()) { + // Store undo information: + panel.getUndoManager().addEdit( + new UndoableKeyChange(entry, oldValue.orElse(null), + entry.getCiteKeyOptional().get())); // Cite key always set here + + // here we update the field + String bibtexKeyData = entry.getCiteKeyOptional().get(); + entry.setField(BibEntry.KEY_FIELD, bibtexKeyData); + panel.markBaseChanged(); + } } } diff --git a/src/main/java/org/jabref/logic/bibtexkeypattern/BibtexKeyPatternUtil.java b/src/main/java/org/jabref/logic/bibtexkeypattern/BibtexKeyPatternUtil.java index 7e1a1c74d72..5b6034e1f62 100644 --- a/src/main/java/org/jabref/logic/bibtexkeypattern/BibtexKeyPatternUtil.java +++ b/src/main/java/org/jabref/logic/bibtexkeypattern/BibtexKeyPatternUtil.java @@ -526,10 +526,10 @@ public static String makeLabel(BibEntry entry, String value, Character keywordDe */ String authString; if (database != null) { - authString = entry.getField(FieldName.AUTHOR) + authString = entry.getResolvedFieldOrAlias(FieldName.AUTHOR, database) .map(authorString -> normalize(database.resolveForStrings(authorString))).orElse(""); } else { - authString = entry.getField(FieldName.AUTHOR).orElse(""); + authString = entry.getResolvedFieldOrAlias(FieldName.AUTHOR, database).orElse(""); } if (val.startsWith("pure")) { @@ -540,10 +540,10 @@ public static String makeLabel(BibEntry entry, String value, Character keywordDe if (authString.isEmpty()) { if (database != null) { - authString = entry.getField(FieldName.EDITOR) + authString = entry.getResolvedFieldOrAlias(FieldName.EDITOR, database) .map(authorString -> normalize(database.resolveForStrings(authorString))).orElse(""); } else { - authString = entry.getField(FieldName.EDITOR).orElse(""); + authString = entry.getResolvedFieldOrAlias(FieldName.EDITOR, database).orElse(""); } } @@ -597,41 +597,41 @@ else if ("authorLast".equals(val)) { } else { // This "auth" business was a dead end, so just // use it literally: - return entry.getFieldOrAlias(val).orElse(""); + return entry.getResolvedFieldOrAlias(val, database).orElse(""); } } else if (val.startsWith("ed")) { // Gather all markers starting with "ed" here, so we // don't have to check all the time. if ("edtr".equals(val)) { - return firstAuthor(entry.getField(FieldName.EDITOR).orElse("")); + return firstAuthor(entry.getResolvedFieldOrAlias(FieldName.EDITOR, database).orElse("")); } else if ("edtrForeIni".equals(val)) { - return firstAuthorForenameInitials(entry.getField(FieldName.EDITOR).orElse("")); + return firstAuthorForenameInitials(entry.getResolvedFieldOrAlias(FieldName.EDITOR, database).orElse("")); } else if ("editors".equals(val)) { - return allAuthors(entry.getField(FieldName.EDITOR).orElse("")); + return allAuthors(entry.getResolvedFieldOrAlias(FieldName.EDITOR, database).orElse("")); // Last author's last name } else if ("editorLast".equals(val)) { - return lastAuthor(entry.getField(FieldName.EDITOR).orElse("")); + return lastAuthor(entry.getResolvedFieldOrAlias(FieldName.EDITOR, database).orElse("")); } else if ("editorLastForeIni".equals(val)) { - return lastAuthorForenameInitials(entry.getField(FieldName.EDITOR).orElse("")); + return lastAuthorForenameInitials(entry.getResolvedFieldOrAlias(FieldName.EDITOR, database).orElse("")); } else if ("editorIni".equals(val)) { - return oneAuthorPlusIni(entry.getField(FieldName.EDITOR).orElse("")); + return oneAuthorPlusIni(entry.getResolvedFieldOrAlias(FieldName.EDITOR, database).orElse("")); } else if (val.matches("edtrIni[\\d]+")) { int num = Integer.parseInt(val.substring(7)); - return authIniN(entry.getField(FieldName.EDITOR).orElse(""), num); + return authIniN(entry.getResolvedFieldOrAlias(FieldName.EDITOR, database).orElse(""), num); } else if (val.matches("edtr[\\d]+_[\\d]+")) { String[] nums = val.substring(4).split("_"); - return authNofMth(entry.getField(FieldName.EDITOR).orElse(""), + return authNofMth(entry.getResolvedFieldOrAlias(FieldName.EDITOR, database).orElse(""), Integer.parseInt(nums[0]), Integer.parseInt(nums[1]) - 1); } else if ("edtr.edtr.ea".equals(val)) { - return authAuthEa(entry.getField(FieldName.EDITOR).orElse("")); + return authAuthEa(entry.getResolvedFieldOrAlias(FieldName.EDITOR, database).orElse("")); } else if ("edtrshort".equals(val)) { - return authshort(entry.getField(FieldName.EDITOR).orElse("")); + return authshort(entry.getResolvedFieldOrAlias(FieldName.EDITOR, database).orElse("")); } // authN. First N chars of the first author's last // name. else if (val.matches("edtr\\d+")) { - String fa = firstAuthor(entry.getField(FieldName.EDITOR).orElse("")); + String fa = firstAuthor(entry.getResolvedFieldOrAlias(FieldName.EDITOR, database).orElse("")); int num = Integer.parseInt(val.substring(4)); if (num > fa.length()) { num = fa.length(); @@ -643,26 +643,26 @@ else if (val.matches("edtr\\d+")) { return entry.getFieldOrAlias(val).orElse(""); } } else if ("firstpage".equals(val)) { - return firstPage(entry.getField(FieldName.PAGES).orElse("")); + return firstPage(entry.getResolvedFieldOrAlias(FieldName.PAGES, database).orElse("")); } else if ("pageprefix".equals(val)) { - return pagePrefix(entry.getField(FieldName.PAGES).orElse("")); + return pagePrefix(entry.getResolvedFieldOrAlias(FieldName.PAGES, database).orElse("")); } else if ("lastpage".equals(val)) { - return lastPage(entry.getField(FieldName.PAGES).orElse("")); + return lastPage(entry.getResolvedFieldOrAlias(FieldName.PAGES, database).orElse("")); } else if ("title".equals(val)) { - return camelizeSignificantWordsInTitle(entry.getField(FieldName.TITLE).orElse("")); + return camelizeSignificantWordsInTitle(entry.getResolvedFieldOrAlias(FieldName.TITLE, database).orElse("")); } else if ("shorttitle".equals(val)) { - return getTitleWords(3, entry.getField(FieldName.TITLE).orElse("")); + return getTitleWords(3, entry.getResolvedFieldOrAlias(FieldName.TITLE, database).orElse("")); } else if ("shorttitleINI".equals(val)) { return keepLettersAndDigitsOnly( - applyModifiers(getTitleWordsWithSpaces(3, entry.getField(FieldName.TITLE).orElse("")), + applyModifiers(getTitleWordsWithSpaces(3, entry.getResolvedFieldOrAlias(FieldName.TITLE, database).orElse("")), Collections.singletonList("abbr"), 0)); } else if ("veryshorttitle".equals(val)) { return getTitleWords(1, - removeSmallWords(entry.getField(FieldName.TITLE).orElse(""))); + removeSmallWords(entry.getResolvedFieldOrAlias(FieldName.TITLE, database).orElse(""))); } else if ("camel".equals(val)) { - return getCamelizedTitle(entry.getField(FieldName.TITLE).orElse("")); + return getCamelizedTitle(entry.getResolvedFieldOrAlias(FieldName.TITLE, database).orElse("")); } else if ("shortyear".equals(val)) { - String yearString = entry.getFieldOrAlias(FieldName.YEAR).orElse(""); + String yearString = entry.getResolvedFieldOrAlias(FieldName.YEAR, database).orElse(""); if (yearString.isEmpty()) { return yearString; // In press/in preparation/submitted @@ -676,7 +676,7 @@ else if (val.matches("edtr\\d+")) { } else if (val.matches("keyword\\d+")) { // according to LabelPattern.php, it returns keyword number n int num = Integer.parseInt(val.substring(7)); - KeywordList separatedKeywords = entry.getKeywords(keywordDelimiter); + KeywordList separatedKeywords = entry.getResolvedKeywords(keywordDelimiter, database); if (separatedKeywords.size() < num) { // not enough keywords return ""; @@ -692,7 +692,7 @@ else if (val.matches("edtr\\d+")) { } else { num = Integer.MAX_VALUE; } - KeywordList separatedKeywords = entry.getKeywords(keywordDelimiter); + KeywordList separatedKeywords = entry.getResolvedKeywords(keywordDelimiter, database); StringBuilder sb = new StringBuilder(); int i = 0; for (Keyword keyword : separatedKeywords) { @@ -707,7 +707,7 @@ else if (val.matches("edtr\\d+")) { return sb.toString(); } else { // we haven't seen any special demands - return entry.getFieldOrAlias(val).orElse(""); + return entry.getResolvedFieldOrAlias(val, database).orElse(""); } } catch (NullPointerException ex) { LOGGER.debug("Problem making label", ex); diff --git a/src/main/java/org/jabref/model/entry/BibEntry.java b/src/main/java/org/jabref/model/entry/BibEntry.java index 5aca2e2259a..911247420b3 100644 --- a/src/main/java/org/jabref/model/entry/BibEntry.java +++ b/src/main/java/org/jabref/model/entry/BibEntry.java @@ -687,6 +687,15 @@ public KeywordList getKeywords(Character delimiter) { } } + public KeywordList getResolvedKeywords(Character delimiter, BibDatabase database) { + Optional keywordsContent = getResolvedFieldOrAlias(FieldName.KEYWORDS, database); + if (keywordsContent.isPresent()) { + return KeywordList.parse(keywordsContent.get(), delimiter); + } else { + return new KeywordList(); + } + } + public Collection getFieldValues() { return fields.values(); } diff --git a/src/test/java/org/jabref/logic/bibtexkeypattern/BibtexKeyPatternUtilTest.java b/src/test/java/org/jabref/logic/bibtexkeypattern/BibtexKeyPatternUtilTest.java index 2effe148fff..52e827b49ed 100644 --- a/src/test/java/org/jabref/logic/bibtexkeypattern/BibtexKeyPatternUtilTest.java +++ b/src/test/java/org/jabref/logic/bibtexkeypattern/BibtexKeyPatternUtilTest.java @@ -7,6 +7,7 @@ import org.jabref.logic.importer.fileformat.BibtexParser; import org.jabref.model.database.BibDatabase; import org.jabref.model.entry.BibEntry; +import org.jabref.model.entry.FieldName; import org.junit.Before; import org.junit.Test; @@ -56,6 +57,21 @@ public void testAndInAuthorName() throws ParseException { ',', new BibDatabase()), true)); } + @Test + public void testCrossrefAndInAuthorNames() throws ParseException { + BibDatabase database = new BibDatabase(); + BibEntry entry1 = new BibEntry(); + entry1.setField(FieldName.CROSSREF, "entry2"); + database.insertEntry(entry1); + String bibtexString = "@ARTICLE{entry2, author={Simon Holland}}"; + BibEntry entry2 = BibtexParser.singleFromString(bibtexString, importFormatPreferences).get(); + database.insertEntry(entry2); + + assertEquals("Holland", + BibtexKeyPatternUtil.checkLegalKey(BibtexKeyPatternUtil.makeLabel(entry1, "auth", + ',', database), true)); + } + @Test public void testAndAuthorNames() throws ParseException { String bibtexString = "@ARTICLE{whatevery, author={Mari D. Herland and Mona-Iren Hauge and Ingeborg M. Helgeland}}"; @@ -65,6 +81,22 @@ public void testAndAuthorNames() throws ParseException { ',', new BibDatabase()), true)); } + @Test + public void testCrossrefAndAuthorNames() throws ParseException { + BibDatabase database = new BibDatabase(); + BibEntry entry1 = new BibEntry(); + entry1.setField(FieldName.CROSSREF, "entry2"); + database.insertEntry(entry1); + String bibtexString = "@ARTICLE{entry2, author={Mari D. Herland and Mona-Iren Hauge and Ingeborg M. Helgeland}}"; + BibEntry entry2 = BibtexParser.singleFromString(bibtexString, importFormatPreferences).get(); + database.insertEntry(entry2); + System.out.println(entry1.getResolvedFieldOrAlias(FieldName.AUTHOR, database)); + + assertEquals("HerlandHaugeHelgeland", + BibtexKeyPatternUtil.checkLegalKey(BibtexKeyPatternUtil.makeLabel(entry1, "authors3", + ',', database), true)); + } + @Test public void testSpecialLatexCharacterInAuthorName() throws ParseException { Optional entry = BibtexParser.singleFromString( @@ -279,6 +311,21 @@ public void testUniversity() throws ParseException { ',', new BibDatabase()), true)); } + @Test + public void testcrossrefUniversity() throws ParseException { + BibDatabase database = new BibDatabase(); + BibEntry entry1 = new BibEntry(); + entry1.setField(FieldName.CROSSREF, "entry2"); + database.insertEntry(entry1); + String bibtexString = "@ARTICLE{entry2, author={{Link{\\\"{o}}ping University}}}"; + BibEntry entry2 = BibtexParser.singleFromString(bibtexString, importFormatPreferences).get(); + database.insertEntry(entry2); + + assertEquals("UniLinkoeping", + BibtexKeyPatternUtil.checkLegalKey(BibtexKeyPatternUtil.makeLabel(entry1, "auth", + ',', database), true)); + } + @Test public void testDepartment() throws ParseException { Optional entry = BibtexParser.singleFromString( @@ -289,6 +336,21 @@ public void testDepartment() throws ParseException { ',', new BibDatabase()), true)); } + @Test + public void testcrossrefDepartment() throws ParseException { + BibDatabase database = new BibDatabase(); + BibEntry entry1 = new BibEntry(); + entry1.setField(FieldName.CROSSREF, "entry2"); + database.insertEntry(entry1); + String bibtexString = "@ARTICLE{entry2, author={{Link{\\\"{o}}ping University, Department of Electrical Engineering}}}"; + BibEntry entry2 = BibtexParser.singleFromString(bibtexString, importFormatPreferences).get(); + database.insertEntry(entry2); + + assertEquals("UniLinkoepingEE", + BibtexKeyPatternUtil.checkLegalKey(BibtexKeyPatternUtil.makeLabel(entry1, "auth", + ',', database), true)); + } + @Test public void testSchool() throws ParseException { Optional entry = BibtexParser.singleFromString( @@ -299,6 +361,21 @@ public void testSchool() throws ParseException { ',', new BibDatabase()), true)); } + @Test + public void testcrossrefSchool() throws ParseException { + BibDatabase database = new BibDatabase(); + BibEntry entry1 = new BibEntry(); + entry1.setField(FieldName.CROSSREF, "entry2"); + database.insertEntry(entry1); + String bibtexString = "@ARTICLE{entry2, author={{Link{\\\"{o}}ping University, School of Computer Engineering}}}"; + BibEntry entry2 = BibtexParser.singleFromString(bibtexString, importFormatPreferences).get(); + database.insertEntry(entry2); + + assertEquals("UniLinkoepingCE", + BibtexKeyPatternUtil.checkLegalKey(BibtexKeyPatternUtil.makeLabel(entry1, "auth", + ',', database), true)); + } + @Test public void testInstituteOfTechnology() throws ParseException { Optional entry = BibtexParser.singleFromString( @@ -308,6 +385,21 @@ public void testInstituteOfTechnology() throws ParseException { ',', new BibDatabase()), true)); } + @Test + public void testcrossrefInstituteOfTechnology() throws ParseException { + BibDatabase database = new BibDatabase(); + BibEntry entry1 = new BibEntry(); + entry1.setField(FieldName.CROSSREF, "entry2"); + database.insertEntry(entry1); + String bibtexString = "@ARTICLE{entry2, author={{Massachusetts Institute of Technology}}}"; + BibEntry entry2 = BibtexParser.singleFromString(bibtexString, importFormatPreferences).get(); + database.insertEntry(entry2); + + assertEquals("MIT", + BibtexKeyPatternUtil.checkLegalKey(BibtexKeyPatternUtil.makeLabel(entry1, "auth", + ',', database), true)); + } + @Test public void testAuthIniN() { assertEquals("NMEB", BibtexKeyPatternUtil.authIniN(AUTHOR_STRING_FIRSTNAME_INITIAL_LASTNAME_FULL_COUNT_5, 4)); @@ -766,6 +858,22 @@ public void keywordNKeywordsSeparatedBySpace() { assertEquals("", result); } + @Test + public void crossrefkeywordNKeywordsSeparatedBySpace() { + BibDatabase database = new BibDatabase(); + BibEntry entry1 = new BibEntry(); + BibEntry entry2 = new BibEntry(); + entry1.setField(FieldName.CROSSREF, "entry2"); + entry2.setCiteKey("entry2"); + database.insertEntry(entry2); + database.insertEntry(entry1); + entry2.setField("keywords", "w1, w2a w2b, w3"); + + String result = BibtexKeyPatternUtil.makeLabel(entry1, "keyword1", ',', database); + + assertEquals("w1", result); + } + @Test public void keywordsNKeywordsSeparatedBySpace() { BibEntry entry = new BibEntry(); @@ -784,6 +892,22 @@ public void keywordsNKeywordsSeparatedBySpace() { assertEquals("w1w2aw2bw3", result); } + @Test + public void crossrefkeywordsNKeywordsSeparatedBySpace() { + BibDatabase database = new BibDatabase(); + BibEntry entry1 = new BibEntry(); + BibEntry entry2 = new BibEntry(); + entry1.setField(FieldName.CROSSREF, "entry2"); + entry2.setCiteKey("entry2"); + database.insertEntry(entry2); + database.insertEntry(entry1); + entry2.setField("keywords", "w1, w2a w2b, w3"); + + String result = BibtexKeyPatternUtil.makeLabel(entry1, "keywords", ',', database); + + assertEquals("w1w2aw2bw3", result); + } + @Test public void testCheckLegalKeyEnforceLegal() { assertEquals("AAAA", BibtexKeyPatternUtil.checkLegalKey("AA AA", true)); @@ -813,4 +937,33 @@ public void testApplyModifiers() { ',', new BibDatabase())); } + @Test + public void testcrossrefShorttitle() { + BibDatabase database = new BibDatabase(); + BibEntry entry1 = new BibEntry(); + BibEntry entry2 = new BibEntry(); + entry1.setField(FieldName.CROSSREF, "entry2"); + entry2.setCiteKey("entry2"); + database.insertEntry(entry2); + database.insertEntry(entry1); + entry2.setField("title", "Green Scheduling of Whatever"); + + assertEquals("Green Scheduling of", BibtexKeyPatternUtil.makeLabel(entry1, "shorttitle", + ',', database)); + } + + @Test + public void testcrossrefShorttitleInitials() { + BibDatabase database = new BibDatabase(); + BibEntry entry1 = new BibEntry(); + BibEntry entry2 = new BibEntry(); + entry1.setField(FieldName.CROSSREF, "entry2"); + entry2.setCiteKey("entry2"); + database.insertEntry(entry2); + database.insertEntry(entry1); + entry2.setField("title", "Green Scheduling of Whatever"); + + assertEquals("GSo", BibtexKeyPatternUtil.makeLabel(entry1, "shorttitleINI", ',', database)); + } + } diff --git a/src/test/java/org/jabref/model/entry/BibEntryTest.java b/src/test/java/org/jabref/model/entry/BibEntryTest.java index 7079a31438c..5cbea9d9477 100644 --- a/src/test/java/org/jabref/model/entry/BibEntryTest.java +++ b/src/test/java/org/jabref/model/entry/BibEntryTest.java @@ -4,6 +4,8 @@ import java.util.List; import java.util.Optional; +import org.jabref.model.database.BibDatabase; + import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -57,4 +59,76 @@ public void testGetAndAddToLinkedFileList() { entry.setFiles(files); assertEquals(Arrays.asList(new LinkedFile("", "", "")), entry.getFiles()); } + + @Test + public void testGetEmptyKeywords() { + KeywordList actual = entry.getKeywords(','); + + assertEquals(new KeywordList(), actual); + } + + @Test + public void testGetSingleKeywords() { + entry.addKeyword("kw", ','); + KeywordList actual = entry.getKeywords(','); + + assertEquals(new KeywordList(new Keyword("kw")), actual); + } + + @Test + public void testGetKeywords() { + entry.addKeyword("kw", ','); + entry.addKeyword("kw2", ','); + entry.addKeyword("kw3", ','); + KeywordList actual = entry.getKeywords(','); + + assertEquals(new KeywordList(new Keyword("kw"), new Keyword("kw2"), new Keyword("kw3")), actual); + } + + @Test + public void testGetEmptyResolvedKeywords() { + BibDatabase database = new BibDatabase(); + BibEntry entry2 = new BibEntry(); + entry.setField(FieldName.CROSSREF, "entry2"); + entry2.setCiteKey("entry2"); + database.insertEntry(entry2); + database.insertEntry(entry); + + KeywordList actual = entry.getResolvedKeywords(',', database); + + assertEquals(new KeywordList(), actual); + } + + @Test + public void testGetSingleResolvedKeywords() { + BibDatabase database = new BibDatabase(); + BibEntry entry2 = new BibEntry(); + entry.setField(FieldName.CROSSREF, "entry2"); + entry2.setCiteKey("entry2"); + entry2.addKeyword("kw", ','); + database.insertEntry(entry2); + database.insertEntry(entry); + + KeywordList actual = entry.getResolvedKeywords(',', database); + + assertEquals(new KeywordList(new Keyword("kw")), actual); + } + + @Test + public void testGetResolvedKeywords() { + BibDatabase database = new BibDatabase(); + BibEntry entry2 = new BibEntry(); + entry.setField(FieldName.CROSSREF, "entry2"); + entry2.setCiteKey("entry2"); + entry2.addKeyword("kw", ','); + entry2.addKeyword("kw2", ','); + entry2.addKeyword("kw3", ','); + database.insertEntry(entry2); + database.insertEntry(entry); + + KeywordList actual = entry.getResolvedKeywords(',', database); + + assertEquals(new KeywordList(new Keyword("kw"), new Keyword("kw2"), new Keyword("kw3")), actual); + } + } From 646b9d07fafe4f70e9e060ae5c9b26296a0fa143 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Mon, 2 Oct 2017 21:22:42 +0200 Subject: [PATCH 2/7] create KeywordList#parse(Optional, Character) --- .../java/org/jabref/model/entry/BibEntry.java | 12 ++-------- .../org/jabref/model/entry/KeywordList.java | 11 +++++++++ .../jabref/model/entry/KeywordListTest.java | 24 +++++++++++++++++++ 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/jabref/model/entry/BibEntry.java b/src/main/java/org/jabref/model/entry/BibEntry.java index 911247420b3..d383b09b5c9 100644 --- a/src/main/java/org/jabref/model/entry/BibEntry.java +++ b/src/main/java/org/jabref/model/entry/BibEntry.java @@ -680,20 +680,12 @@ public void addKeywords(Collection keywords, Character delimiter) { public KeywordList getKeywords(Character delimiter) { Optional keywordsContent = getField(FieldName.KEYWORDS); - if (keywordsContent.isPresent()) { - return KeywordList.parse(keywordsContent.get(), delimiter); - } else { - return new KeywordList(); - } + return KeywordList.parse(keywordsContent, delimiter); } public KeywordList getResolvedKeywords(Character delimiter, BibDatabase database) { Optional keywordsContent = getResolvedFieldOrAlias(FieldName.KEYWORDS, database); - if (keywordsContent.isPresent()) { - return KeywordList.parse(keywordsContent.get(), delimiter); - } else { - return new KeywordList(); - } + return KeywordList.parse(keywordsContent, delimiter); } public Collection getFieldValues() { diff --git a/src/main/java/org/jabref/model/entry/KeywordList.java b/src/main/java/org/jabref/model/entry/KeywordList.java index c9e435a762f..4aa3de99fb3 100644 --- a/src/main/java/org/jabref/model/entry/KeywordList.java +++ b/src/main/java/org/jabref/model/entry/KeywordList.java @@ -6,6 +6,7 @@ import java.util.Iterator; import java.util.List; import java.util.Objects; +import java.util.Optional; import java.util.Set; import java.util.StringTokenizer; import java.util.stream.Collectors; @@ -66,6 +67,16 @@ public static KeywordList parse(String keywordString, Character delimiter) { return parse(keywordString, delimiter, Keyword.DEFAULT_HIERARCHICAL_DELIMITER); } + /** + * parses a KeywordList from an optional String of keywordChains + * + * @param keywordString a optional String of keywordChains + * @return an parsed list containing the keywordChains + */ + public static KeywordList parse(Optional keywordString, Character delimiter) { + return keywordString.map(keyword -> KeywordList.parse(keywordString.get(), delimiter)).orElse(new KeywordList()); + } + public KeywordList createClone() { return new KeywordList(this.keywordChains); } diff --git a/src/test/java/org/jabref/model/entry/KeywordListTest.java b/src/test/java/org/jabref/model/entry/KeywordListTest.java index 2fa3f62b2f3..177d26f5940 100644 --- a/src/test/java/org/jabref/model/entry/KeywordListTest.java +++ b/src/test/java/org/jabref/model/entry/KeywordListTest.java @@ -1,5 +1,7 @@ package org.jabref.model.entry; +import java.util.Optional; + import org.junit.Before; import org.junit.Test; @@ -88,4 +90,26 @@ public void parseTwoHierarchicalChains() throws Exception { assertEquals(new KeywordList(expectedOne, expectedTwo), KeywordList.parse("Parent1 > Node1 > Child1, Parent2 > Node2 > Child2", ',', '>')); } + + @Test + public void parseEmptyOptionalReturnsEmptyList() throws Exception { + assertEquals(new KeywordList(), KeywordList.parse(Optional.empty(), ',')); + } + + @Test + public void parseEmptyStringOptionalReturnsEmptyList() throws Exception { + assertEquals(new KeywordList(), KeywordList.parse(Optional.of(""), ',')); + } + + @Test + public void parseOneWordOptionalReturnsOneKeyword() throws Exception { + assertEquals(new KeywordList("keywordOne"), + KeywordList.parse(Optional.of("keywordOne"), ',')); + } + + @Test + public void parseTwoWordOptionalReturnsTwoKeywords() throws Exception { + assertEquals(new KeywordList("keywordOne", "keywordTwo"), + KeywordList.parse(Optional.of("keywordOne, keywordTwo"), ',')); + } } From a200234dfe36c04e3f559da0eff29607f3370fa3 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Mon, 2 Oct 2017 21:29:37 +0200 Subject: [PATCH 3/7] add changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ebfe805866..43ff14cc49c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - We added the file description filed back to the list of files in the `General`-Tab [#2930, comment](https://github.com/JabRef/jabref/issues/2930#issuecomment-328328172) - Added an error dialog if the file is open in another process and cannot be renamed. [#3229] - On Windows, the `JabRef.exe` executable can now be used to start JabRef from the command line. By default, no output is shown unless the new "-console" option is specified. +- Crossreferenced entries are now used when a BibTex key is generated for an entry with empty fields. [#2811](https://github.com/JabRef/jabref/issues/2811) ### Fixed From 9b3bacacc839fa3369c14eda1bccf302979e9c4e Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Mon, 2 Oct 2017 21:56:56 +0200 Subject: [PATCH 4/7] remove System.out.println in test --- .../jabref/logic/bibtexkeypattern/BibtexKeyPatternUtilTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/org/jabref/logic/bibtexkeypattern/BibtexKeyPatternUtilTest.java b/src/test/java/org/jabref/logic/bibtexkeypattern/BibtexKeyPatternUtilTest.java index 52e827b49ed..f6144d34ddd 100644 --- a/src/test/java/org/jabref/logic/bibtexkeypattern/BibtexKeyPatternUtilTest.java +++ b/src/test/java/org/jabref/logic/bibtexkeypattern/BibtexKeyPatternUtilTest.java @@ -90,7 +90,6 @@ public void testCrossrefAndAuthorNames() throws ParseException { String bibtexString = "@ARTICLE{entry2, author={Mari D. Herland and Mona-Iren Hauge and Ingeborg M. Helgeland}}"; BibEntry entry2 = BibtexParser.singleFromString(bibtexString, importFormatPreferences).get(); database.insertEntry(entry2); - System.out.println(entry1.getResolvedFieldOrAlias(FieldName.AUTHOR, database)); assertEquals("HerlandHaugeHelgeland", BibtexKeyPatternUtil.checkLegalKey(BibtexKeyPatternUtil.makeLabel(entry1, "authors3", From 3f280833c2b37c02053f00cdd9141e93a87764e3 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Tue, 3 Oct 2017 08:28:30 +0200 Subject: [PATCH 5/7] Fix map --- src/main/java/org/jabref/model/entry/KeywordList.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/jabref/model/entry/KeywordList.java b/src/main/java/org/jabref/model/entry/KeywordList.java index 4aa3de99fb3..8da3b2e426c 100644 --- a/src/main/java/org/jabref/model/entry/KeywordList.java +++ b/src/main/java/org/jabref/model/entry/KeywordList.java @@ -74,7 +74,7 @@ public static KeywordList parse(String keywordString, Character delimiter) { * @return an parsed list containing the keywordChains */ public static KeywordList parse(Optional keywordString, Character delimiter) { - return keywordString.map(keyword -> KeywordList.parse(keywordString.get(), delimiter)).orElse(new KeywordList()); + return keywordString.map(keyword -> KeywordList.parse(keyword, delimiter)).orElse(new KeywordList()); } public KeywordList createClone() { From 5833428839dc5dc3c9030f2eb33f516af592fca8 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 4 Oct 2017 14:00:06 +0200 Subject: [PATCH 6/7] construct entries for crossref tests by hand --- .../BibtexKeyPatternUtilTest.java | 42 +++++++++++-------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/src/test/java/org/jabref/logic/bibtexkeypattern/BibtexKeyPatternUtilTest.java b/src/test/java/org/jabref/logic/bibtexkeypattern/BibtexKeyPatternUtilTest.java index f6144d34ddd..551134c45c1 100644 --- a/src/test/java/org/jabref/logic/bibtexkeypattern/BibtexKeyPatternUtilTest.java +++ b/src/test/java/org/jabref/logic/bibtexkeypattern/BibtexKeyPatternUtilTest.java @@ -58,13 +58,14 @@ public void testAndInAuthorName() throws ParseException { } @Test - public void testCrossrefAndInAuthorNames() throws ParseException { + public void testCrossrefAndInAuthorNames() throws Exception { BibDatabase database = new BibDatabase(); BibEntry entry1 = new BibEntry(); entry1.setField(FieldName.CROSSREF, "entry2"); + BibEntry entry2 = new BibEntry(); + entry2.setCiteKey("entry2"); + entry2.setField(FieldName.AUTHOR, "Simon Holland"); database.insertEntry(entry1); - String bibtexString = "@ARTICLE{entry2, author={Simon Holland}}"; - BibEntry entry2 = BibtexParser.singleFromString(bibtexString, importFormatPreferences).get(); database.insertEntry(entry2); assertEquals("Holland", @@ -82,13 +83,14 @@ public void testAndAuthorNames() throws ParseException { } @Test - public void testCrossrefAndAuthorNames() throws ParseException { + public void testCrossrefAndAuthorNames() throws Exception { BibDatabase database = new BibDatabase(); BibEntry entry1 = new BibEntry(); entry1.setField(FieldName.CROSSREF, "entry2"); + BibEntry entry2 = new BibEntry(); + entry2.setCiteKey("entry2"); + entry2.setField(FieldName.AUTHOR, "Mari D. Herland and Mona-Iren Hauge and Ingeborg M. Helgeland"); database.insertEntry(entry1); - String bibtexString = "@ARTICLE{entry2, author={Mari D. Herland and Mona-Iren Hauge and Ingeborg M. Helgeland}}"; - BibEntry entry2 = BibtexParser.singleFromString(bibtexString, importFormatPreferences).get(); database.insertEntry(entry2); assertEquals("HerlandHaugeHelgeland", @@ -311,13 +313,14 @@ public void testUniversity() throws ParseException { } @Test - public void testcrossrefUniversity() throws ParseException { + public void testcrossrefUniversity() throws Exception { BibDatabase database = new BibDatabase(); BibEntry entry1 = new BibEntry(); entry1.setField(FieldName.CROSSREF, "entry2"); + BibEntry entry2 = new BibEntry(); + entry2.setCiteKey("entry2"); + entry2.setField(FieldName.AUTHOR, "{Link{\\\"{o}}ping University}}"); database.insertEntry(entry1); - String bibtexString = "@ARTICLE{entry2, author={{Link{\\\"{o}}ping University}}}"; - BibEntry entry2 = BibtexParser.singleFromString(bibtexString, importFormatPreferences).get(); database.insertEntry(entry2); assertEquals("UniLinkoeping", @@ -336,13 +339,14 @@ public void testDepartment() throws ParseException { } @Test - public void testcrossrefDepartment() throws ParseException { + public void testcrossrefDepartment() throws Exception { BibDatabase database = new BibDatabase(); BibEntry entry1 = new BibEntry(); entry1.setField(FieldName.CROSSREF, "entry2"); + BibEntry entry2 = new BibEntry(); + entry2.setCiteKey("entry2"); + entry2.setField(FieldName.AUTHOR, "{Link{\\\"{o}}ping University, Department of Electrical Engineering}}"); database.insertEntry(entry1); - String bibtexString = "@ARTICLE{entry2, author={{Link{\\\"{o}}ping University, Department of Electrical Engineering}}}"; - BibEntry entry2 = BibtexParser.singleFromString(bibtexString, importFormatPreferences).get(); database.insertEntry(entry2); assertEquals("UniLinkoepingEE", @@ -361,13 +365,14 @@ public void testSchool() throws ParseException { } @Test - public void testcrossrefSchool() throws ParseException { + public void testcrossrefSchool() throws Exception { BibDatabase database = new BibDatabase(); BibEntry entry1 = new BibEntry(); entry1.setField(FieldName.CROSSREF, "entry2"); + BibEntry entry2 = new BibEntry(); + entry2.setCiteKey("entry2"); + entry2.setField(FieldName.AUTHOR, "{Link{\\\"{o}}ping University, School of Computer Engineering}}"); database.insertEntry(entry1); - String bibtexString = "@ARTICLE{entry2, author={{Link{\\\"{o}}ping University, School of Computer Engineering}}}"; - BibEntry entry2 = BibtexParser.singleFromString(bibtexString, importFormatPreferences).get(); database.insertEntry(entry2); assertEquals("UniLinkoepingCE", @@ -385,13 +390,14 @@ public void testInstituteOfTechnology() throws ParseException { } @Test - public void testcrossrefInstituteOfTechnology() throws ParseException { + public void testcrossrefInstituteOfTechnology() throws Exception { BibDatabase database = new BibDatabase(); BibEntry entry1 = new BibEntry(); entry1.setField(FieldName.CROSSREF, "entry2"); + BibEntry entry2 = new BibEntry(); + entry2.setCiteKey("entry2"); + entry2.setField(FieldName.AUTHOR, "{Massachusetts Institute of Technology}"); database.insertEntry(entry1); - String bibtexString = "@ARTICLE{entry2, author={{Massachusetts Institute of Technology}}}"; - BibEntry entry2 = BibtexParser.singleFromString(bibtexString, importFormatPreferences).get(); database.insertEntry(entry2); assertEquals("MIT", From d912bd833ac0d711154a205d7b7e449e7ccef430 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Fri, 6 Oct 2017 17:26:24 +0200 Subject: [PATCH 7/7] add tests for crossreferences to BracketedPatternTest --- .../logic/util/BracketedPatternTest.java | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/test/java/org/jabref/logic/util/BracketedPatternTest.java b/src/test/java/org/jabref/logic/util/BracketedPatternTest.java index 6d9d4209e88..7329ba018c3 100644 --- a/src/test/java/org/jabref/logic/util/BracketedPatternTest.java +++ b/src/test/java/org/jabref/logic/util/BracketedPatternTest.java @@ -4,6 +4,7 @@ import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.BibtexEntryTypes; import org.jabref.model.entry.BibtexString; +import org.jabref.model.entry.FieldName; import org.junit.Before; import org.junit.Test; @@ -156,4 +157,39 @@ public void testFieldAndFormat() { assertEquals("HipKro03", BracketedPattern.expandBrackets("[bibtexkey:]", separator, dbentry, database)); } + @Test + public void testResolvedFieldAndFormat() { + BibEntry child = new BibEntry(); + child.setField(FieldName.CROSSREF, "HipKro03"); + database.insertEntry(child); + + Character separator = ';'; + assertEquals("Eric von Hippel and Georg von Krogh", + BracketedPattern.expandBrackets("[author]", separator, child, database)); + + assertEquals("", BracketedPattern.expandBrackets("[unknownkey]", separator, child, database)); + + assertEquals("", BracketedPattern.expandBrackets("[:]", separator, child, database)); + + assertEquals("", BracketedPattern.expandBrackets("[:lower]", separator, child, database)); + + assertEquals("eric von hippel and georg von krogh", + BracketedPattern.expandBrackets("[author:lower]", separator, child, database)); + + // the bibtexkey is not inherited + assertEquals("", BracketedPattern.expandBrackets("[bibtexkey]", separator, child, database)); + + assertEquals("", BracketedPattern.expandBrackets("[bibtexkey:]", separator, child, database)); + } + + @Test + public void testResolvedParentNotInDatabase() { + BibEntry child = new BibEntry(); + child.setField(FieldName.CROSSREF, "HipKro03"); + database.removeEntry(dbentry); + database.insertEntry(child); + + assertEquals("", BracketedPattern.expandBrackets("[author]", ';', child, database)); + } + }