Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use SequencedSet for required and optional fields #11007

Merged
merged 1 commit into from
Mar 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ protected SequencedSet<Field> determineFieldsToShow(BibEntry entry) {
for (OrFields orFields : entryType.get().getRequiredFields()) {
fields.addAll(orFields.getFields());
}
// Add the edit field for Bibtex-key.
// Add the edit field for BibTeX key (AKA citation key)
fields.add(InternalField.KEY_FIELD);
} else {
// Entry type unknown -> treat all fields as required
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.jabref.migrations;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -57,18 +58,18 @@ private static Optional<BibEntryType> getBibEntryType(int number, JabRefPreferen

BibEntryTypeBuilder entryTypeBuilder = new BibEntryTypeBuilder()
.withType(EntryTypeFactory.parse(name))
.withRequiredFields(req.stream().map(FieldFactory::parseOrFields).collect(Collectors.toList()));
.withRequiredFields(req.stream().map(FieldFactory::parseOrFields).collect(Collectors.toCollection(LinkedHashSet::new)));
if (priOpt.isEmpty()) {
entryTypeBuilder = entryTypeBuilder
.withImportantFields(opt.stream().map(FieldFactory::parseField).collect(Collectors.toSet()));
.withImportantFields(opt.stream().map(FieldFactory::parseField).collect(Collectors.toCollection(LinkedHashSet::new)));
return Optional.of(entryTypeBuilder.build());
} else {
List<String> secondary = new ArrayList<>(opt);
secondary.removeAll(priOpt);

entryTypeBuilder = entryTypeBuilder
.withImportantFields(priOpt.stream().map(FieldFactory::parseField).collect(Collectors.toSet()))
.withDetailFields(secondary.stream().map(FieldFactory::parseField).collect(Collectors.toSet()));
.withImportantFields(priOpt.stream().map(FieldFactory::parseField).collect(Collectors.toCollection(LinkedHashSet::new)))
.withDetailFields(secondary.stream().map(FieldFactory::parseField).collect(Collectors.toCollection(LinkedHashSet::new)));
return Optional.of(entryTypeBuilder.build());
}
}
Expand Down
21 changes: 11 additions & 10 deletions src/main/java/org/jabref/model/entry/BibEntryType.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Objects;
import java.util.SequencedSet;
Expand All @@ -21,8 +22,8 @@
public class BibEntryType implements Comparable<BibEntryType> {

private final EntryType type;
private final LinkedHashSet<OrFields> requiredFields;
private final LinkedHashSet<BibField> fields;
private final SequencedSet<OrFields> requiredFields;
private final SequencedSet<BibField> fields;

/**
* Provides an enriched EntryType with information about defined standards as mandatory fields etc.
Expand All @@ -43,7 +44,7 @@ public EntryType getType() {
return type;
}

public Set<BibField> getOptionalFields() {
public SequencedSet<BibField> getOptionalFields() {
return getAllBibFields().stream()
.filter(field -> !isRequired(field.field()))
.collect(Collectors.toCollection(LinkedHashSet::new));
Expand All @@ -61,15 +62,15 @@ public boolean isRequired(Field field) {
*
* @return a Set of required field name Strings
*/
public Set<OrFields> getRequiredFields() {
return Collections.unmodifiableSet(requiredFields);
public SequencedSet<OrFields> getRequiredFields() {
return Collections.unmodifiableSequencedSet(requiredFields);
}

/**
* Returns all defined fields.
*/
public Set<BibField> getAllBibFields() {
return Collections.unmodifiableSet(fields);
public SequencedSet<BibField> getAllBibFields() {
return Collections.unmodifiableSequencedSet(fields);
}

public Set<Field> getAllFields() {
Expand All @@ -90,11 +91,11 @@ public SequencedSet<Field> getSecondaryOptionalFields() {
.collect(Collectors.toCollection(LinkedHashSet::new));
}

public SequencedSet<Field> getDeprecatedFields(BibDatabaseMode mode) {
public Set<Field> getDeprecatedFields(BibDatabaseMode mode) {
if (mode == BibDatabaseMode.BIBTEX) {
return new LinkedHashSet<>();
return Set.of();
}
SequencedSet<Field> deprecatedFields = new LinkedHashSet<>(EntryConverter.FIELD_ALIASES_BIBTEX_TO_BIBLATEX.keySet());
Set<Field> deprecatedFields = new HashSet<>(EntryConverter.FIELD_ALIASES_BIBTEX_TO_BIBLATEX.keySet());

// Only the optional fields which are mapped to another BibLaTeX name should be shown as "deprecated"
deprecatedFields.retainAll(getOptionalFieldsAndAliases());
Expand Down
34 changes: 20 additions & 14 deletions src/main/java/org/jabref/model/entry/BibEntryTypeBuilder.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package org.jabref.model.entry;

import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.SequencedCollection;
import java.util.SequencedSet;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
Expand All @@ -20,29 +20,25 @@
public class BibEntryTypeBuilder {

private EntryType type = StandardEntryType.Misc;
private Set<BibField> fields = new LinkedHashSet<>();
private Set<OrFields> requiredFields = new LinkedHashSet<>();
private SequencedSet<BibField> fields = new LinkedHashSet<>();
private SequencedSet<OrFields> requiredFields = new LinkedHashSet<>();

public BibEntryTypeBuilder withType(EntryType type) {
this.type = type;
return this;
}

public BibEntryTypeBuilder withImportantFields(Set<BibField> newFields) {
return withImportantFields(newFields.stream().map(BibField::field).collect(Collectors.toCollection(LinkedHashSet::new)));
}

public BibEntryTypeBuilder withImportantFields(Collection<Field> newFields) {
public BibEntryTypeBuilder withImportantFields(SequencedSet<Field> newFields) {
this.fields = Streams.concat(fields.stream(), newFields.stream().map(field -> new BibField(field, FieldPriority.IMPORTANT)))
.collect(Collectors.toCollection(LinkedHashSet::new));
return this;
}

public BibEntryTypeBuilder withImportantFields(Field... newFields) {
return withImportantFields(Arrays.asList(newFields));
return withImportantFields(Arrays.stream(newFields).collect(Collectors.toCollection(LinkedHashSet::new)));
}

public BibEntryTypeBuilder withDetailFields(Collection<Field> newFields) {
public BibEntryTypeBuilder withDetailFields(SequencedCollection<Field> newFields) {
this.fields = Streams.concat(fields.stream(), newFields.stream().map(field -> new BibField(field, FieldPriority.DETAIL)))
.collect(Collectors.toCollection(LinkedHashSet::new));
return this;
Expand All @@ -52,11 +48,21 @@ public BibEntryTypeBuilder withDetailFields(Field... fields) {
return withDetailFields(Arrays.asList(fields));
}

public BibEntryTypeBuilder withRequiredFields(Set<OrFields> requiredFields) {
public BibEntryTypeBuilder withRequiredFields(SequencedSet<OrFields> requiredFields) {
this.requiredFields = requiredFields;
return this;
}

public BibEntryTypeBuilder addRequiredFields(OrFields... requiredFields) {
this.requiredFields.addAll(Arrays.asList(requiredFields));
return this;
}

public BibEntryTypeBuilder addRequiredFields(Field... requiredFields) {
this.requiredFields.addAll(Arrays.stream(requiredFields).map(OrFields::new).toList());
return this;
}

public BibEntryTypeBuilder withRequiredFields(Field... requiredFields) {
this.requiredFields = Arrays.stream(requiredFields).map(OrFields::new).collect(Collectors.toCollection(LinkedHashSet::new));
return this;
Expand All @@ -67,7 +73,7 @@ public BibEntryTypeBuilder withRequiredFields(OrFields first, Field... requiredF
return this;
}

public BibEntryTypeBuilder withRequiredFields(List<OrFields> first, Field... requiredFields) {
public BibEntryTypeBuilder withRequiredFields(SequencedSet<OrFields> first, Field... requiredFields) {
this.requiredFields = Stream.concat(first.stream(), Arrays.stream(requiredFields).map(OrFields::new)).collect(Collectors.toCollection(LinkedHashSet::new));
return this;
}
Expand All @@ -78,7 +84,7 @@ public BibEntryType build() {
.map(OrFields::getFields)
.flatMap(Set::stream)
.map(field -> new BibField(field, FieldPriority.IMPORTANT));
Set<BibField> allFields = Stream.concat(fields.stream(), requiredAsImportant).collect(Collectors.toCollection(LinkedHashSet::new));
SequencedSet<BibField> allFields = Stream.concat(fields.stream(), requiredAsImportant).collect(Collectors.toCollection(LinkedHashSet::new));
return new BibEntryType(type, allFields, requiredFields);
}
}
2 changes: 1 addition & 1 deletion src/main/java/org/jabref/model/entry/EntryConverter.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import org.jabref.model.entry.field.StandardField;

/**
* Converts Entry models from BibTex to biblatex and back.
* Converts Entry models from BibTeX to biblatex and back.
*/
public class EntryConverter {

Expand Down
5 changes: 3 additions & 2 deletions src/main/java/org/jabref/model/entry/field/FieldFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.SequencedSet;
import java.util.Set;
import java.util.TreeSet;
import java.util.function.Predicate;
Expand Down Expand Up @@ -64,14 +65,14 @@ public static OrFields parseOrFields(String fieldNames) {
return new OrFields(fields);
}

public static Set<OrFields> parseOrFieldsList(String fieldNames) {
public static SequencedSet<OrFields> parseOrFieldsList(String fieldNames) {
return Arrays.stream(fieldNames.split(FieldFactory.DELIMITER))
.filter(StringUtil::isNotBlank)
.map(FieldFactory::parseOrFields)
.collect(Collectors.toCollection(LinkedHashSet::new));
}

public static Set<Field> parseFieldList(String fieldNames) {
public static SequencedSet<Field> parseFieldList(String fieldNames) {
return Arrays.stream(fieldNames.split(FieldFactory.DELIMITER))
.filter(StringUtil::isNotBlank)
.map(FieldFactory::parseField)
Expand Down
11 changes: 8 additions & 3 deletions src/main/java/org/jabref/model/entry/field/OrFields.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,17 @@
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Objects;
import java.util.Set;
import java.util.SequencedSet;
import java.util.StringJoiner;

/**
* Represents a choice between two (or more) fields or any combination of them.
* <p>
* Example is that a BibEntry requires either an author or an editor, but both can be be present.
*/
public class OrFields implements Comparable<OrFields> {

private LinkedHashSet<Field> fields = new LinkedHashSet<>();
private SequencedSet<Field> fields = new LinkedHashSet<>();

public OrFields(Field field) {
fields.add(field);
Expand All @@ -35,7 +40,7 @@ public Field getPrimary() {
return fields.getFirst();
}

public Set<Field> getFields() {
public SequencedSet<Field> getFields() {
return this.fields;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@ public class BibtexEntryTypeDefinitions {
*/
private static final BibEntryType INBOOK = new BibEntryTypeBuilder()
.withType(StandardEntryType.InBook)
.withRequiredFields(Arrays.asList(new OrFields(StandardField.CHAPTER, StandardField.PAGES), new OrFields(StandardField.AUTHOR, StandardField.EDITOR)), StandardField.TITLE, StandardField.PUBLISHER, StandardField.YEAR)
.addRequiredFields(new OrFields(StandardField.AUTHOR, StandardField.EDITOR))
.addRequiredFields(StandardField.TITLE, StandardField.PUBLISHER, StandardField.YEAR)
.addRequiredFields(new OrFields(StandardField.CHAPTER, StandardField.PAGES))
.withImportantFields(StandardField.VOLUME, StandardField.NUMBER, StandardField.SERIES, StandardField.TYPE, StandardField.ADDRESS, StandardField.EDITION, StandardField.MONTH, StandardField.ISBN, StandardField.NOTE)
.build();

Expand Down
Loading