From f1838e7e452af0c0b505d81d71c2daebd666f12a Mon Sep 17 00:00:00 2001 From: Oscar Gustafsson Date: Thu, 4 Aug 2016 18:35:10 +0200 Subject: [PATCH] First steps --- .../sf/jabref/logic/auxparser/AuxParser.java | 2 +- .../logic/auxparser/AuxParserResult.java | 17 ++++++- .../sf/jabref/model/database/BibDatabase.java | 40 +++++++++++++-- .../model/database/BibDatabaseTest.java | 51 +++++++++++++++++++ .../net/sf/jabref/logic/auxparser/config.bib | 3 +- 5 files changed, 105 insertions(+), 8 deletions(-) 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 7844b4d9875..8c210ae0cd0 100644 --- a/src/main/java/net/sf/jabref/logic/auxparser/AuxParser.java +++ b/src/main/java/net/sf/jabref/logic/auxparser/AuxParser.java @@ -141,7 +141,7 @@ private void resolveTags(AuxParserResult result) { // Copy database definitions if (result.getGeneratedBibDatabase().hasEntries()) { result.getGeneratedBibDatabase().copyPreamble(masterDatabase); - result.getGeneratedBibDatabase().copyStrings(masterDatabase); + result.insertStrings(masterDatabase.getUsedStrings(result.getGeneratedBibDatabase().getEntries())); } } diff --git a/src/main/java/net/sf/jabref/logic/auxparser/AuxParserResult.java b/src/main/java/net/sf/jabref/logic/auxparser/AuxParserResult.java index 6e9047099d2..5391779dbdf 100644 --- a/src/main/java/net/sf/jabref/logic/auxparser/AuxParserResult.java +++ b/src/main/java/net/sf/jabref/logic/auxparser/AuxParserResult.java @@ -1,12 +1,14 @@ package net.sf.jabref.logic.auxparser; import java.util.ArrayList; +import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; import net.sf.jabref.logic.l10n.Localization; import net.sf.jabref.model.database.BibDatabase; +import net.sf.jabref.model.entry.BibtexString; public class AuxParserResult { @@ -17,6 +19,7 @@ public class AuxParserResult { private final BibDatabase auxDatabase = new BibDatabase(); private int nestedAuxCount; private int crossRefEntriesCount; + private int insertedStrings; public AuxParserResult(BibDatabase masterDatabase) { this.masterDatabase = masterDatabase; @@ -42,6 +45,10 @@ public int getUnresolvedKeysCount() { return unresolvedKeys.size(); } + public int getInsertedStringsCount() { + return insertedStrings; + } + /** * Query the number of extra entries pulled in due to crossrefs from other entries. * @@ -59,6 +66,13 @@ public void increaseNestedAuxFilesCounter() { nestedAuxCount++; } + public void insertStrings(Collection usedStrings) { + for (BibtexString string : usedStrings) { + auxDatabase.addString(string); + insertedStrings++; + } + } + /** * Prints parsing statistics * @@ -73,7 +87,8 @@ public String getInformation(boolean includeMissingEntries) { .append(Localization.lang("resolved")).append(' ').append(getResolvedKeysCount()).append('\n') .append(Localization.lang("not_found")).append(' ').append(getUnresolvedKeysCount()).append('\n') .append(Localization.lang("crossreferenced entries included")).append(' ') - .append(crossRefEntriesCount).append('\n'); + .append(crossRefEntriesCount).append(Localization.lang("strings included")).append(' ') + .append(insertedStrings).append('\n'); if (includeMissingEntries && (getUnresolvedKeysCount() > 0)) { for (String entry : unresolvedKeys) { 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 98a8d257f10..2aeb7c0a735 100644 --- a/src/main/java/net/sf/jabref/model/database/BibDatabase.java +++ b/src/main/java/net/sf/jabref/model/database/BibDatabase.java @@ -342,7 +342,33 @@ public synchronized boolean hasStringLabel(String label) { */ public String resolveForStrings(String content) { Objects.requireNonNull(content, "Content for resolveForStrings must not be null."); - return resolveContent(content, new HashSet<>()); + return resolveContent(content, new HashSet<>(), null); + } + + /** + * Get all strings used in the entries. + */ + public Collection getUsedStrings(Collection entries) { + List result = new ArrayList<>(); + Set allUsedIds = new HashSet<>(); + + // All entries + for (BibEntry entry : entries) { + for (String fieldContent : entry.getFieldValues()) { + resolveContent(fieldContent, new HashSet<>(), allUsedIds); + } + } + + // Preamble + if (preamble != null) { + resolveContent(preamble, new HashSet<>(), allUsedIds); + } + + for (String stringId : allUsedIds) { + result.add((BibtexString) bibtexStrings.get(stringId).clone()); + } + + return result; } /** @@ -400,7 +426,7 @@ public BibEntry resolveForStrings(BibEntry entry, boolean inPlace) { * care not to follow a circular reference pattern. * If the string is undefined, returns null. */ - private String resolveString(String label, Set usedIds) { + private String resolveString(String label, Set usedIds, Set allUsedIds) { for (BibtexString string : bibtexStrings.values()) { if (string.getName().equalsIgnoreCase(label)) { // First check if this string label has been resolved @@ -413,11 +439,14 @@ private String resolveString(String label, Set usedIds) { } // If not, log this string's ID now. usedIds.add(string.getId()); + if (allUsedIds != null) { + allUsedIds.add(string.getId()); + } // Ok, we found the string. Now we must make sure we // resolve any references to other strings in this one. String result = string.getContent(); - result = resolveContent(result, usedIds); + result = resolveContent(result, usedIds, allUsedIds); // Finished with recursing this branch, so we remove our // ID again: @@ -439,7 +468,8 @@ private String resolveString(String label, Set usedIds) { private static final Pattern RESOLVE_CONTENT_PATTERN = Pattern.compile(".*#[^#]+#.*"); - private String resolveContent(String result, Set usedIds) { + + private String resolveContent(String result, Set usedIds, Set allUsedIds) { String res = result; if (RESOLVE_CONTENT_PATTERN.matcher(res).matches()) { StringBuilder newRes = new StringBuilder(); @@ -457,7 +487,7 @@ private String resolveContent(String result, Set usedIds) { // We found the boundaries of the string ref, // now resolve that one. String refLabel = res.substring(next + 1, stringEnd); - String resolved = resolveString(refLabel, usedIds); + String resolved = resolveString(refLabel, usedIds, allUsedIds); if (resolved == null) { // Could not resolve string. Display the # diff --git a/src/test/java/net/sf/jabref/model/database/BibDatabaseTest.java b/src/test/java/net/sf/jabref/model/database/BibDatabaseTest.java index f5136528adb..97b6d0cfbd4 100644 --- a/src/test/java/net/sf/jabref/model/database/BibDatabaseTest.java +++ b/src/test/java/net/sf/jabref/model/database/BibDatabaseTest.java @@ -4,7 +4,10 @@ import java.io.IOException; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.Collection; import java.util.Collections; +import java.util.List; import net.sf.jabref.Globals; import net.sf.jabref.importer.ParserResult; @@ -317,4 +320,52 @@ public void resolveForStringsOddHashMarkAtTheEnd() { database.addString(string); assertEquals(database.resolveForStrings("AAA#AAA#AAA#"), "AAAaaaAAA#"); } + + @Test + public void getUsedStringsSingleStringWithString() { + BibEntry entry = new BibEntry(IdGenerator.next()); + entry.setField("author", "#AAA#"); + BibtexString string = new BibtexString(IdGenerator.next(), "AAA", "Some other #BBB#"); + BibtexString string2 = new BibtexString(IdGenerator.next(), "BBB", "Some more text"); + BibtexString string3 = new BibtexString(IdGenerator.next(), "CCC", "Even more text"); + database.addString(string); + database.addString(string2); + database.addString(string3); + database.insertEntry(entry); + List usedStrings = (List) database.getUsedStrings(Arrays.asList(entry)); + assertEquals(2, usedStrings.size()); + assertTrue((string.getName() == usedStrings.get(0).getName()) + || (string.getName() == usedStrings.get(1).getName())); + assertTrue((string2.getName() == usedStrings.get(0).getName()) + || (string2.getName() == usedStrings.get(1).getName())); + assertTrue((string.getContent() == usedStrings.get(0).getContent()) + || (string.getContent() == usedStrings.get(1).getContent())); + assertTrue((string2.getContent() == usedStrings.get(0).getContent()) + || (string2.getContent() == usedStrings.get(1).getContent())); + } + + @Test + public void getUsedStringsSingleString() { + BibEntry entry = new BibEntry(IdGenerator.next()); + entry.setField("author", "#AAA#"); + BibtexString string = new BibtexString(IdGenerator.next(), "AAA", "Some other text"); + BibtexString string2 = new BibtexString(IdGenerator.next(), "BBB", "Some more text"); + database.addString(string); + database.addString(string2); + database.insertEntry(entry); + List usedStrings = (List) database.getUsedStrings(Arrays.asList(entry)); + assertEquals(string.getName(), usedStrings.get(0).getName()); + assertEquals(string.getContent(), usedStrings.get(0).getContent()); + } + + @Test + public void getUsedStringsNoString() { + BibEntry entry = new BibEntry(IdGenerator.next()); + entry.setField("author", "Oscar Gustafsson"); + BibtexString string = new BibtexString(IdGenerator.next(), "AAA", "Some other text"); + database.addString(string); + database.insertEntry(entry); + Collection usedStrings = database.getUsedStrings(Arrays.asList(entry)); + assertEquals(Collections.emptyList(), usedStrings); + } } diff --git a/src/test/resources/net/sf/jabref/logic/auxparser/config.bib b/src/test/resources/net/sf/jabref/logic/auxparser/config.bib index 3dae7b25e5d..3e3cac593a9 100644 --- a/src/test/resources/net/sf/jabref/logic/auxparser/config.bib +++ b/src/test/resources/net/sf/jabref/logic/auxparser/config.bib @@ -1,5 +1,6 @@ @String {maintainer = "Stefan Kolb"} @preamble {"Maintained by " # maintainer} +@String {einstein = "Einstein, Albert"} @Book{Newton1999, title = {The Principia: mathematical principles of natural philosophy}, @@ -19,7 +20,7 @@ @Book{Einstein1920 title = {Relativity: The special and general theory}, publisher = {Penguin}, year = {1920}, - author = {Einstein, Albert} + author = einstein } @Comment{jabref-meta: databaseType:bibtex;}