Skip to content

Commit d00bd68

Browse files
authored
Merge branch 'main' into java-module-plugins
2 parents 4ace5e1 + 3b06b8b commit d00bd68

File tree

13 files changed

+141
-214
lines changed

13 files changed

+141
-214
lines changed

jabgui/src/main/java/org/jabref/gui/autosaveandbackup/BackupManager.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@
2626
import org.jabref.gui.maintable.columns.MainTableColumn;
2727
import org.jabref.logic.bibtex.InvalidFieldValueException;
2828
import org.jabref.logic.exporter.AtomicFileWriter;
29+
import org.jabref.logic.exporter.BibDatabaseWriter;
2930
import org.jabref.logic.exporter.BibWriter;
30-
import org.jabref.logic.exporter.BibtexDatabaseWriter;
3131
import org.jabref.logic.exporter.SelfContainedSaveConfiguration;
3232
import org.jabref.logic.preferences.CliPreferences;
3333
import org.jabref.logic.util.BackupFileType;
@@ -281,7 +281,7 @@ void performBackup(Path backupPath) {
281281
// This MUST NOT create a broken backup file that then jabref wants to "restore" from?
282282
try (Writer writer = new AtomicFileWriter(backupPath, encoding, false)) {
283283
BibWriter bibWriter = new BibWriter(writer, bibDatabaseContext.getDatabase().getNewLineSeparator());
284-
new BibtexDatabaseWriter(
284+
new BibDatabaseWriter(
285285
bibWriter,
286286
saveConfiguration,
287287
preferences.getFieldPreferences(),

jabgui/src/main/java/org/jabref/gui/exporter/SaveDatabaseAction.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
import org.jabref.logic.exporter.AtomicFileWriter;
3131
import org.jabref.logic.exporter.BibDatabaseWriter;
3232
import org.jabref.logic.exporter.BibWriter;
33-
import org.jabref.logic.exporter.BibtexDatabaseWriter;
3433
import org.jabref.logic.exporter.SaveException;
3534
import org.jabref.logic.exporter.SelfContainedSaveConfiguration;
3635
import org.jabref.logic.l10n.Encodings;
@@ -263,7 +262,7 @@ private boolean saveDatabase(Path file, boolean selectedOnly, Charset encoding,
263262
synchronized (bibDatabaseContext) {
264263
try (AtomicFileWriter fileWriter = new AtomicFileWriter(file, encoding, saveConfiguration.shouldMakeBackup())) {
265264
BibWriter bibWriter = new BibWriter(fileWriter, bibDatabaseContext.getDatabase().getNewLineSeparator());
266-
BibtexDatabaseWriter databaseWriter = new BibtexDatabaseWriter(
265+
BibDatabaseWriter databaseWriter = new BibDatabaseWriter(
267266
bibWriter,
268267
saveConfiguration,
269268
preferences.getFieldPreferences(),

jabgui/src/test/java/org/jabref/gui/autosaveandbackup/BackupManagerDiscardedTest.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
import org.jabref.logic.exporter.AtomicFileWriter;
1111
import org.jabref.logic.exporter.BibDatabaseWriter;
1212
import org.jabref.logic.exporter.BibWriter;
13-
import org.jabref.logic.exporter.BibtexDatabaseWriter;
1413
import org.jabref.logic.exporter.SelfContainedSaveConfiguration;
1514
import org.jabref.logic.preferences.CliPreferences;
1615
import org.jabref.model.database.BibDatabase;
@@ -66,7 +65,7 @@ void setup(@TempDir Path tempDir) throws IOException {
6665
private void saveDatabase() throws IOException {
6766
try (Writer writer = new AtomicFileWriter(testBib, StandardCharsets.UTF_8, false)) {
6867
BibWriter bibWriter = new BibWriter(writer, bibDatabaseContext.getDatabase().getNewLineSeparator());
69-
new BibtexDatabaseWriter(
68+
new BibDatabaseWriter(
7069
bibWriter,
7170
saveConfiguration,
7271
preferences.getFieldPreferences(),

jabkit/src/main/java/org/jabref/cli/ArgumentProcessor.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
import org.jabref.logic.exporter.AtomicFileWriter;
1313
import org.jabref.logic.exporter.BibDatabaseWriter;
1414
import org.jabref.logic.exporter.BibWriter;
15-
import org.jabref.logic.exporter.BibtexDatabaseWriter;
1615
import org.jabref.logic.exporter.ExporterFactory;
1716
import org.jabref.logic.exporter.SelfContainedSaveConfiguration;
1817
import org.jabref.logic.importer.FetcherException;
@@ -168,7 +167,7 @@ protected static void saveDatabaseContext(CliPreferences cliPreferences,
168167
BibWriter bibWriter = new BibWriter(fileWriter, OS.NEWLINE);
169168
SelfContainedSaveConfiguration saveConfiguration = (SelfContainedSaveConfiguration) new SelfContainedSaveConfiguration()
170169
.withReformatOnSave(cliPreferences.getLibraryPreferences().shouldAlwaysReformatOnSave());
171-
BibDatabaseWriter databaseWriter = new BibtexDatabaseWriter(
170+
BibDatabaseWriter databaseWriter = new BibDatabaseWriter(
172171
bibWriter,
173172
saveConfiguration,
174173
cliPreferences.getFieldPreferences(),

jablib/src/jmh/java/org/jabref/benchmarks/Benchmarks.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
import org.jabref.logic.citationkeypattern.CitationKeyPatternPreferences;
1111
import org.jabref.logic.exporter.BibDatabaseWriter;
1212
import org.jabref.logic.exporter.BibWriter;
13-
import org.jabref.logic.exporter.BibtexDatabaseWriter;
1413
import org.jabref.logic.exporter.SelfContainedSaveConfiguration;
1514
import org.jabref.logic.formatter.bibtexfields.HtmlToLatexFormatter;
1615
import org.jabref.logic.importer.ParserResult;
@@ -83,7 +82,7 @@ private StringWriter getOutputWriter() throws IOException {
8382
FieldPreferences fieldPreferences = new FieldPreferences(true, List.of(), List.of());
8483
CitationKeyPatternPreferences citationKeyPatternPreferences = mock(CitationKeyPatternPreferences.class, Answers.RETURNS_DEEP_STUBS);
8584

86-
BibtexDatabaseWriter databaseWriter = new BibtexDatabaseWriter(
85+
BibDatabaseWriter databaseWriter = new BibDatabaseWriter(
8786
bibWriter,
8887
saveConfiguration,
8988
fieldPreferences,

jablib/src/main/java/org/jabref/logic/crawler/StudyRepository.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
import org.jabref.logic.citationkeypattern.CitationKeyGenerator;
1515
import org.jabref.logic.database.DatabaseMerger;
1616
import org.jabref.logic.exporter.AtomicFileWriter;
17+
import org.jabref.logic.exporter.BibDatabaseWriter;
1718
import org.jabref.logic.exporter.BibWriter;
18-
import org.jabref.logic.exporter.BibtexDatabaseWriter;
1919
import org.jabref.logic.exporter.SaveException;
2020
import org.jabref.logic.exporter.SelfContainedSaveConfiguration;
2121
import org.jabref.logic.git.SlrGitHandler;
@@ -431,7 +431,7 @@ private void writeResultToFile(Path pathToFile, BibDatabaseContext context) thro
431431
.withSaveOrder(context.getMetaData().getSaveOrder().map(SelfContainedSaveOrder::of).orElse(SaveOrder.getDefaultSaveOrder()))
432432
.withReformatOnSave(preferences.getLibraryPreferences().shouldAlwaysReformatOnSave());
433433
BibWriter bibWriter = new BibWriter(fileWriter, OS.NEWLINE);
434-
BibtexDatabaseWriter databaseWriter = new BibtexDatabaseWriter(
434+
BibDatabaseWriter databaseWriter = new BibDatabaseWriter(
435435
bibWriter,
436436
saveConfiguration,
437437
preferences.getFieldPreferences(),

jablib/src/main/java/org/jabref/logic/exporter/BibDatabaseWriter.java

Lines changed: 111 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.jabref.logic.exporter;
22

33
import java.io.IOException;
4+
import java.io.Writer;
45
import java.nio.charset.Charset;
56
import java.nio.charset.StandardCharsets;
67
import java.util.ArrayList;
@@ -16,7 +17,10 @@
1617
import java.util.regex.Matcher;
1718
import java.util.regex.Pattern;
1819

20+
import org.jabref.logic.bibtex.BibEntryWriter;
1921
import org.jabref.logic.bibtex.FieldPreferences;
22+
import org.jabref.logic.bibtex.FieldWriter;
23+
import org.jabref.logic.bibtex.InvalidFieldValueException;
2024
import org.jabref.logic.bibtex.comparator.BibtexStringComparator;
2125
import org.jabref.logic.bibtex.comparator.CrossRefEntryComparator;
2226
import org.jabref.logic.bibtex.comparator.FieldComparator;
@@ -44,20 +48,25 @@
4448
import org.jabref.model.strings.StringUtil;
4549

4650
import org.jooq.lambda.Unchecked;
51+
import org.slf4j.Logger;
52+
import org.slf4j.LoggerFactory;
4753

4854
/**
49-
* A generic writer for our database. This is independent of the concrete serialization format.
50-
* For instance, we could also write out YAML or XML by subclassing this class.
55+
* Writes a .bib file following the BibTeX / BibLaTeX format using the provided {@link BibWriter}
5156
* <p>
52-
* Currently, {@link BibtexDatabaseWriter} is the only subclass of this class (and that class writes a .bib file)
53-
* <p>
54-
* The opposite class is {@link org.jabref.logic.importer.fileformat.BibtexParser}
57+
* The opposite class is {@link org.jabref.logic.importer.fileformat.BibtexImporter}
5558
*/
56-
public abstract class BibDatabaseWriter {
57-
59+
public class BibDatabaseWriter {
5860
public enum SaveType { WITH_JABREF_META_DATA, PLAIN_BIBTEX }
5961

62+
public static final String DATABASE_ID_PREFIX = "DBID:";
63+
private static final Logger LOGGER = LoggerFactory.getLogger(BibDatabaseWriter.class);
6064
private static final Pattern REFERENCE_PATTERN = Pattern.compile("(#[A-Za-z]+#)"); // Used to detect string references in strings
65+
private static final String COMMENT_PREFIX = "@Comment";
66+
private static final String PREAMBLE_PREFIX = "@Preamble";
67+
68+
private static final String STRING_PREFIX = "@String";
69+
6170
protected final BibWriter bibWriter;
6271
protected final SelfContainedSaveConfiguration saveConfiguration;
6372
protected final CitationKeyPatternPreferences keyPatternPreferences;
@@ -78,6 +87,19 @@ public BibDatabaseWriter(BibWriter bibWriter,
7887
assert saveConfiguration.getSaveOrder().getOrderType() != SaveOrder.OrderType.TABLE;
7988
}
8089

90+
public BibDatabaseWriter(Writer writer,
91+
String newline,
92+
SelfContainedSaveConfiguration saveConfiguration,
93+
FieldPreferences fieldPreferences,
94+
CitationKeyPatternPreferences citationKeyPatternPreferences,
95+
BibEntryTypesManager entryTypesManager) {
96+
this(new BibWriter(writer, newline),
97+
saveConfiguration,
98+
fieldPreferences,
99+
citationKeyPatternPreferences,
100+
entryTypesManager);
101+
}
102+
81103
private static List<FieldChange> applySaveActions(List<BibEntry> toChange, MetaData metaData, FieldPreferences fieldPreferences) {
82104
List<FieldChange> changes = new ArrayList<>();
83105

@@ -224,11 +246,31 @@ public void savePartOfDatabase(BibDatabaseContext bibDatabaseContext, List<BibEn
224246
writeEpilogue(bibDatabaseContext.getDatabase().getEpilog());
225247
}
226248

227-
protected abstract void writeProlog(BibDatabaseContext bibDatabaseContext, Charset encoding) throws IOException;
249+
protected void writeProlog(BibDatabaseContext bibDatabaseContext, Charset encoding) throws IOException {
250+
// We write the encoding if
251+
// - it is provided (!= null)
252+
// - explicitly set in the .bib file OR not equal to UTF_8
253+
// Otherwise, we do not write anything and return
254+
if ((encoding == null) || (!bibDatabaseContext.getMetaData().getEncodingExplicitlySupplied() && (encoding.equals(StandardCharsets.UTF_8)))) {
255+
return;
256+
}
257+
258+
// Writes the file encoding information.
259+
bibWriter.write("% ");
260+
bibWriter.writeLine(SaveConfiguration.ENCODING_PREFIX + encoding);
261+
}
228262

229-
protected abstract void writeEntry(BibEntry entry, BibDatabaseMode mode) throws IOException;
263+
protected void writeEntry(BibEntry entry, BibDatabaseMode mode) throws IOException {
264+
BibEntryWriter bibtexEntryWriter = new BibEntryWriter(new FieldWriter(fieldPreferences), entryTypesManager);
265+
bibtexEntryWriter.write(entry, bibWriter, mode, saveConfiguration.shouldReformatFile());
266+
}
230267

231-
protected abstract void writeEpilogue(String epilogue) throws IOException;
268+
protected void writeEpilogue(String epilogue) throws IOException {
269+
if (!StringUtil.isNullOrEmpty(epilogue)) {
270+
bibWriter.write(epilogue);
271+
bibWriter.finishBlock();
272+
}
273+
}
232274

233275
/**
234276
* Writes all data to the specified writer, using each object's toString() method.
@@ -244,11 +286,31 @@ protected void writeMetaData(MetaData metaData, GlobalCitationKeyPatterns global
244286
}
245287
}
246288

247-
protected abstract void writeMetaDataItem(Map.Entry<String, String> metaItem) throws IOException;
289+
protected void writeMetaDataItem(Map.Entry<String, String> metaItem) throws IOException {
290+
bibWriter.write(COMMENT_PREFIX + "{");
291+
bibWriter.write(MetaData.META_FLAG);
292+
bibWriter.write(metaItem.getKey());
293+
bibWriter.write(":");
294+
bibWriter.write(metaItem.getValue());
295+
bibWriter.write("}");
296+
bibWriter.finishBlock();
297+
}
248298

249-
protected abstract void writePreamble(String preamble) throws IOException;
299+
protected void writePreamble(String preamble) throws IOException {
300+
if (!StringUtil.isNullOrEmpty(preamble)) {
301+
bibWriter.write(PREAMBLE_PREFIX + "{");
302+
bibWriter.write(preamble);
303+
bibWriter.writeLine("}");
304+
bibWriter.finishBlock();
305+
}
306+
}
250307

251-
protected abstract void writeDatabaseID(String sharedDatabaseID) throws IOException;
308+
protected void writeDatabaseID(String sharedDatabaseID) throws IOException {
309+
bibWriter.write("% ");
310+
bibWriter.write(DATABASE_ID_PREFIX);
311+
bibWriter.write(" ");
312+
bibWriter.writeLine(sharedDatabaseID);
313+
}
252314

253315
/**
254316
* Write all strings in alphabetical order, modified to produce a safe (for BibTeX) order of the strings if they
@@ -307,16 +369,49 @@ protected void writeString(BibtexString bibtexString, Map<String, BibtexString>
307369
writeString(bibtexString, maxKeyLength);
308370
}
309371

310-
protected abstract void writeString(BibtexString bibtexString, int maxKeyLength)
311-
throws IOException;
372+
protected void writeString(BibtexString bibtexString, int maxKeyLength) throws IOException {
373+
// If the string has not been modified, write it back as it was
374+
if (!saveConfiguration.shouldReformatFile() && !bibtexString.hasChanged()) {
375+
LOGGER.debug("Writing parsed serialization {}.", bibtexString.getParsedSerialization());
376+
bibWriter.write(bibtexString.getParsedSerialization());
377+
return;
378+
}
379+
380+
// Write user comments
381+
String userComments = bibtexString.getUserComments();
382+
if (!userComments.isEmpty()) {
383+
bibWriter.writeLine(userComments);
384+
}
385+
386+
bibWriter.write(STRING_PREFIX + "{" + bibtexString.getName() + StringUtil
387+
.repeatSpaces(maxKeyLength - bibtexString.getName().length()) + " = ");
388+
if (bibtexString.getContent().isEmpty()) {
389+
bibWriter.write("{}");
390+
} else {
391+
try {
392+
String formatted = new FieldWriter(fieldPreferences)
393+
.write(InternalField.BIBTEX_STRING, bibtexString.getContent());
394+
bibWriter.write(formatted);
395+
} catch (InvalidFieldValueException ex) {
396+
throw new IOException(ex);
397+
}
398+
}
399+
400+
bibWriter.writeLine("}");
401+
}
312402

313403
protected void writeEntryTypeDefinitions(SortedSet<BibEntryType> types) throws IOException {
314404
for (BibEntryType type : types) {
315405
writeEntryTypeDefinition(type);
316406
}
317407
}
318408

319-
protected abstract void writeEntryTypeDefinition(BibEntryType customType) throws IOException;
409+
protected void writeEntryTypeDefinition(BibEntryType customType) throws IOException {
410+
bibWriter.write(COMMENT_PREFIX + "{");
411+
bibWriter.write(MetaDataSerializer.serializeCustomEntryTypes(customType));
412+
bibWriter.writeLine("}");
413+
bibWriter.finishBlock();
414+
}
320415

321416
/**
322417
* Generate keys for all entries that are lacking keys.

jablib/src/main/java/org/jabref/logic/exporter/BibWriter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import org.jabref.model.strings.StringUtil;
77

88
/**
9-
* Class to write to a .bib file. Used by {@link BibtexDatabaseWriter}
9+
* Class to write to a .bib file. Used by {@link BibDatabaseWriter}
1010
*/
1111
public class BibWriter {
1212

0 commit comments

Comments
 (0)