package org.jabref.model.cleanup;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import org.jabref.model.FieldChange;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.entry.FieldName;
import org.jabref.model.entry.event.EntryEventSource;
/**
* Formats a given entry field with the specified formatter.
*/
public class FieldFormatterCleanup implements CleanupJob {
private final String field;
private final Formatter formatter;
public FieldFormatterCleanup(String field, Formatter formatter) {
this.field = field;
this.formatter = formatter;
}
@Override
public List<FieldChange> cleanup(BibEntry entry) {
if (FieldName.INTERNAL_ALL_FIELD.equalsIgnoreCase(field)) {
return cleanupAllFields(entry);
} else if (FieldName.INTERNAL_ALL_TEXT_FIELDS_FIELD.equalsIgnoreCase(field)) {
return cleanupAllTextFields(entry);
} else {
return cleanupSingleField(field, entry);
}
}
/**
* Runs the formatter on the specified field in the given entry.
*
* If the formatter returns an empty string, then the field is removed.
* @param fieldKey the field on which to run the formatter
* @param entry the entry to be cleaned up
* @return a list of changes of the entry
*/
private List<FieldChange> cleanupSingleField(String fieldKey, BibEntry entry) {
if (!entry.hasField(fieldKey)) {
// Not set -> nothing to do
return new ArrayList<>();
}
String oldValue = entry.getField(fieldKey).orElse(null);
// Run formatter
String newValue = formatter.format(oldValue);
if (oldValue.equals(newValue)) {
return new ArrayList<>();
} else {
if (newValue.isEmpty()) {
entry.clearField(fieldKey);
newValue = null;
} else {
entry.setField(fieldKey, newValue, EntryEventSource.SAVE_ACTION);
}
FieldChange change = new FieldChange(entry, fieldKey, oldValue, newValue);
return Collections.singletonList(change);
}
}
private List<FieldChange> cleanupAllFields(BibEntry entry) {
List<FieldChange> fieldChanges = new ArrayList<>();
for (String fieldKey : entry.getFieldNames()) {
fieldChanges.addAll(cleanupSingleField(fieldKey, entry));
}
return fieldChanges;
}
private List<FieldChange> cleanupAllTextFields(BibEntry entry) {
List<FieldChange> fieldChanges = new ArrayList<>();
Set<String> fields = entry.getFieldNames();
fields.removeAll(FieldName.getNotTextFieldNames());
for (String fieldKey : fields) {
fieldChanges.addAll(cleanupSingleField(fieldKey, entry));
}
return fieldChanges;
}
public String getField() {
return field;
}
public Formatter getFormatter() {
return formatter;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o instanceof FieldFormatterCleanup) {
FieldFormatterCleanup that = (FieldFormatterCleanup) o;
return Objects.equals(field, that.field) && Objects.equals(formatter, that.formatter);
}
return false;
}
@Override
public int hashCode() {
return Objects.hash(field, formatter);
}
@Override
public String toString() {
return field + ": " + formatter.getName();
}
}