package org.jabref.model.entry;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.jabref.model.strings.StringUtil;
/**
* This class is used to represent customized entry types.
*/
public class CustomEntryType implements EntryType {
public static final String ENTRYTYPE_FLAG = "jabref-entrytype: ";
private final String name;
private final List<String> required;
private final List<String> optional;
private final List<String> primaryOptional;
public CustomEntryType(String name, List<String> required, List<String> primaryOptional, List<String> secondaryOptional) {
this.name = StringUtil.capitalizeFirst(name);
this.primaryOptional = primaryOptional;
this.required = required;
this.optional = Stream.concat(primaryOptional.stream(), secondaryOptional.stream()).collect(Collectors.toList());
}
public CustomEntryType(String name, List<String> required, List<String> optional) {
this.name = StringUtil.capitalizeFirst(name);
this.required = required;
this.optional = optional;
this.primaryOptional = optional;
}
public CustomEntryType(String name, String required, String optional) {
this(name, Arrays.asList(required.split(";")), Arrays.asList(optional.split(";")));
}
public static Optional<CustomEntryType> parse(String comment) {
String rest = comment.substring(ENTRYTYPE_FLAG.length());
int indexEndOfName = rest.indexOf(':');
if (indexEndOfName < 0) {
return Optional.empty();
}
String fieldsDescription = rest.substring(indexEndOfName + 2);
int indexEndOfRequiredFields = fieldsDescription.indexOf(']');
int indexEndOfOptionalFields = fieldsDescription.indexOf(']', indexEndOfRequiredFields + 1);
if ((indexEndOfRequiredFields < 4) || (indexEndOfOptionalFields < (indexEndOfRequiredFields + 6))) {
return Optional.empty();
}
String name = rest.substring(0, indexEndOfName);
String reqFields = fieldsDescription.substring(4, indexEndOfRequiredFields);
String optFields = fieldsDescription.substring(indexEndOfRequiredFields + 6, indexEndOfOptionalFields);
return Optional.of(new CustomEntryType(name, reqFields, optFields));
}
@Override
public int compareTo(EntryType o) {
return getName().compareTo(o.getName());
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o instanceof CustomEntryType) {
return Objects.equals(name, ((CustomEntryType) o).name);
} else {
return false;
}
}
@Override
public String getName() {
return name;
}
@Override
public List<String> getOptionalFields() {
return Collections.unmodifiableList(optional);
}
@Override
public List<String> getRequiredFields() {
return Collections.unmodifiableList(required);
}
@Override
public List<String> getPrimaryOptionalFields() {
return Collections.unmodifiableList(primaryOptional);
}
@Override
public List<String> getSecondaryOptionalFields() {
List<String> result = new ArrayList<>(optional);
result.removeAll(primaryOptional);
return Collections.unmodifiableList(result);
}
/**
* Get a String describing the required field set for this entry type.
*
* @return Description of required field set for storage in preferences or BIB file.
*/
public String getRequiredFieldsString() {
return String.join(";", required);
}
@Override
public int hashCode() {
return super.hashCode();
}
public String getAsString() {
StringBuilder builder = new StringBuilder();
builder.append(ENTRYTYPE_FLAG);
builder.append(getName());
builder.append(": req[");
builder.append(getRequiredFieldsString());
builder.append("] opt[");
builder.append(String.join(";", getOptionalFields()));
builder.append("]");
return builder.toString();
}
}