diff --git a/CHANGELOG.md b/CHANGELOG.md index ebf3434f2bb..aa8854dcfe4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ Note that this project **does not** adhere to [Semantic Versioning](http://semve - JabRef now writes log files. Linux: `$home/.cache/jabref/logs/version`, Windows: `%APPDATA%\..\Local\harawata\jabref\version\logs`, Mac: `Users/.../Library/Logs/jabref/version` - We added an importer for Citavi backup files, support ".ctv5bak" and ".ctv6bak" file formats. [#8322](https://github.com/JabRef/jabref/issues/8322) - We added a feature to drag selected entries and drop them to other opened inactive library tabs [koppor521](https://github.com/koppor/jabref/issues/521). +- We added support for the [biblatex-apa](https://github.com/plk/biblatex-apa) legal entry types `Legislation`, `Legadminmaterial`, `Jurisdiction`, `Constitution` and `Legal` [#8931](https://github.com/JabRef/jabref/issues/8931) ### Changed diff --git a/src/main/java/org/jabref/gui/EntryTypeView.java b/src/main/java/org/jabref/gui/EntryTypeView.java index 10a95f3a5d0..165e1d7a380 100644 --- a/src/main/java/org/jabref/gui/EntryTypeView.java +++ b/src/main/java/org/jabref/gui/EntryTypeView.java @@ -28,6 +28,7 @@ import org.jabref.logic.l10n.Localization; import org.jabref.model.database.BibDatabaseMode; import org.jabref.model.entry.BibEntryType; +import org.jabref.model.entry.types.BiblatexAPAEntryTypeDefinitions; import org.jabref.model.entry.types.BiblatexEntryTypeDefinitions; import org.jabref.model.entry.types.BiblatexSoftwareEntryTypeDefinitions; import org.jabref.model.entry.types.BibtexEntryTypeDefinitions; @@ -157,6 +158,7 @@ public void initialize() { .filter(e -> !recommendedEntries.contains(e)) .collect(Collectors.toList()); otherEntries.addAll(BiblatexSoftwareEntryTypeDefinitions.ALL); + otherEntries.addAll(BiblatexAPAEntryTypeDefinitions.ALL); } else { recommendedEntries = BibtexEntryTypeDefinitions.RECOMMENDED; otherEntries = BibtexEntryTypeDefinitions.ALL diff --git a/src/main/java/org/jabref/logic/importer/fileformat/BibTeXMLImporter.java b/src/main/java/org/jabref/logic/importer/fileformat/BibTeXMLImporter.java index 5fb3d8ed900..65301e2a7a1 100644 --- a/src/main/java/org/jabref/logic/importer/fileformat/BibTeXMLImporter.java +++ b/src/main/java/org/jabref/logic/importer/fileformat/BibTeXMLImporter.java @@ -184,7 +184,7 @@ private void parse(T entryType, Map fields) { } else if (isMethodToIgnore(method.getName())) { continue; } else if (method.getName().startsWith("get")) { - putIfValueNotNull(fields, FieldFactory.parseField(method.getName().replace("get", "")), (String) method.invoke(entryType)); + putIfValueNotNull(fields, FieldFactory.parseField(entryType, method.getName().replace("get", "")), (String) method.invoke(entryType)); } } catch (IllegalArgumentException | InvocationTargetException | IllegalAccessException e) { LOGGER.error("Could not invoke method", e); diff --git a/src/main/java/org/jabref/logic/importer/fileformat/BibtexParser.java b/src/main/java/org/jabref/logic/importer/fileformat/BibtexParser.java index f3e6e7462f5..666ae01a7fb 100644 --- a/src/main/java/org/jabref/logic/importer/fileformat/BibtexParser.java +++ b/src/main/java/org/jabref/logic/importer/fileformat/BibtexParser.java @@ -387,8 +387,8 @@ private String purge(String context, String stringToPurge) { } // strip empty lines while ((runningIndex < indexOfAt) && - (context.charAt(runningIndex) == '\r' || - context.charAt(runningIndex) == '\n')) { + ((context.charAt(runningIndex) == '\r') || + (context.charAt(runningIndex) == '\n'))) { runningIndex++; } return context.substring(runningIndex); diff --git a/src/main/java/org/jabref/logic/importer/fileformat/CffImporter.java b/src/main/java/org/jabref/logic/importer/fileformat/CffImporter.java index 2ff451e6dca..afbe5af657d 100644 --- a/src/main/java/org/jabref/logic/importer/fileformat/CffImporter.java +++ b/src/main/java/org/jabref/logic/importer/fileformat/CffImporter.java @@ -14,6 +14,7 @@ import org.jabref.model.entry.Author; import org.jabref.model.entry.AuthorList; import org.jabref.model.entry.BibEntry; +import org.jabref.model.entry.field.BiblatexSoftwareField; import org.jabref.model.entry.field.Field; import org.jabref.model.entry.field.StandardField; import org.jabref.model.entry.field.UnknownField; @@ -95,7 +96,7 @@ public ParserResult importDatabase(BufferedReader reader) throws IOException { StandardEntryType entryType = StandardEntryType.Software; // Map CFF fields to JabRef Fields - HashMap fieldMap = getFieldMappings(); + HashMap fieldMap = getFieldMappings(); for (Map.Entry property : citation.values.entrySet()) { if (fieldMap.containsKey(property.getKey())) { entryMap.put(fieldMap.get(property.getKey()), property.getValue()); @@ -120,7 +121,7 @@ public ParserResult importDatabase(BufferedReader reader) throws IOException { entryMap.put(StandardField.AUTHOR, authorStr); // Select DOI to keep - if (entryMap.get(StandardField.DOI) == null && citation.ids != null) { + if ((entryMap.get(StandardField.DOI) == null) && (citation.ids != null)) { List doiIds = citation.ids.stream() .filter(id -> id.type.equals("doi")) .collect(Collectors.toList()); @@ -137,14 +138,14 @@ public ParserResult importDatabase(BufferedReader reader) throws IOException { .collect(Collectors.toList()); if (swhIds.size() == 1) { - entryMap.put(StandardField.SWHID, swhIds.get(0)); + entryMap.put(BiblatexSoftwareField.SWHID, swhIds.get(0)); } else if (swhIds.size() > 1) { List relSwhIds = swhIds.stream() .filter(id -> id.split(":").length > 3) // quick filter for invalid swhids .filter(id -> id.split(":")[2].equals("rel")) .collect(Collectors.toList()); if (relSwhIds.size() == 1) { - entryMap.put(StandardField.SWHID, relSwhIds.get(0)); + entryMap.put(BiblatexSoftwareField.SWHID, relSwhIds.get(0)); } } } @@ -166,19 +167,19 @@ public boolean isRecognizedFormat(BufferedReader reader) throws IOException { try { citation = mapper.readValue(reader, CffFormat.class); - return citation != null && citation.values.get("title") != null; + return (citation != null) && (citation.values.get("title") != null); } catch (IOException e) { return false; } } - private HashMap getFieldMappings() { - HashMap fieldMappings = new HashMap<>(); + private HashMap getFieldMappings() { + HashMap fieldMappings = new HashMap<>(); fieldMappings.put("title", StandardField.TITLE); fieldMappings.put("version", StandardField.VERSION); fieldMappings.put("doi", StandardField.DOI); - fieldMappings.put("license", StandardField.LICENSE); - fieldMappings.put("repository", StandardField.REPOSITORY); + fieldMappings.put("license", BiblatexSoftwareField.LICENSE); + fieldMappings.put("repository", BiblatexSoftwareField.REPOSITORY); fieldMappings.put("url", StandardField.URL); fieldMappings.put("abstract", StandardField.ABSTRACT); fieldMappings.put("message", StandardField.COMMENT); diff --git a/src/main/java/org/jabref/logic/importer/fileformat/CopacImporter.java b/src/main/java/org/jabref/logic/importer/fileformat/CopacImporter.java index ab857becd0a..ab638ae4cf3 100644 --- a/src/main/java/org/jabref/logic/importer/fileformat/CopacImporter.java +++ b/src/main/java/org/jabref/logic/importer/fileformat/CopacImporter.java @@ -137,7 +137,7 @@ public ParserResult importDatabase(BufferedReader reader) throws IOException { } else if ("DT- ".equals(code)) { setOrAppend(b, new UnknownField("documenttype"), line.substring(4).trim(), ", "); } else { - setOrAppend(b, FieldFactory.parseField(code.substring(0, 2)), line.substring(4).trim(), ", "); + setOrAppend(b, FieldFactory.parseField(StandardEntryType.Book, line.substring(0, 2)), line.substring(4).trim(), ", "); } } results.add(b); diff --git a/src/main/java/org/jabref/logic/importer/fileformat/IsiImporter.java b/src/main/java/org/jabref/logic/importer/fileformat/IsiImporter.java index b502977f716..2845756b770 100644 --- a/src/main/java/org/jabref/logic/importer/fileformat/IsiImporter.java +++ b/src/main/java/org/jabref/logic/importer/fileformat/IsiImporter.java @@ -281,7 +281,7 @@ public ParserResult importDatabase(BufferedReader reader) throws IOException { if ("ER".equals(beg) || "EF".equals(beg) || "VR".equals(beg) || "FN".equals(beg)) { continue; } - hm.put(FieldFactory.parseField(beg), value); + hm.put(FieldFactory.parseField(type, beg), value); } } diff --git a/src/main/java/org/jabref/logic/importer/fileformat/MedlineImporter.java b/src/main/java/org/jabref/logic/importer/fileformat/MedlineImporter.java index 392fad9772b..b9e9eac39d4 100644 --- a/src/main/java/org/jabref/logic/importer/fileformat/MedlineImporter.java +++ b/src/main/java/org/jabref/logic/importer/fileformat/MedlineImporter.java @@ -425,7 +425,7 @@ private void addArticleIdList(Map fields, ArticleIdList articleId if ("pubmed".equals(id.getIdType())) { fields.put(StandardField.PMID, id.getContent()); } else { - fields.put(FieldFactory.parseField(id.getIdType()), id.getContent()); + fields.put(FieldFactory.parseField(StandardEntryType.Article, id.getIdType()), id.getContent()); } } } @@ -499,7 +499,7 @@ private void addKeyWords(Map fields, List allKeyword private void addOtherId(Map fields, List otherID) { for (OtherID id : otherID) { if ((id.getSource() != null) && (id.getContent() != null)) { - fields.put(FieldFactory.parseField(id.getSource()), id.getContent()); + fields.put(FieldFactory.parseField(StandardEntryType.Article, id.getSource()), id.getContent()); } } } diff --git a/src/main/java/org/jabref/logic/importer/util/MetaDataParser.java b/src/main/java/org/jabref/logic/importer/util/MetaDataParser.java index eb1e905adca..5f3d5e29c52 100644 --- a/src/main/java/org/jabref/logic/importer/util/MetaDataParser.java +++ b/src/main/java/org/jabref/logic/importer/util/MetaDataParser.java @@ -65,6 +65,7 @@ public MetaData parse(MetaData metaData, Map data, Character key String user = entry.getKey().substring(MetaData.FILE_DIRECTORY.length() + 1); metaData.setUserFileDirectory(user, getSingleItem(value)); } else if (entry.getKey().startsWith(MetaData.SELECTOR_META_PREFIX)) { + // edge case, it might be one special field e.g. article from biblatex-apa, but we can't distinguish this from any other field and rather prefer to handle it as UnknownField metaData.addContentSelector(ContentSelectors.parse(FieldFactory.parseField(entry.getKey().substring(MetaData.SELECTOR_META_PREFIX.length())), StringUtil.unquote(entry.getValue(), MetaData.ESCAPE_CHARACTER))); } else if (entry.getKey().startsWith(MetaData.FILE_DIRECTORY + "Latex-")) { // The user name comes directly after "FILE_DIRECTORYLatex-" diff --git a/src/main/java/org/jabref/model/entry/BibEntryTypesManager.java b/src/main/java/org/jabref/model/entry/BibEntryTypesManager.java index b737596abd6..836cd39dac8 100644 --- a/src/main/java/org/jabref/model/entry/BibEntryTypesManager.java +++ b/src/main/java/org/jabref/model/entry/BibEntryTypesManager.java @@ -11,6 +11,7 @@ import org.jabref.model.database.BibDatabaseMode; import org.jabref.model.entry.field.BibField; import org.jabref.model.entry.field.FieldFactory; +import org.jabref.model.entry.types.BiblatexAPAEntryTypeDefinitions; import org.jabref.model.entry.types.BiblatexEntryTypeDefinitions; import org.jabref.model.entry.types.BiblatexSoftwareEntryTypeDefinitions; import org.jabref.model.entry.types.BibtexEntryTypeDefinitions; @@ -21,7 +22,7 @@ public class BibEntryTypesManager { public static final String ENTRYTYPE_FLAG = "jabref-entrytype: "; private final InternalEntryTypes BIBTEX = new InternalEntryTypes(Stream.concat(BibtexEntryTypeDefinitions.ALL.stream(), IEEETranEntryTypeDefinitions.ALL.stream()).collect(Collectors.toList())); - private final InternalEntryTypes BIBLATEX = new InternalEntryTypes(Stream.concat(BiblatexEntryTypeDefinitions.ALL.stream(), BiblatexSoftwareEntryTypeDefinitions.ALL.stream()).collect(Collectors.toList())); + private final InternalEntryTypes BIBLATEX = new InternalEntryTypes(Stream.concat(BiblatexEntryTypeDefinitions.ALL.stream(), Stream.concat(BiblatexSoftwareEntryTypeDefinitions.ALL.stream(), BiblatexAPAEntryTypeDefinitions.ALL.stream())).collect(Collectors.toList())); public BibEntryTypesManager() { } @@ -99,6 +100,7 @@ public List getAllCustomTypes(BibDatabaseMode mode) { return customizedTypes.stream() .filter(entryType -> BiblatexEntryTypeDefinitions.ALL.stream().noneMatch(biblatexType -> biblatexType.getType().equals(entryType.getType()))) .filter(entryType -> BiblatexSoftwareEntryTypeDefinitions.ALL.stream().noneMatch(biblatexSoftware -> biblatexSoftware.getType().equals(entryType.getType()))) + .filter(entryType -> BiblatexAPAEntryTypeDefinitions.ALL.stream().noneMatch(biblatexAPA -> biblatexAPA.getType().equals(entryType.getType()))) .collect(Collectors.toList()); } } diff --git a/src/main/java/org/jabref/model/entry/field/BiblatexApaField.java b/src/main/java/org/jabref/model/entry/field/BiblatexApaField.java new file mode 100644 index 00000000000..b2938963efe --- /dev/null +++ b/src/main/java/org/jabref/model/entry/field/BiblatexApaField.java @@ -0,0 +1,82 @@ +package org.jabref.model.entry.field; + +import java.util.Arrays; +import java.util.Collections; +import java.util.EnumSet; +import java.util.Optional; +import java.util.Set; + +import org.jabref.model.entry.types.BiblatexApaEntryType; + +public enum BiblatexApaField implements Field { + + AMENDMENT("amendment"), + ARTICLE("article"), + CITATION("citation"), + CITATION_CITEORG("citation_citeorg"), + CITATION_CITEDATE("citation_citedate", FieldProperty.DATE), + CITATION_CITEINFO("citation_citeinfo"), + SECTION("section", FieldProperty.NUMERIC), + SOURCE("source"); + + private final String name; + private final String displayName; + private final Set properties; + + BiblatexApaField(String name) { + this.name = name; + this.displayName = null; + this.properties = EnumSet.noneOf(FieldProperty.class); + } + + BiblatexApaField(String name, String displayName) { + this.name = name; + this.displayName = displayName; + this.properties = EnumSet.noneOf(FieldProperty.class); + } + + BiblatexApaField(String name, String displayName, FieldProperty first, FieldProperty... rest) { + this.name = name; + this.displayName = displayName; + this.properties = EnumSet.of(first, rest); + } + + BiblatexApaField(String name, FieldProperty first, FieldProperty... rest) { + this.name = name; + this.displayName = null; + this.properties = EnumSet.of(first, rest); + } + + public static Optional fromName(T type, String name) { + if (!(type instanceof BiblatexApaEntryType)) { + return Optional.empty(); + } + return Arrays.stream(BiblatexApaField.values()) + .filter(field -> field.getName().equalsIgnoreCase(name)) + .findAny(); + } + + @Override + public Set getProperties() { + return Collections.unmodifiableSet(properties); + } + + @Override + public String getName() { + return name; + } + + @Override + public boolean isStandardField() { + return false; + } + + @Override + public String getDisplayName() { + if (displayName == null) { + return Field.super.getDisplayName(); + } else { + return displayName; + } + } +} diff --git a/src/main/java/org/jabref/model/entry/field/BiblatexSoftwareField.java b/src/main/java/org/jabref/model/entry/field/BiblatexSoftwareField.java new file mode 100644 index 00000000000..fc3bb4dcc48 --- /dev/null +++ b/src/main/java/org/jabref/model/entry/field/BiblatexSoftwareField.java @@ -0,0 +1,82 @@ +package org.jabref.model.entry.field; + +import java.util.Arrays; +import java.util.Collections; +import java.util.EnumSet; +import java.util.Optional; +import java.util.Set; + +import org.jabref.model.entry.types.BiblatexSoftwareEntryType; + +public enum BiblatexSoftwareField implements Field { + + HALID("hal_id"), + HALVERSION("hal_version"), + INTRODUCEDIN("introducedin"), + LICENSE("license"), + RELATEDTYPE("relatedtype"), + RELATEDSTRING("relatedstring"), + REPOSITORY("repository"), + SWHID("swhid"); + + private final String name; + private final String displayName; + private final Set properties; + + BiblatexSoftwareField(String name) { + this.name = name; + this.displayName = null; + this.properties = EnumSet.noneOf(FieldProperty.class); + } + + BiblatexSoftwareField(String name, String displayName) { + this.name = name; + this.displayName = displayName; + this.properties = EnumSet.noneOf(FieldProperty.class); + } + + BiblatexSoftwareField(String name, String displayName, FieldProperty first, FieldProperty... rest) { + this.name = name; + this.displayName = displayName; + this.properties = EnumSet.of(first, rest); + } + + BiblatexSoftwareField(String name, FieldProperty first, FieldProperty... rest) { + this.name = name; + this.displayName = null; + this.properties = EnumSet.of(first, rest); + } + + public static Optional fromName(T type, String name) { + if (!(type instanceof BiblatexSoftwareEntryType)) { + return Optional.empty(); + } + return Arrays.stream(BiblatexSoftwareField.values()) + .filter(field -> field.getName().equalsIgnoreCase(name)) + .findAny(); + } + + @Override + public Set getProperties() { + return Collections.unmodifiableSet(properties); + } + + @Override + public String getName() { + return name; + } + + @Override + public boolean isStandardField() { + return false; + } + + @Override + public String getDisplayName() { + if (displayName == null) { + return Field.super.getDisplayName(); + } else { + return displayName; + } + } +} diff --git a/src/main/java/org/jabref/model/entry/field/FieldFactory.java b/src/main/java/org/jabref/model/entry/field/FieldFactory.java index b1c2f3b99b9..07a34b039d3 100644 --- a/src/main/java/org/jabref/model/entry/field/FieldFactory.java +++ b/src/main/java/org/jabref/model/entry/field/FieldFactory.java @@ -73,13 +73,23 @@ public static String serializeFieldsList(Collection fields) { .collect(Collectors.joining(DELIMITER)); } + public static Field parseField(T type, String fieldName) { + return OptionalUtil.orElse( + OptionalUtil.orElse( + OptionalUtil.orElse( + OptionalUtil.orElse( + OptionalUtil.orElse( + InternalField.fromName(fieldName), + StandardField.fromName(fieldName)), + SpecialField.fromName(fieldName)), + IEEEField.fromName(fieldName)), + BiblatexSoftwareField.fromName(type, fieldName)), + BiblatexApaField.fromName(type, fieldName)) + .orElse(new UnknownField(fieldName)); + } + public static Field parseField(String fieldName) { - return OptionalUtil.orElse(OptionalUtil.orElse(OptionalUtil.orElse( - InternalField.fromName(fieldName), - StandardField.fromName(fieldName)), - SpecialField.fromName(fieldName)), - IEEEField.fromName(fieldName)) - .orElse(new UnknownField(fieldName)); + return parseField(null, fieldName); } public static Set getKeyFields() { @@ -138,6 +148,8 @@ private static Set getFieldsFiltered(Predicate selector) { private static Set getAllFields() { Set fields = new HashSet<>(); + fields.addAll(EnumSet.allOf(BiblatexApaField.class)); + fields.addAll(EnumSet.allOf(BiblatexSoftwareField.class)); fields.addAll(EnumSet.allOf(IEEEField.class)); fields.addAll(EnumSet.allOf(InternalField.class)); fields.addAll(EnumSet.allOf(SpecialField.class)); diff --git a/src/main/java/org/jabref/model/entry/field/IEEEField.java b/src/main/java/org/jabref/model/entry/field/IEEEField.java index d00bec02eee..f56ce79ea99 100644 --- a/src/main/java/org/jabref/model/entry/field/IEEEField.java +++ b/src/main/java/org/jabref/model/entry/field/IEEEField.java @@ -31,7 +31,7 @@ public enum IEEEField implements Field { this.properties = EnumSet.of(first, rest); } - public static Optional fromName(String name) { + public static Optional fromName(String name) { return Arrays.stream(IEEEField.values()) .filter(field -> field.getName().equalsIgnoreCase(name)) .findAny(); diff --git a/src/main/java/org/jabref/model/entry/field/StandardField.java b/src/main/java/org/jabref/model/entry/field/StandardField.java index ef3646802e0..bcf9b710b7d 100644 --- a/src/main/java/org/jabref/model/entry/field/StandardField.java +++ b/src/main/java/org/jabref/model/entry/field/StandardField.java @@ -59,14 +59,11 @@ public enum StandardField implements Field { FOREWORD("foreword", FieldProperty.PERSON_NAMES), FOLDER("folder"), GENDER("gender", FieldProperty.GENDER), - HALID("hal_id"), - HALVERSION("hal_version"), HOLDER("holder", FieldProperty.PERSON_NAMES), HOWPUBLISHED("howpublished"), IDS("ids", FieldProperty.MULTIPLE_ENTRY_LINK), INSTITUTION("institution"), INTRODUCTION("introduction", FieldProperty.PERSON_NAMES), - INTRODUCEDIN("introducedin"), ISBN("isbn", "ISBN", FieldProperty.ISBN), ISRN("isrn", "ISRN"), ISSN("issn", "ISSN"), @@ -81,7 +78,6 @@ public enum StandardField implements Field { LANGUAGE("language", FieldProperty.LANGUAGE), LABEL("label"), LIBRARY("library"), - LICENSE("license"), LOCATION("location"), MAINSUBTITLE("mainsubtitle", FieldProperty.BOOK_NAME), MAINTITLE("maintitle", FieldProperty.BOOK_NAME), @@ -106,10 +102,7 @@ public enum StandardField implements Field { PUBSTATE("pubstate", FieldProperty.PUBLICATION_STATE), PRIMARYCLASS("primaryclass"), RELATED("related", FieldProperty.MULTIPLE_ENTRY_LINK), - RELATEDTYPE("relatedtype"), - RELATEDSTRING("relatedstring"), REPORTNO("reportno"), - REPOSITORY("repository"), REVIEW("review"), REVISION("revision"), SCHOOL("school"), @@ -120,7 +113,6 @@ public enum StandardField implements Field { SORTKEY("sortkey"), SORTNAME("sortname", FieldProperty.PERSON_NAMES), SUBTITLE("subtitle"), - SWHID("swhid"), TITLE("title"), TITLEADDON("titleaddon"), TRANSLATOR("translator", FieldProperty.PERSON_NAMES), diff --git a/src/main/java/org/jabref/model/entry/types/BiblatexAPAEntryTypeDefinitions.java b/src/main/java/org/jabref/model/entry/types/BiblatexAPAEntryTypeDefinitions.java new file mode 100644 index 00000000000..f5c0b89b0be --- /dev/null +++ b/src/main/java/org/jabref/model/entry/types/BiblatexAPAEntryTypeDefinitions.java @@ -0,0 +1,43 @@ +package org.jabref.model.entry.types; + +import java.util.Arrays; +import java.util.List; + +import org.jabref.model.entry.BibEntryType; +import org.jabref.model.entry.BibEntryTypeBuilder; +import org.jabref.model.entry.field.BiblatexApaField; +import org.jabref.model.entry.field.StandardField; + +public class BiblatexAPAEntryTypeDefinitions { + + private static final BibEntryType JURISDICTION = new BibEntryTypeBuilder() + .withType(BiblatexApaEntryType.Jurisdiction) + .withImportantFields(StandardField.ORGANIZATION, BiblatexApaField.CITATION_CITEORG, BiblatexApaField.CITATION_CITEDATE, BiblatexApaField.CITATION_CITEDATE, StandardField.ORIGDATE) + .withRequiredFields(StandardField.TITLE, BiblatexApaField.CITATION, BiblatexApaField.CITATION_CITEINFO, StandardField.URL, StandardField.DATE) + .build(); + + private static final BibEntryType LEGISLATION = new BibEntryTypeBuilder() + .withType(BiblatexApaEntryType.Legislation) + .withImportantFields(StandardField.TITLEADDON, StandardField.ORIGDATE) + .withRequiredFields(StandardField.TITLE, StandardField.LOCATION, StandardField.URL, StandardField.DATE) + .build(); + + private static final BibEntryType LEGADMINMATERIAL = new BibEntryTypeBuilder() + .withType(BiblatexApaEntryType.Legadminmaterial) + .withImportantFields(StandardField.NUMBER, StandardField.SHORTTITLE, StandardField.NOTE, StandardField.KEYWORDS) + .withRequiredFields(StandardField.TITLE, BiblatexApaField.CITATION, StandardField.URL, StandardField.DATE) + .build(); + + private static final BibEntryType CONSTITUTION = new BibEntryTypeBuilder() + .withType(BiblatexApaEntryType.Constitution) + .withImportantFields(BiblatexApaField.ARTICLE, BiblatexApaField.AMENDMENT, StandardField.EVENTDATE, StandardField.KEYWORDS, StandardField.PART, BiblatexApaField.SECTION) + .withRequiredFields(BiblatexApaField.SOURCE, StandardField.TYPE) + .build(); + + private static final BibEntryType LEGAL = new BibEntryTypeBuilder() + .withType(BiblatexApaEntryType.Legal) + .withRequiredFields(StandardField.TITLE, StandardField.DATE, StandardField.URI, StandardField.KEYWORDS, StandardField.PART, BiblatexApaField.SECTION) + .build(); + + public static final List ALL = Arrays.asList(JURISDICTION, LEGISLATION, LEGADMINMATERIAL, CONSTITUTION, LEGAL); +} diff --git a/src/main/java/org/jabref/model/entry/types/BiblatexApaEntryType.java b/src/main/java/org/jabref/model/entry/types/BiblatexApaEntryType.java new file mode 100644 index 00000000000..6a1d8d3abe2 --- /dev/null +++ b/src/main/java/org/jabref/model/entry/types/BiblatexApaEntryType.java @@ -0,0 +1,36 @@ +package org.jabref.model.entry.types; + +import java.util.Arrays; +import java.util.Locale; +import java.util.Optional; + +public enum BiblatexApaEntryType implements EntryType { + + Legislation("Legislation"), + Legadminmaterial("Legadminmaterial"), + Jurisdiction("Jurisdiction"), + Constitution("Constitution"), + Legal("Legal"); + + private final String displayName; + + BiblatexApaEntryType(String displayName) { + this.displayName = displayName; + } + + @Override + public String getName() { + return displayName.toLowerCase(Locale.ENGLISH); + } + + @Override + public String getDisplayName() { + return displayName; + } + + public static Optional fromName(String name) { + return Arrays.stream(BiblatexApaEntryType.values()) + .filter(field -> field.getName().equalsIgnoreCase(name)) + .findAny(); + } +} diff --git a/src/main/java/org/jabref/model/entry/types/BiblatexSoftwareEntryType.java b/src/main/java/org/jabref/model/entry/types/BiblatexSoftwareEntryType.java new file mode 100644 index 00000000000..041c48e592a --- /dev/null +++ b/src/main/java/org/jabref/model/entry/types/BiblatexSoftwareEntryType.java @@ -0,0 +1,35 @@ +package org.jabref.model.entry.types; + +import java.util.Arrays; +import java.util.Locale; +import java.util.Optional; + +public enum BiblatexSoftwareEntryType implements EntryType { + + Dataset("Dataset"), + SoftwareVersion("SoftwareVersion"), + SoftwareModule("SoftwareModule"), + CodeFragment("CodeFragment"); + + private final String displayName; + + BiblatexSoftwareEntryType(String displayName) { + this.displayName = displayName; + } + + public static Optional fromName(String name) { + return Arrays.stream(BiblatexSoftwareEntryType.values()) + .filter(field -> field.getName().equalsIgnoreCase(name)) + .findAny(); + } + + @Override + public String getName() { + return displayName.toLowerCase(Locale.ENGLISH); + } + + @Override + public String getDisplayName() { + return displayName; + } +} diff --git a/src/main/java/org/jabref/model/entry/types/BiblatexSoftwareEntryTypeDefinitions.java b/src/main/java/org/jabref/model/entry/types/BiblatexSoftwareEntryTypeDefinitions.java index 0fc48e6d904..6a2e7f0851e 100644 --- a/src/main/java/org/jabref/model/entry/types/BiblatexSoftwareEntryTypeDefinitions.java +++ b/src/main/java/org/jabref/model/entry/types/BiblatexSoftwareEntryTypeDefinitions.java @@ -5,6 +5,7 @@ import org.jabref.model.entry.BibEntryType; import org.jabref.model.entry.BibEntryTypeBuilder; +import org.jabref.model.entry.field.BiblatexSoftwareField; import org.jabref.model.entry.field.OrFields; import org.jabref.model.entry.field.StandardField; @@ -12,40 +13,40 @@ public class BiblatexSoftwareEntryTypeDefinitions { private static final BibEntryType SOFTWARE = new BibEntryTypeBuilder() .withType(StandardEntryType.Software) .withImportantFields(StandardField.DATE, StandardField.DOI, StandardField.EPRINTTYPE, StandardField.EPRINTCLASS, StandardField.EPRINT, - StandardField.EDITOR, StandardField.FILE, StandardField.HALID, StandardField.HALVERSION, StandardField.INSTITUTION, StandardField.INTRODUCEDIN, - StandardField.LICENSE, StandardField.MONTH, StandardField.NOTE, StandardField.ORGANIZATION, StandardField.PUBLISHER, StandardField.RELATED, - StandardField.RELATEDSTRING, StandardField.REPOSITORY, StandardField.SWHID, StandardField.URLDATE, StandardField.VERSION) + StandardField.EDITOR, StandardField.FILE, BiblatexSoftwareField.HALID, BiblatexSoftwareField.HALVERSION, StandardField.INSTITUTION, BiblatexSoftwareField.INTRODUCEDIN, + BiblatexSoftwareField.LICENSE, StandardField.MONTH, StandardField.NOTE, StandardField.ORGANIZATION, StandardField.PUBLISHER, StandardField.RELATED, + BiblatexSoftwareField.RELATEDSTRING, BiblatexSoftwareField.REPOSITORY, BiblatexSoftwareField.SWHID, StandardField.URLDATE, StandardField.VERSION) .withRequiredFields(new OrFields(StandardField.AUTHOR, StandardField.EDITOR), StandardField.TITLE, StandardField.URL, StandardField.VERSION, StandardField.YEAR) .build(); private static final BibEntryType SOFTWAREVERSION = new BibEntryTypeBuilder() - .withType(StandardEntryType.SoftwareVersion) - .withImportantFields(StandardField.DATE, StandardField.EPRINTCLASS, StandardField.EPRINTTYPE, StandardField.HALID, StandardField.HALVERSION, - StandardField.INSTITUTION, StandardField.INTRODUCEDIN, StandardField.LICENSE, StandardField.MONTH, StandardField.NOTE, StandardField.ORGANIZATION, - StandardField.PUBLISHER, StandardField.RELATED, StandardField.RELATEDTYPE, StandardField.RELATEDSTRING, - StandardField.REPOSITORY, StandardField.SWHID, StandardField.SUBTITLE, StandardField.URLDATE) + .withType(BiblatexSoftwareEntryType.SoftwareVersion) + .withImportantFields(StandardField.DATE, StandardField.EPRINTCLASS, StandardField.EPRINTTYPE, BiblatexSoftwareField.HALID, BiblatexSoftwareField.HALVERSION, + StandardField.INSTITUTION, BiblatexSoftwareField.INTRODUCEDIN, BiblatexSoftwareField.LICENSE, StandardField.MONTH, StandardField.NOTE, StandardField.ORGANIZATION, + StandardField.PUBLISHER, StandardField.RELATED, BiblatexSoftwareField.RELATEDTYPE, BiblatexSoftwareField.RELATEDSTRING, + BiblatexSoftwareField.REPOSITORY, BiblatexSoftwareField.SWHID, StandardField.SUBTITLE, StandardField.URLDATE) .withRequiredFields(new OrFields(StandardField.AUTHOR, StandardField.EDITOR), StandardField.TITLE, StandardField.URL, StandardField.YEAR, StandardField.VERSION) - .withDetailFields(StandardField.DATE, StandardField.EPRINTCLASS, StandardField.EPRINTTYPE, StandardField.HALID, StandardField.HALVERSION, - StandardField.INSTITUTION, StandardField.INTRODUCEDIN, StandardField.LICENSE, StandardField.MONTH, StandardField.NOTE, StandardField.ORGANIZATION, - StandardField.PUBLISHER, StandardField.RELATED, StandardField.RELATEDTYPE, StandardField.RELATEDSTRING, - StandardField.REPOSITORY, StandardField.SWHID, StandardField.SUBTITLE, StandardField.URLDATE) + .withDetailFields(StandardField.DATE, StandardField.EPRINTCLASS, StandardField.EPRINTTYPE, BiblatexSoftwareField.HALID, BiblatexSoftwareField.HALVERSION, + StandardField.INSTITUTION, BiblatexSoftwareField.INTRODUCEDIN, BiblatexSoftwareField.LICENSE, StandardField.MONTH, StandardField.NOTE, StandardField.ORGANIZATION, + StandardField.PUBLISHER, StandardField.RELATED, BiblatexSoftwareField.RELATEDTYPE, BiblatexSoftwareField.RELATEDSTRING, + BiblatexSoftwareField.REPOSITORY, BiblatexSoftwareField.SWHID, StandardField.SUBTITLE, StandardField.URLDATE) .withRequiredFields(new OrFields(StandardField.AUTHOR, StandardField.EDITOR), StandardField.TITLE, StandardField.URL, StandardField.YEAR) .build(); private static final BibEntryType SOFTWAREMODULE = new BibEntryTypeBuilder() - .withType(StandardEntryType.SoftwareModule) + .withType(BiblatexSoftwareEntryType.SoftwareModule) .withImportantFields(StandardField.DATE, StandardField.DOI, StandardField.EPRINTTYPE, StandardField.EPRINTCLASS, StandardField.EPRINT, - StandardField.EDITOR, StandardField.FILE, StandardField.HALID, StandardField.HALVERSION, StandardField.INSTITUTION, StandardField.INTRODUCEDIN, - StandardField.LICENSE, StandardField.MONTH, StandardField.NOTE, StandardField.ORGANIZATION, StandardField.PUBLISHER, StandardField.RELATED, - StandardField.RELATEDSTRING, StandardField.REPOSITORY, StandardField.SWHID, StandardField.URLDATE, StandardField.VERSION) + StandardField.EDITOR, StandardField.FILE, BiblatexSoftwareField.HALID, BiblatexSoftwareField.HALVERSION, StandardField.INSTITUTION, BiblatexSoftwareField.INTRODUCEDIN, + BiblatexSoftwareField.LICENSE, StandardField.MONTH, StandardField.NOTE, StandardField.ORGANIZATION, StandardField.PUBLISHER, StandardField.RELATED, + BiblatexSoftwareField.RELATEDSTRING, BiblatexSoftwareField.REPOSITORY, BiblatexSoftwareField.SWHID, StandardField.URLDATE, StandardField.VERSION) .withRequiredFields(StandardField.AUTHOR, StandardField.SUBTITLE, StandardField.URL, StandardField.YEAR) .build(); private static final BibEntryType CODEFRAGMENT = new BibEntryTypeBuilder() - .withType(StandardEntryType.CodeFragment) + .withType(BiblatexSoftwareEntryType.CodeFragment) .withImportantFields(StandardField.DATE, StandardField.DOI, StandardField.EPRINTTYPE, StandardField.EPRINTCLASS, StandardField.EPRINT, - StandardField.EDITOR, StandardField.FILE, StandardField.HALID, StandardField.HALVERSION, StandardField.INSTITUTION, StandardField.INTRODUCEDIN, - StandardField.LICENSE, StandardField.MONTH, StandardField.NOTE, StandardField.ORGANIZATION, StandardField.PUBLISHER, StandardField.RELATED, - StandardField.RELATEDSTRING, StandardField.REPOSITORY, StandardField.SWHID, StandardField.URLDATE, StandardField.VERSION) + StandardField.EDITOR, StandardField.FILE, BiblatexSoftwareField.HALID, BiblatexSoftwareField.HALVERSION, StandardField.INSTITUTION, BiblatexSoftwareField.INTRODUCEDIN, + BiblatexSoftwareField.LICENSE, StandardField.MONTH, StandardField.NOTE, StandardField.ORGANIZATION, StandardField.PUBLISHER, StandardField.RELATED, + BiblatexSoftwareField.RELATEDSTRING, BiblatexSoftwareField.REPOSITORY, BiblatexSoftwareField.SWHID, StandardField.URLDATE, StandardField.VERSION) .withRequiredFields(StandardField.URL) .build(); diff --git a/src/main/java/org/jabref/model/entry/types/EntryTypeFactory.java b/src/main/java/org/jabref/model/entry/types/EntryTypeFactory.java index 1c94f6dd9a0..6b40a56c4f4 100644 --- a/src/main/java/org/jabref/model/entry/types/EntryTypeFactory.java +++ b/src/main/java/org/jabref/model/entry/types/EntryTypeFactory.java @@ -49,6 +49,8 @@ private static boolean isBiblatex(EntryType type) { public static EntryType parse(String typeName) { List types = new ArrayList<>(Arrays.asList(StandardEntryType.values())); types.addAll(Arrays.asList(IEEETranEntryType.values())); + types.addAll(Arrays.asList(BiblatexSoftwareEntryType.values())); + types.addAll(Arrays.asList(BiblatexApaEntryType.values())); types.addAll(Arrays.asList(SystematicLiteratureReviewStudyEntryType.values())); return types.stream().filter(type -> type.getName().equals(typeName.toLowerCase(Locale.ENGLISH))).findFirst().orElse(new UnknownEntryType(typeName)); diff --git a/src/main/java/org/jabref/model/entry/types/StandardEntryType.java b/src/main/java/org/jabref/model/entry/types/StandardEntryType.java index fb2922e61a0..6f6f91ac6a5 100644 --- a/src/main/java/org/jabref/model/entry/types/StandardEntryType.java +++ b/src/main/java/org/jabref/model/entry/types/StandardEntryType.java @@ -36,10 +36,7 @@ public enum StandardEntryType implements EntryType { Thesis("Thesis"), WWW("WWW"), Software("Software"), - Dataset("Dataset"), - SoftwareVersion("SoftwareVersion"), - SoftwareModule("SoftwareModule"), - CodeFragment("CodeFragment"); + Dataset("Dataset"); private final String displayName; diff --git a/src/test/java/org/jabref/logic/exporter/OpenOfficeDocumentCreatorTest.java b/src/test/java/org/jabref/logic/exporter/OpenOfficeDocumentCreatorTest.java index 1c5ebf0cbc8..886398c7725 100644 --- a/src/test/java/org/jabref/logic/exporter/OpenOfficeDocumentCreatorTest.java +++ b/src/test/java/org/jabref/logic/exporter/OpenOfficeDocumentCreatorTest.java @@ -90,6 +90,10 @@ void testPerformExportForSingleEntry(@TempDir Path testFolder) throws Exception Input.Builder control = Input.from(Files.newInputStream(xmlFile)); Input.Builder test = Input.from(Files.newInputStream(contentXmlPath)); + // for debugging purposes + // Path testPath = xmlFile.resolveSibling("test.xml"); + // Files.copy(Files.newInputStream(contentXmlPath), testPath, StandardCopyOption.REPLACE_EXISTING); + assertThat(test, CompareMatcher.isSimilarTo(control) .normalizeWhitespace() .withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)).throwComparisonFailure()); diff --git a/src/test/java/org/jabref/logic/importer/fileformat/CffImporterTest.java b/src/test/java/org/jabref/logic/importer/fileformat/CffImporterTest.java index 38fa42f948d..cc3e27cae1f 100644 --- a/src/test/java/org/jabref/logic/importer/fileformat/CffImporterTest.java +++ b/src/test/java/org/jabref/logic/importer/fileformat/CffImporterTest.java @@ -8,6 +8,7 @@ import org.jabref.logic.util.StandardFileType; import org.jabref.model.entry.BibEntry; +import org.jabref.model.entry.field.BiblatexSoftwareField; import org.jabref.model.entry.field.StandardField; import org.jabref.model.entry.field.UnknownField; import org.jabref.model.entry.types.StandardEntryType; @@ -93,7 +94,7 @@ public void testImportEntriesSwhIdSelect1() throws IOException, URISyntaxExcepti List bibEntries = importer.importDatabase(file).getDatabase().getEntries(); BibEntry entry = bibEntries.get(0); - BibEntry expected = getPopulatedEntry().withField(StandardField.SWHID, "swh:1:rel:22ece559cc7cc2364edc5e5593d63ae8bd229f9f"); + BibEntry expected = getPopulatedEntry().withField(BiblatexSoftwareField.SWHID, "swh:1:rel:22ece559cc7cc2364edc5e5593d63ae8bd229f9f"); assertEquals(entry, expected); } @@ -104,7 +105,7 @@ public void testImportEntriesSwhIdSelect2() throws IOException, URISyntaxExcepti List bibEntries = importer.importDatabase(file).getDatabase().getEntries(); BibEntry entry = bibEntries.get(0); - BibEntry expected = getPopulatedEntry().withField(StandardField.SWHID, "swh:1:cnt:94a9ed024d3859793618152ea559a168bbcbb5e2"); + BibEntry expected = getPopulatedEntry().withField(BiblatexSoftwareField.SWHID, "swh:1:cnt:94a9ed024d3859793618152ea559a168bbcbb5e2"); assertEquals(entry, expected); } @@ -150,12 +151,12 @@ public BibEntry getPopulatedEntry() { entry.setField(StandardField.AUTHOR, "Joe van Smith and Bob Jones, Jr."); entry.setField(StandardField.TITLE, "Test"); entry.setField(StandardField.URL, "www.google.com"); - entry.setField(StandardField.REPOSITORY, "www.github.com"); + entry.setField(BiblatexSoftwareField.REPOSITORY, "www.github.com"); entry.setField(StandardField.DOI, "10.0000/TEST"); entry.setField(StandardField.DATE, "2000-07-02"); entry.setField(StandardField.COMMENT, "Test entry."); entry.setField(StandardField.ABSTRACT, "Test abstract."); - entry.setField(StandardField.LICENSE, "MIT"); + entry.setField(BiblatexSoftwareField.LICENSE, "MIT"); entry.setField(StandardField.VERSION, "1.0"); return entry; diff --git a/src/test/java/org/jabref/model/entry/BibEntryTypesManagerTest.java b/src/test/java/org/jabref/model/entry/BibEntryTypesManagerTest.java index 48b47bc4f32..1e87c87abd7 100644 --- a/src/test/java/org/jabref/model/entry/BibEntryTypesManagerTest.java +++ b/src/test/java/org/jabref/model/entry/BibEntryTypesManagerTest.java @@ -13,6 +13,7 @@ import org.jabref.model.entry.field.OrFields; import org.jabref.model.entry.field.StandardField; import org.jabref.model.entry.field.UnknownField; +import org.jabref.model.entry.types.BiblatexAPAEntryTypeDefinitions; import org.jabref.model.entry.types.BiblatexEntryTypeDefinitions; import org.jabref.model.entry.types.BiblatexSoftwareEntryTypeDefinitions; import org.jabref.model.entry.types.BibtexEntryTypeDefinitions; @@ -74,6 +75,7 @@ void allTypesBibtexAreCorrect() { void allTypesBiblatexAreCorrect() { TreeSet defaultTypes = new TreeSet<>(BiblatexEntryTypeDefinitions.ALL); defaultTypes.addAll(BiblatexSoftwareEntryTypeDefinitions.ALL); + defaultTypes.addAll(BiblatexAPAEntryTypeDefinitions.ALL); assertEquals(defaultTypes, entryTypesManager.getAllTypes(BibDatabaseMode.BIBLATEX)); } diff --git a/src/test/java/org/jabref/model/entry/field/FieldFactoryTest.java b/src/test/java/org/jabref/model/entry/field/FieldFactoryTest.java index 4ee6c716a49..ddb60cb61a7 100644 --- a/src/test/java/org/jabref/model/entry/field/FieldFactoryTest.java +++ b/src/test/java/org/jabref/model/entry/field/FieldFactoryTest.java @@ -1,8 +1,11 @@ package org.jabref.model.entry.field; +import org.jabref.model.entry.types.BiblatexApaEntryType; + import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; class FieldFactoryTest { @Test @@ -14,4 +17,14 @@ void testOrFieldsTwoTerms() { void testOrFieldsThreeTerms() { assertEquals("aaa/bbb/ccc", FieldFactory.serializeOrFields(new UnknownField("aaa"), new UnknownField("bbb"), new UnknownField("ccc"))); } + + @Test + void testDoesNotParseApaFieldWithoutEntryType() { + assertNotEquals(BiblatexApaField.ARTICLE, FieldFactory.parseField("article")); + } + + @Test + void testDoesParseApaFieldWithEntryType() { + assertEquals(BiblatexApaField.ARTICLE, FieldFactory.parseField(BiblatexApaEntryType.Constitution, "article")); + } } diff --git a/src/test/resources/org/jabref/logic/exporter/OldOpenOfficeCalcExportFormatContentSingleEntry.xml b/src/test/resources/org/jabref/logic/exporter/OldOpenOfficeCalcExportFormatContentSingleEntry.xml index 9695f3bdea2..0594bb222be 100644 --- a/src/test/resources/org/jabref/logic/exporter/OldOpenOfficeCalcExportFormatContentSingleEntry.xml +++ b/src/test/resources/org/jabref/logic/exporter/OldOpenOfficeCalcExportFormatContentSingleEntry.xml @@ -150,12 +150,6 @@ Gender - - Hal_id - - - Hal_version - Holder @@ -171,9 +165,6 @@ Introduction - - Introducedin - ISBN @@ -216,9 +207,6 @@ Library - - License - Location @@ -291,18 +279,9 @@ Related - - Relatedtype - - - Relatedstring - Reportno - - Repository - Review @@ -333,9 +312,6 @@ Subtitle - - Swhid - Title @@ -566,15 +542,6 @@ - - - - - - - - - 0097-8418 @@ -638,9 +605,6 @@ - - - 4 @@ -719,18 +683,6 @@ - - - - - - - - - - - - Design and usability in security systems: daily life as a context of use?