Skip to content

Commit c438554

Browse files
authored
Fix #3359: Automatically remove colon and apostrophe from key pattern (#3506)
* Refactor BibTeX key generator * Fix #3359: Automatically remove colon and apostrophe from key pattern * Minor code review and fix tests * Fix localization * Fix build after merge * Merge
1 parent c751715 commit c438554

33 files changed

+478
-509
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `#
126126
- We fixed an issue where fetched entries from the ACM fetcher could not be imported. [#3500](https://github.com/JabRef/jabref/issues/3500)
127127
- We fixed an issue where custom data in combobox fields in the entry editor was not saved. [#3538](https://github.com/JabRef/jabref/issues/3538)
128128
- We fixed an issue where automatically found files were not added with a relative paths when the bib file is in the same directory as the files. [#3476](https://github.com/JabRef/jabref/issues/3476)
129+
- We improved the key generator to remove certain illegal characters such as colons or apostrophes. [#3359](https://github.com/JabRef/jabref/issues/3359)
129130

130131

131132
## [4.0] - 2017-10-04

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

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
import org.jabref.gui.externalfiles.AutoSetLinks;
1919
import org.jabref.gui.importer.fetcher.EntryFetcher;
2020
import org.jabref.gui.importer.fetcher.EntryFetchers;
21-
import org.jabref.logic.bibtexkeypattern.BibtexKeyPatternUtil;
21+
import org.jabref.logic.bibtexkeypattern.BibtexKeyGenerator;
2222
import org.jabref.logic.exporter.BibDatabaseWriter;
2323
import org.jabref.logic.exporter.BibtexDatabaseWriter;
2424
import org.jabref.logic.exporter.ExportFormat;
@@ -47,7 +47,6 @@
4747
import org.jabref.model.database.BibDatabaseContext;
4848
import org.jabref.model.database.BibDatabaseMode;
4949
import org.jabref.model.entry.BibEntry;
50-
import org.jabref.model.metadata.MetaData;
5150
import org.jabref.model.strings.StringUtil;
5251
import org.jabref.preferences.SearchPreferences;
5352

@@ -509,17 +508,11 @@ private void regenerateBibtexKeys(List<ParserResult> loaded) {
509508
for (ParserResult parserResult : loaded) {
510509
BibDatabase database = parserResult.getDatabase();
511510

512-
MetaData metaData = parserResult.getMetaData();
513-
if (metaData != null) {
514-
LOGGER.info(Localization.lang("Regenerating BibTeX keys according to metadata"));
515-
for (BibEntry entry : database.getEntries()) {
516-
// try to make a new label
517-
BibtexKeyPatternUtil.makeAndSetLabel(
518-
metaData.getCiteKeyPattern(Globals.prefs.getBibtexKeyPatternPreferences().getKeyPattern()),
519-
database, entry, Globals.prefs.getBibtexKeyPatternPreferences());
520-
}
521-
} else {
522-
LOGGER.info(Localization.lang("No meta data present in BIB file. Cannot regenerate BibTeX keys"));
511+
LOGGER.info(Localization.lang("Regenerating BibTeX keys according to metadata"));
512+
513+
BibtexKeyGenerator keyGenerator = new BibtexKeyGenerator(parserResult.getDatabaseContext(), Globals.prefs.getBibtexKeyPatternPreferences());
514+
for (BibEntry entry : database.getEntries()) {
515+
keyGenerator.generateAndSetKey(entry);
523516
}
524517
}
525518
}

src/main/java/org/jabref/gui/BasePanel.java

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@
102102
import org.jabref.gui.worker.CitationStyleToClipboardWorker;
103103
import org.jabref.gui.worker.MarkEntriesAction;
104104
import org.jabref.gui.worker.SendAsEMailAction;
105-
import org.jabref.logic.bibtexkeypattern.BibtexKeyPatternUtil;
105+
import org.jabref.logic.bibtexkeypattern.BibtexKeyGenerator;
106106
import org.jabref.logic.citationstyle.CitationStyleCache;
107107
import org.jabref.logic.citationstyle.CitationStyleOutputFormat;
108108
import org.jabref.logic.exporter.BibtexDatabaseWriter;
@@ -122,7 +122,6 @@
122122
import org.jabref.logic.util.io.FileFinders;
123123
import org.jabref.logic.util.io.FileUtil;
124124
import org.jabref.model.FieldChange;
125-
import org.jabref.model.bibtexkeypattern.AbstractBibtexKeyPattern;
126125
import org.jabref.model.database.BibDatabase;
127126
import org.jabref.model.database.BibDatabaseContext;
128127
import org.jabref.model.database.KeyCollisionException;
@@ -140,6 +139,7 @@
140139
import org.jabref.model.entry.event.EntryEventSource;
141140
import org.jabref.model.entry.specialfields.SpecialField;
142141
import org.jabref.model.entry.specialfields.SpecialFieldValue;
142+
import org.jabref.model.strings.StringUtil;
143143
import org.jabref.preferences.JabRefPreferences;
144144
import org.jabref.preferences.PreviewPreferences;
145145

@@ -489,16 +489,10 @@ public void run() {
489489

490490
// generate the new cite keys for each entry
491491
final NamedCompound ce = new NamedCompound(Localization.lang("Autogenerate BibTeX keys"));
492-
AbstractBibtexKeyPattern citeKeyPattern = bibDatabaseContext.getMetaData()
493-
.getCiteKeyPattern(Globals.prefs.getBibtexKeyPatternPreferences().getKeyPattern());
492+
BibtexKeyGenerator keyGenerator = new BibtexKeyGenerator(bibDatabaseContext, Globals.prefs.getBibtexKeyPatternPreferences());
494493
for (BibEntry entry : entries) {
495-
String oldCiteKey = entry.getCiteKeyOptional().orElse("");
496-
BibtexKeyPatternUtil.makeAndSetLabel(citeKeyPattern, bibDatabaseContext.getDatabase(),
497-
entry, Globals.prefs.getBibtexKeyPatternPreferences());
498-
String newCiteKey = entry.getCiteKeyOptional().orElse("");
499-
if (!oldCiteKey.equals(newCiteKey)) {
500-
ce.addEdit(new UndoableKeyChange(entry, oldCiteKey, newCiteKey));
501-
}
494+
Optional<FieldChange> change = keyGenerator.generateAndSetKey(entry);
495+
change.ifPresent(fieldChange -> ce.addEdit(new UndoableKeyChange(fieldChange)));
502496
}
503497
ce.end();
504498

@@ -1754,15 +1748,12 @@ public void autoGenerateKeysBeforeSaving() {
17541748
if (Globals.prefs.getBoolean(JabRefPreferences.GENERATE_KEYS_BEFORE_SAVING)) {
17551749
NamedCompound ce = new NamedCompound(Localization.lang("Autogenerate BibTeX keys"));
17561750

1751+
BibtexKeyGenerator keyGenerator = new BibtexKeyGenerator(bibDatabaseContext, Globals.prefs.getBibtexKeyPatternPreferences());
17571752
for (BibEntry bes : bibDatabaseContext.getDatabase().getEntries()) {
17581753
Optional<String> oldKey = bes.getCiteKeyOptional();
1759-
if (!(oldKey.isPresent()) || oldKey.get().isEmpty()) {
1760-
BibtexKeyPatternUtil.makeAndSetLabel(bibDatabaseContext.getMetaData()
1761-
.getCiteKeyPattern(Globals.prefs.getBibtexKeyPatternPreferences().getKeyPattern()),
1762-
bibDatabaseContext.getDatabase(),
1763-
bes, Globals.prefs.getBibtexKeyPatternPreferences());
1764-
bes.getCiteKeyOptional().ifPresent(
1765-
newKey -> ce.addEdit(new UndoableKeyChange(bes, oldKey.orElse(""), newKey)));
1754+
if (StringUtil.isBlank(oldKey)) {
1755+
Optional<FieldChange> change = keyGenerator.generateAndSetKey(bes);
1756+
change.ifPresent(fieldChange -> ce.addEdit(new UndoableKeyChange(fieldChange)));
17661757
}
17671758
}
17681759

src/main/java/org/jabref/gui/EntryTypeDialog.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
import org.jabref.gui.importer.ImportInspectionDialog;
3131
import org.jabref.gui.keyboard.KeyBinding;
3232
import org.jabref.logic.bibtex.DuplicateCheck;
33-
import org.jabref.logic.bibtexkeypattern.BibtexKeyPatternUtil;
33+
import org.jabref.logic.bibtexkeypattern.BibtexKeyGenerator;
3434
import org.jabref.logic.importer.FetcherException;
3535
import org.jabref.logic.importer.IdBasedFetcher;
3636
import org.jabref.logic.importer.WebFetchers;
@@ -319,7 +319,7 @@ protected void done() {
319319
diag.toFront();
320320
} else {
321321
// Regenerate CiteKey of imported BibEntry
322-
BibtexKeyPatternUtil.makeAndSetLabel(Globals.prefs.getBibtexKeyPatternPreferences().getKeyPattern(), frame.getCurrentBasePanel().getDatabase(), bibEntry, Globals.prefs.getBibtexKeyPatternPreferences());
322+
new BibtexKeyGenerator(frame.getCurrentBasePanel().getBibDatabaseContext(), Globals.prefs.getBibtexKeyPatternPreferences()).generateAndSetKey(bibEntry);
323323
// Update Timestamps
324324
if (Globals.prefs.getTimestampPreferences().includeCreatedTimestamp()) {
325325
bibEntry.setField(Globals.prefs.getTimestampPreferences().getTimestampField(), Globals.prefs.getTimestampPreferences().now());

src/main/java/org/jabref/gui/GenFieldsCustomizer.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
import org.jabref.gui.entryeditor.EntryEditorTabList;
2525
import org.jabref.gui.help.HelpAction;
2626
import org.jabref.gui.keyboard.KeyBinding;
27-
import org.jabref.logic.bibtexkeypattern.BibtexKeyPatternUtil;
27+
import org.jabref.logic.bibtexkeypattern.BibtexKeyGenerator;
2828
import org.jabref.logic.help.HelpFile;
2929
import org.jabref.logic.l10n.Localization;
3030
import org.jabref.preferences.JabRefPreferences;
@@ -119,7 +119,7 @@ private void okActionPerformed() {
119119
Localization.lang("Error"), JOptionPane.ERROR_MESSAGE);
120120
return;
121121
}
122-
String testString = BibtexKeyPatternUtil.checkLegalKey(parts[1],
122+
String testString = BibtexKeyGenerator.cleanKey(parts[1],
123123
Globals.prefs.getBoolean(JabRefPreferences.ENFORCE_LEGAL_BIBTEX_KEY));
124124
if (!testString.equals(parts[1]) || (parts[1].indexOf('&') >= 0)) {
125125
// Report error and exit.

src/main/java/org/jabref/gui/bibtexkeypattern/SearchFixDuplicateLabels.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import java.util.HashMap;
55
import java.util.List;
66
import java.util.Map;
7+
import java.util.Optional;
78

89
import javax.swing.JCheckBox;
910

@@ -12,8 +13,9 @@
1213
import org.jabref.gui.undo.NamedCompound;
1314
import org.jabref.gui.undo.UndoableKeyChange;
1415
import org.jabref.gui.worker.AbstractWorker;
15-
import org.jabref.logic.bibtexkeypattern.BibtexKeyPatternUtil;
16+
import org.jabref.logic.bibtexkeypattern.BibtexKeyGenerator;
1617
import org.jabref.logic.l10n.Localization;
18+
import org.jabref.model.FieldChange;
1719
import org.jabref.model.database.BibDatabase;
1820
import org.jabref.model.entry.BibEntry;
1921

@@ -91,13 +93,10 @@ public void update() {
9193
// Do the actual generation:
9294
if (!toGenerateFor.isEmpty()) {
9395
NamedCompound ce = new NamedCompound(Localization.lang("Resolve duplicate BibTeX keys"));
96+
BibtexKeyGenerator keyGenerator = new BibtexKeyGenerator(panel.getBibDatabaseContext(), Globals.prefs.getBibtexKeyPatternPreferences());
9497
for (BibEntry entry : toGenerateFor) {
95-
String oldKey = entry.getCiteKeyOptional().orElse(null);
96-
BibtexKeyPatternUtil.makeAndSetLabel(panel.getBibDatabaseContext().getMetaData()
97-
.getCiteKeyPattern(Globals.prefs.getBibtexKeyPatternPreferences().getKeyPattern()),
98-
panel.getDatabase(), entry,
99-
Globals.prefs.getBibtexKeyPatternPreferences());
100-
ce.addEdit(new UndoableKeyChange(entry, oldKey, entry.getCiteKeyOptional().get()));
98+
Optional<FieldChange> change = keyGenerator.generateAndSetKey(entry);
99+
change.ifPresent(fieldChange -> ce.addEdit(new UndoableKeyChange(fieldChange)));
101100
}
102101
ce.end();
103102
panel.getUndoManager().addEdit(ce);

src/main/java/org/jabref/gui/customentrytypes/EntryTypeList.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import javax.swing.event.ListSelectionListener;
1313

1414
import org.jabref.Globals;
15-
import org.jabref.logic.bibtexkeypattern.BibtexKeyPatternUtil;
15+
import org.jabref.logic.bibtexkeypattern.BibtexKeyGenerator;
1616
import org.jabref.logic.l10n.Localization;
1717
import org.jabref.model.EntryTypes;
1818
import org.jabref.model.database.BibDatabaseMode;
@@ -57,7 +57,7 @@ protected void addField(String str) {
5757
return;
5858
}
5959

60-
String testString = BibtexKeyPatternUtil.checkLegalKey(s,
60+
String testString = BibtexKeyGenerator.cleanKey(s,
6161
Globals.prefs.getBoolean(JabRefPreferences.ENFORCE_LEGAL_BIBTEX_KEY));
6262
if (!testString.equals(s) || (s.indexOf('&') >= 0)) {
6363
// Report error and exit.

src/main/java/org/jabref/gui/customentrytypes/FieldSetComponent.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434

3535
import org.jabref.Globals;
3636
import org.jabref.gui.IconTheme;
37-
import org.jabref.logic.bibtexkeypattern.BibtexKeyPatternUtil;
37+
import org.jabref.logic.bibtexkeypattern.BibtexKeyGenerator;
3838
import org.jabref.logic.l10n.Localization;
3939
import org.jabref.preferences.JabRefPreferences;
4040

@@ -242,7 +242,7 @@ protected void addField(String str) {
242242
return;
243243
}
244244

245-
String testString = BibtexKeyPatternUtil.checkLegalKey(s,
245+
String testString = BibtexKeyGenerator.cleanKey(s,
246246
Globals.prefs.getBoolean(JabRefPreferences.ENFORCE_LEGAL_BIBTEX_KEY));
247247
if (!testString.equals(s) || (s.indexOf('&') >= 0)) {
248248
// Report error and exit.

src/main/java/org/jabref/gui/entryeditor/EntryEditor.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,17 +53,16 @@ public class EntryEditor extends BorderPane {
5353

5454
private final BibDatabaseContext bibDatabaseContext;
5555
private final CountingUndoManager undoManager;
56-
56+
private final BasePanel panel;
57+
private final List<SearchQueryHighlightListener> searchListeners = new ArrayList<>();
58+
private final List<EntryEditorTab> tabs;
5759
/**
5860
* A reference to the entry this editor works on.
5961
*/
6062
private BibEntry entry;
6163
@FXML private TabPane tabbed;
6264
@FXML private Button typeChangeButton;
6365
@FXML private Button fetcherButton;
64-
private final BasePanel panel;
65-
private final List<SearchQueryHighlightListener> searchListeners = new ArrayList<>();
66-
private final List<EntryEditorTab> tabs;
6766
private SourceTab sourceTab;
6867
@FXML private Label typeLabel;
6968

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
package org.jabref.gui.fieldeditors;
22

3-
import java.util.Optional;
4-
53
import javax.swing.undo.UndoManager;
64

75
import org.jabref.gui.autocompleter.AutoCompleteSuggestionProvider;
86
import org.jabref.gui.undo.UndoableKeyChange;
7+
import org.jabref.logic.bibtexkeypattern.BibtexKeyGenerator;
98
import org.jabref.logic.bibtexkeypattern.BibtexKeyPatternPreferences;
10-
import org.jabref.logic.bibtexkeypattern.BibtexKeyPatternUtil;
119
import org.jabref.logic.integrity.FieldCheckers;
12-
import org.jabref.model.FieldChange;
1310
import org.jabref.model.database.BibDatabaseContext;
1411

1512
public class BibtexKeyEditorViewModel extends AbstractEditorViewModel {
@@ -25,11 +22,8 @@ public BibtexKeyEditorViewModel(String fieldName, AutoCompleteSuggestionProvider
2522
}
2623

2724
public void generateKey() {
28-
Optional<FieldChange> fieldChange = BibtexKeyPatternUtil.makeAndSetLabel(
29-
bibDatabaseContext.getMetaData().getCiteKeyPattern(keyPatternPreferences.getKeyPattern()),
30-
bibDatabaseContext.getDatabase(),
31-
entry,
32-
keyPatternPreferences);
33-
fieldChange.ifPresent(change -> undoManager.addEdit(new UndoableKeyChange(change)));
25+
new BibtexKeyGenerator(bibDatabaseContext, keyPatternPreferences)
26+
.generateAndSetKey(entry)
27+
.ifPresent(change -> undoManager.addEdit(new UndoableKeyChange(change)));
3428
}
3529
}

0 commit comments

Comments
 (0)