Skip to content

Commit

Permalink
Use SequencedSet for required and optional fields
Browse files Browse the repository at this point in the history
  • Loading branch information
koppor committed Mar 11, 2024
1 parent be34c97 commit 9ac38f4
Show file tree
Hide file tree
Showing 8 changed files with 52 additions and 36 deletions.
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

0 comments on commit 9ac38f4

Please sign in to comment.