package net.sf.jabref.labelPattern;
import net.sf.jabref.*;
import net.sf.jabref.undo.NamedCompound;
import net.sf.jabref.undo.UndoableKeyChange;
import javax.swing.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
* Function for resolving duplicate BibTeX keys.
*/
public class SearchFixDuplicateLabels extends AbstractWorker {
private BasePanel panel;
HashMap<String, List<BibtexEntry>> dupes = null;
public SearchFixDuplicateLabels(BasePanel panel) {
this.panel = panel;
}
public void run() {
// Find all multiple occurences of BibTeX keys.
dupes = new HashMap<String, List<BibtexEntry>>();
HashMap<String, BibtexEntry> foundKeys = new HashMap<String, BibtexEntry>();
BibtexDatabase db = panel.database();
for (BibtexEntry entry : db.getEntries()) {
String key = entry.getCiteKey();
// Only handle keys that are actually set:
if ((key != null) && (key.length() > 0)) {
// See whether this entry's key is already known:
if (!foundKeys.containsKey(key)) {
// Not already known. Add key and entry to map:
foundKeys.put(key, entry);
}
else {
// Already known, so we have found a dupe. See if it was already found as a dupe:
if (dupes.containsKey(key)) {
// Already in the dupe map. Add this entry as well:
dupes.get(key).add(entry);
}
else {
// Construct a list of entries for this key:
ArrayList<BibtexEntry> al = new ArrayList<BibtexEntry>();
// Add both the first one we found, and the one we found just now:
al.add(foundKeys.get(key));
al.add(entry);
// Add the list to the dupe map:
dupes.put(key, al);
}
}
}
}
}
@Override
public void init() throws Throwable {
panel.output(Globals.lang("Resolving duplicate BibTeX keys..."));
}
@Override
public void update() {
List<BibtexEntry> toGenerateFor = new ArrayList<BibtexEntry>();
for (String key : dupes.keySet()) {
ResolveDuplicateLabelDialog rdld = new ResolveDuplicateLabelDialog(panel,
key, dupes.get(key));
rdld.show();
if (rdld.isOkPressed()) {
List<JCheckBox> cbs = rdld.getCheckBoxes();
for (int i=0; i<cbs.size(); i++) {
if (cbs.get(i).isSelected()) {
// The checkbox for entry i has been selected, so we should generate a new key for it:
toGenerateFor.add(dupes.get(key).get(i));
}
}
}
}
// Do the actual generation:
if (toGenerateFor.size() > 0) {
NamedCompound ce = new NamedCompound("resolve duplicate keys");
for (BibtexEntry entry : toGenerateFor) {
String oldKey = entry.getCiteKey();
entry = LabelPatternUtil.makeLabel(Globals.prefs.getKeyPattern(),
panel.database(), entry);
ce.addEdit(new UndoableKeyChange(panel.database(), entry.getId(), oldKey,
entry.getField(BibtexFields.KEY_FIELD)));
}
ce.end();
panel.undoManager.addEdit(ce);
panel.markBaseChanged();
}
panel.output(Globals.lang("Finished resolving duplicate BibTeX keys. %0 entries modified.",
String.valueOf(toGenerateFor.size())));
}
}