Skip to content

Commit

Permalink
implement field inheritance for crossref-relationships
Browse files Browse the repository at this point in the history
* based on biblatex inheritance rules (c.f. doc appendix B)
* fixes JabRef#5045
  • Loading branch information
sfo committed Sep 5, 2019
1 parent 99a0a7a commit ce72cb6
Showing 1 changed file with 113 additions and 13 deletions.
126 changes: 113 additions & 13 deletions src/main/java/org/jabref/model/entry/BibEntry.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.jabref.model.entry.field.StandardField;
import org.jabref.model.entry.identifier.DOI;
import org.jabref.model.entry.types.EntryType;
import org.jabref.model.entry.types.IEEETranEntryType;
import org.jabref.model.entry.types.StandardEntryType;
import org.jabref.model.strings.LatexToUnicodeAdapter;
import org.jabref.model.strings.StringUtil;
Expand Down Expand Up @@ -112,6 +113,110 @@ public Optional<String> getResolvedFieldOrAlias(OrFields fields, BibDatabase dat
return Optional.empty();
}

/**
* Map an (empty) field of a BibEntry to a field of a cross-referenced entry.
*
* @param targetField field name of the BibEntry
* @param targetEntry type of the BibEntry
* @param sourceEntry type of the cross-referenced BibEntry
*
* @return the mapped field or null if there is no valid mapping available
*/
private Field getSourceField(Field targetField, EntryType targetEntry, EntryType sourceEntry) {
//// 1. Sort out forbidden fields
if ((targetField == StandardField.IDS) ||
(targetField == StandardField.CROSSREF) ||
(targetField == StandardField.XREF) ||
(targetField == StandardField.ENTRYSET) ||
(targetField == StandardField.RELATED) ||
(targetField == StandardField.SORTKEY)) {
return null;
}

//// 2. Handle special field mappings
if ((sourceEntry == StandardEntryType.MvBook && targetEntry == StandardEntryType.InBook) ||
(sourceEntry == StandardEntryType.MvBook && targetEntry == StandardEntryType.BookInBook) ||
(sourceEntry == StandardEntryType.MvBook && targetEntry == StandardEntryType.SuppBook) ||
(sourceEntry == StandardEntryType.Book && targetEntry == StandardEntryType.InBook) ||
(sourceEntry == StandardEntryType.Book && targetEntry == StandardEntryType.BookInBook) ||
(sourceEntry == StandardEntryType.Book && targetEntry == StandardEntryType.SuppBook)) {
if (targetField == StandardField.AUTHOR) { return StandardField.AUTHOR; }
if (targetField == StandardField.BOOKAUTHOR) { return StandardField.AUTHOR; }
}

if ((sourceEntry == StandardEntryType.MvBook && targetEntry == StandardEntryType.Book) ||
(sourceEntry == StandardEntryType.MvBook && targetEntry == StandardEntryType.InBook) ||
(sourceEntry == StandardEntryType.MvBook && targetEntry == StandardEntryType.BookInBook) ||
(sourceEntry == StandardEntryType.MvBook && targetEntry == StandardEntryType.SuppBook) ||
(sourceEntry == StandardEntryType.MvCollection && targetEntry == StandardEntryType.Collection) ||
(sourceEntry == StandardEntryType.MvCollection && targetEntry == StandardEntryType.InCollection) ||
(sourceEntry == StandardEntryType.MvCollection && targetEntry == StandardEntryType.SuppCollection) ||
(sourceEntry == StandardEntryType.MvProceedings && targetEntry == StandardEntryType.Proceedings) ||
(sourceEntry == StandardEntryType.MvProceedings && targetEntry == StandardEntryType.InProceedings) ||
(sourceEntry == StandardEntryType.MvReference && targetEntry == StandardEntryType.Reference) ||
(sourceEntry == StandardEntryType.MvReference && targetEntry == StandardEntryType.InReference)) {
if (targetField == StandardField.MAINTITLE) { return StandardField.TITLE; }
if (targetField == StandardField.MAINSUBTITLE) { return StandardField.SUBTITLE; }
if (targetField == StandardField.MAINTITLEADDON) { return StandardField.TITLEADDON; }

// those fields are no more available for the same-name inheritance strategy
if ((targetField == StandardField.TITLE) ||
(targetField == StandardField.SUBTITLE) ||
(targetField == StandardField.TITLEADDON)) {
return null;
}

// for these fields, inheritance is not allowed for the specified entry types
if ((targetField == StandardField.SHORTTITLE)) {
return null;
}
}

if ((sourceEntry == StandardEntryType.Book && targetEntry == StandardEntryType.InBook) ||
(sourceEntry == StandardEntryType.Book && targetEntry == StandardEntryType.BookInBook) ||
(sourceEntry == StandardEntryType.Book && targetEntry == StandardEntryType.SuppBook) ||
(sourceEntry == StandardEntryType.Collection && targetEntry == StandardEntryType.InCollection) ||
(sourceEntry == StandardEntryType.Collection && targetEntry == StandardEntryType.SuppCollection) ||
(sourceEntry == StandardEntryType.Reference && targetEntry == StandardEntryType.InReference) ||
(sourceEntry == StandardEntryType.Proceedings && targetEntry == StandardEntryType.InProceedings)) {
if (targetField == StandardField.BOOKTITLE) { return StandardField.TITLE; }
if (targetField == StandardField.BOOKSUBTITLE) { return StandardField.SUBTITLE; }
if (targetField == StandardField.BOOKTITLEADDON) { return StandardField.TITLEADDON; }

// those fields are no more available for the same-name inheritance strategy
if ((targetField == StandardField.TITLE) ||
(targetField == StandardField.SUBTITLE) ||
(targetField == StandardField.TITLEADDON)) {
return null;
}

// for these fields, inheritance is not allowed for the specified entry types
if ((targetField == StandardField.SHORTTITLE)) {
return null;
}
}

if ((sourceEntry == IEEETranEntryType.Periodical && targetEntry == StandardEntryType.Article) ||
(sourceEntry == IEEETranEntryType.Periodical && targetEntry == StandardEntryType.SuppPeriodical)) {
if (targetField == StandardField.JOURNALTITLE) { return StandardField.TITLE; }
if (targetField == StandardField.JOURNALSUBTITLE) { return StandardField.SUBTITLE; }

// those fields are no more available for the same-name inheritance strategy
if ((targetField == StandardField.TITLE) ||
(targetField == StandardField.SUBTITLE)) {
return null;
}

// for these fields, inheritance is not allowed for the specified entry types
if ((targetField == StandardField.SHORTTITLE)) {
return null;
}
}

//// 3. Fallback to inherit the field with the same name.
return targetField;
}

/**
* Returns the text stored in the given field of the given bibtex entry
* which belongs to the given database.
Expand All @@ -137,21 +242,16 @@ public Optional<String> getResolvedFieldOrAlias(Field field, BibDatabase databas

Optional<String> result = getFieldOrAlias(field);
// If this field is not set, and the entry has a crossref, try to look up the
// field in the referred entry: Do not do this for the bibtex key.
if (!result.isPresent() && (database != null)) {
// field in the referred entry, following the biblatex rules
if (result.isEmpty() && (database != null)) {
Optional<BibEntry> referred = database.getReferencedEntry(this);
if (referred.isPresent()) {
result = referred.get().getFieldOrAlias(field);
if (!result.isPresent() && type.equals(StandardEntryType.InProceedings)) {
if (field == StandardField.BOOKTITLE) {
result = referred.get().getFieldOrAlias(StandardField.TITLE);
}
else if (field == StandardField.BOOKSUBTITLE) {
result = referred.get().getFieldOrAlias(StandardField.SUBTITLE);
}
else if (field == StandardField.BOOKAUTHOR) {
result = referred.get().getFieldOrAlias(StandardField.AUTHOR);
}
EntryType sourceEntry = referred.get().type.get();
EntryType targetEntry = type.get();
Field sourceField = getSourceField(field, targetEntry, sourceEntry);

if (sourceField != null) {
result = referred.get().getFieldOrAlias(sourceField);
}
}
}
Expand Down

0 comments on commit ce72cb6

Please sign in to comment.