From 7bc676699929c6e6c5da1e948e6f3154fcc38c9a Mon Sep 17 00:00:00 2001 From: addak Date: Wed, 9 Mar 2022 23:16:17 +0530 Subject: [PATCH] Add Missing Fillers/Extractors for Supported Fields and Support Day Conversion (#8531) * #8491 : Add Missing Setters/Fillers. Support XMP(DC) -> BibTex For Day Field. * #8491 : Implement Suggestions. Refactor. Add Test for XMP->BibTex for Date Field * #8491 : Change changelog message and update method description * #8491 : Address Requested Changes --- CHANGELOG.md | 1 + .../jabref/logic/xmp/DublinCoreExtractor.java | 167 +++++++++++++----- .../org/jabref/logic/xmp/XmpUtilReader.java | 3 +- .../org/jabref/logic/xmp/XmpUtilWriter.java | 3 +- .../java/org/jabref/model/entry/Date.java | 25 +-- .../model/schema/DublinCoreSchemaCustom.java | 66 +++++++ .../jabref/logic/xmp/XmpUtilReaderTest.java | 24 ++- .../jabref/logic/xmp/XmpUtilWriterTest.java | 11 ++ .../jabref/logic/xmp/article_dublinCore.bib | 1 + .../xmp/article_dublinCore_partial_date.bib | 8 + .../xmp/article_dublinCore_partial_date.pdf | Bin 0 -> 1717 bytes .../xmp/article_dublinCore_without_day.bib | 23 +++ .../xmp/article_dublinCore_without_day.pdf | Bin 0 -> 3072 bytes 13 files changed, 268 insertions(+), 64 deletions(-) create mode 100644 src/main/java/org/jabref/model/schema/DublinCoreSchemaCustom.java create mode 100644 src/test/resources/org/jabref/logic/xmp/article_dublinCore_partial_date.bib create mode 100644 src/test/resources/org/jabref/logic/xmp/article_dublinCore_partial_date.pdf create mode 100644 src/test/resources/org/jabref/logic/xmp/article_dublinCore_without_day.bib create mode 100644 src/test/resources/org/jabref/logic/xmp/article_dublinCore_without_day.pdf diff --git a/CHANGELOG.md b/CHANGELOG.md index d33d741c353..39e94d1044e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -54,6 +54,7 @@ Note that this project **does not** adhere to [Semantic Versioning](http://semve - We moved the search box in preview preferences closer to the available citation styles list. [#8370](https://github.com/JabRef/jabref/pull/8370) - Changing the preference to show the preview panel as a separate tab now has effect without restarting JabRef. [#8370](https://github.com/JabRef/jabref/pull/8370) - We enabled switching themes in JabRef without the need to restart JabRef. [#7335](https://github.com/JabRef/jabref/pull/7335) +- We added support for the field `day`, `rights`, `coverage` and `language` when reading XMP data in Dublin Core format. [#8491](https://github.com/JabRef/jabref/issues/8491) ### Fixed diff --git a/src/main/java/org/jabref/logic/xmp/DublinCoreExtractor.java b/src/main/java/org/jabref/logic/xmp/DublinCoreExtractor.java index 78ed8b6a64a..59af0cb3869 100644 --- a/src/main/java/org/jabref/logic/xmp/DublinCoreExtractor.java +++ b/src/main/java/org/jabref/logic/xmp/DublinCoreExtractor.java @@ -1,7 +1,6 @@ package org.jabref.logic.xmp; -import java.io.IOException; -import java.util.Calendar; +import java.util.Arrays; import java.util.Comparator; import java.util.List; import java.util.Map.Entry; @@ -16,6 +15,7 @@ import org.jabref.model.entry.Author; import org.jabref.model.entry.AuthorList; import org.jabref.model.entry.BibEntry; +import org.jabref.model.entry.Date; import org.jabref.model.entry.Month; import org.jabref.model.entry.field.Field; import org.jabref.model.entry.field.FieldFactory; @@ -24,7 +24,6 @@ import org.jabref.model.entry.types.EntryTypeFactory; import org.jabref.model.strings.StringUtil; -import org.apache.xmpbox.DateConverter; import org.apache.xmpbox.schema.DublinCoreSchema; import org.apache.xmpbox.type.BadFieldValueException; import org.slf4j.Logger; @@ -32,6 +31,10 @@ public class DublinCoreExtractor { + public static final String DC_COVERAGE = "coverage"; + public static final String DC_RIGHTS = "rights"; + public static final String DC_SOURCE = "source"; + private static final Logger LOGGER = LoggerFactory.getLogger(DublinCoreExtractor.class); private final DublinCoreSchema dcSchema; @@ -71,32 +74,19 @@ private void extractAuthor() { } /** - * Year in BibTex - Date in DublinCore is only the year information, because dc interprets empty months as January. - * Tries to extract the month as well. In JabRef the bibtex/month/value is prioritized.
The problem is the - * default value of the calendar, which is always January, also if there is no month information in the xmp metdata. - * The idea is, to reject all information with YYYY-01-01. In cases, where xmp is written with JabRef the month - * property filled with jan will override this behavior and no data is lost. In the cases, where xmp is written by - * another service, the assumption is, that the 1st January is not a publication date at all. + * Bibtex-Fields : year, [month], [day] - 'dc:date' in DublinCore */ - private void extractYearAndMonth() { + private void extractDate() { List dates = dcSchema.getUnqualifiedSequenceValueList("date"); if ((dates != null) && !dates.isEmpty()) { + String date = dates.get(0).trim(); - Calendar calender = null; - try { - calender = DateConverter.toCalendar(date); - } catch (IOException ignored) { - // Ignored - } - if (calender != null) { - bibEntry.setField(StandardField.YEAR, String.valueOf(calender.get(Calendar.YEAR))); - int monthNumber = calender.get(Calendar.MONTH) + 1; - // not the 1st of January - if (!((monthNumber == 1) && (calender.get(Calendar.DAY_OF_MONTH) == 1))) { - Month.getMonthByNumber(monthNumber) - .ifPresent(month -> bibEntry.setMonth(month)); - } - } + Date.parse(date) + .ifPresent(dateValue -> { + dateValue.getDay().ifPresent(day -> bibEntry.setField(StandardField.DAY, Integer.toString(day))); + dateValue.getMonth().ifPresent(bibEntry::setMonth); + dateValue.getYear().ifPresent(year -> bibEntry.setField(StandardField.YEAR, Integer.toString(year))); + }); } } @@ -182,7 +172,7 @@ private void extractRights() { LOGGER.warn("Could not extract rights", e); } if (!StringUtil.isNullOrEmpty(rights)) { - bibEntry.setField(new UnknownField("rights"), rights); + bibEntry.setField(new UnknownField(DC_RIGHTS), rights); } } @@ -192,7 +182,7 @@ private void extractRights() { private void extractSource() { String source = dcSchema.getSource(); if (!StringUtil.isNullOrEmpty(source)) { - bibEntry.setField(new UnknownField("source"), source); + bibEntry.setField(new UnknownField(DC_SOURCE), source); } } @@ -234,6 +224,29 @@ private void extractType() { } } + /** + * No Equivalent in BibTex. Will create an Unknown "Coverage" Field + */ + private void extractCoverage() { + String coverage = dcSchema.getCoverage(); + if (!StringUtil.isNullOrEmpty(coverage)) { + bibEntry.setField(FieldFactory.parseField(DC_COVERAGE), coverage); + } + } + + /** + * Language is equivalent in both formats (BibTex and DublinCore) + */ + private void extractLanguages() { + StringBuilder builder = new StringBuilder(); + + List languages = dcSchema.getLanguages(); + if (languages != null && !languages.isEmpty()) { + languages.forEach(language -> builder.append(",").append(language)); + bibEntry.setField(StandardField.LANGUAGE, builder.substring(1)); + } + } + /** * Helper function for retrieving a BibEntry from the DublinCore metadata in a PDF file. *

@@ -252,7 +265,7 @@ public Optional extractBibtexEntry() { // then extract all "standard" dublin core entries this.extractEditor(); this.extractAuthor(); - this.extractYearAndMonth(); + this.extractDate(); this.extractAbstract(); this.extractDOI(); this.extractPublisher(); @@ -261,6 +274,8 @@ public Optional extractBibtexEntry() { this.extractSubject(); this.extractTitle(); this.extractType(); + this.extractCoverage(); + this.extractLanguages(); // we pass a new BibEntry in the constructor which is never empty as it already consists of "@misc" if (bibEntry.getFieldMap().isEmpty()) { @@ -350,6 +365,37 @@ private void fillTitle(String title) { dcSchema.setTitle(title); } + /** + * BibTex : Coverage (Custom Field); DC Field : Coverage + * + * @param coverage + */ + private void fillCoverage(String coverage) { + dcSchema.setCoverage(coverage); + } + + /** + * BibTex Field : language ; DC Field : dc:language + */ + private void fillLanguages(String languages) { + Arrays.stream(languages.split(",")) + .forEach(dcSchema::addLanguage); + } + + /** + * BibTex : Rights (Custom Field); DC Field : dc:rights + */ + private void fillRights(String rights) { + dcSchema.addRights(null, rights.split(",")[0]); + } + + /** + * BibTex : Source (Custom Field); DC Field : Source + */ + private void fillSource(String source) { + dcSchema.setSource(source); + } + /** * All others (+ citation key) get packaged in the relation attribute * @@ -366,29 +412,60 @@ public void fillDublinCoreSchema() { Set> fieldValues = new TreeSet<>(Comparator.comparing(fieldStringEntry -> fieldStringEntry.getKey().getName())); fieldValues.addAll(bibEntry.getFieldMap().entrySet()); + boolean hasStandardYearField = fieldValues.stream().anyMatch(field -> StandardField.YEAR.equals(field.getKey())); for (Entry field : fieldValues) { if (useXmpPrivacyFilter && xmpPreferences.getXmpPrivacyFilter().contains(field.getKey())) { continue; } - if (StandardField.EDITOR.equals(field.getKey())) { - this.fillContributor(field.getValue()); - } else if (StandardField.AUTHOR.equals(field.getKey())) { - this.fillCreator(field.getValue()); - } else if (StandardField.YEAR.equals(field.getKey())) { - this.fillDate(); - } else if (StandardField.ABSTRACT.equals(field.getKey())) { - this.fillDescription(field.getValue()); - } else if (StandardField.DOI.equals(field.getKey())) { - this.fillIdentifier(field.getValue()); - } else if (StandardField.PUBLISHER.equals(field.getKey())) { - this.fillPublisher(field.getValue()); - } else if (StandardField.KEYWORDS.equals(field.getKey())) { - this.fillKeywords(field.getValue()); - } else if (StandardField.TITLE.equals(field.getKey())) { - this.fillTitle(field.getValue()); + Field fieldEntry = field.getKey(); + if (fieldEntry instanceof StandardField) { + switch ((StandardField) fieldEntry) { + case EDITOR: + this.fillContributor(field.getValue()); + break; + case AUTHOR: + this.fillCreator(field.getValue()); + break; + case YEAR: + this.fillDate(); + break; + case ABSTRACT: + this.fillDescription(field.getValue()); + break; + case DOI: + this.fillIdentifier(field.getValue()); + break; + case PUBLISHER: + this.fillPublisher(field.getValue()); + break; + case KEYWORDS: + this.fillKeywords(field.getValue()); + break; + case TITLE: + this.fillTitle(field.getValue()); + break; + case LANGUAGE: + this.fillLanguages(field.getValue()); + break; + case DAY: + case MONTH: + if (hasStandardYearField) { + break; + } + default: + this.fillCustomField(field.getKey(), field.getValue()); + } } else { - this.fillCustomField(field.getKey(), field.getValue()); + if (DC_COVERAGE.equals(fieldEntry.getName())) { + this.fillCoverage(field.getValue()); + } else if (DC_RIGHTS.equals(fieldEntry.getName())) { + this.fillRights(field.getValue()); + } else if (DC_SOURCE.equals(fieldEntry.getName())) { + this.fillSource(field.getValue()); + } else { + this.fillCustomField(field.getKey(), field.getValue()); + } } } diff --git a/src/main/java/org/jabref/logic/xmp/XmpUtilReader.java b/src/main/java/org/jabref/logic/xmp/XmpUtilReader.java index 21be8d96000..51248543d94 100644 --- a/src/main/java/org/jabref/logic/xmp/XmpUtilReader.java +++ b/src/main/java/org/jabref/logic/xmp/XmpUtilReader.java @@ -10,6 +10,7 @@ import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.LinkedFile; +import org.jabref.model.schema.DublinCoreSchemaCustom; import org.apache.pdfbox.Loader; import org.apache.pdfbox.pdmodel.PDDocument; @@ -77,8 +78,8 @@ public static List readXmp(Path path, XmpPreferences xmpPreferences) if (!xmpMetaList.isEmpty()) { // Only support Dublin Core since JabRef 4.2 for (XMPMetadata xmpMeta : xmpMetaList) { - DublinCoreSchema dcSchema = xmpMeta.getDublinCoreSchema(); + DublinCoreSchema dcSchema = DublinCoreSchemaCustom.copyDublinCoreSchema(xmpMeta.getDublinCoreSchema()); if (dcSchema != null) { DublinCoreExtractor dcExtractor = new DublinCoreExtractor(dcSchema, xmpPreferences, new BibEntry()); Optional entry = dcExtractor.extractBibtexEntry(); diff --git a/src/main/java/org/jabref/logic/xmp/XmpUtilWriter.java b/src/main/java/org/jabref/logic/xmp/XmpUtilWriter.java index 7133d3773b6..60fbc825b5b 100644 --- a/src/main/java/org/jabref/logic/xmp/XmpUtilWriter.java +++ b/src/main/java/org/jabref/logic/xmp/XmpUtilWriter.java @@ -19,6 +19,7 @@ import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.field.Field; import org.jabref.model.entry.field.StandardField; +import org.jabref.model.schema.DublinCoreSchemaCustom; import org.apache.pdfbox.Loader; import org.apache.pdfbox.pdmodel.PDDocument; @@ -160,7 +161,7 @@ private static void writeDublinCore(PDDocument document, meta.removeSchema(meta.getDublinCoreSchema()); for (BibEntry entry : resolvedEntries) { - DublinCoreSchema dcSchema = meta.createAndAddDublinCoreSchema(); + DublinCoreSchema dcSchema = DublinCoreSchemaCustom.copyDublinCoreSchema(meta.createAndAddDublinCoreSchema()); XmpUtilWriter.writeToDCSchema(dcSchema, entry, null, xmpPreferences); } diff --git a/src/main/java/org/jabref/model/entry/Date.java b/src/main/java/org/jabref/model/entry/Date.java index b63b78c7781..a5266eb7521 100644 --- a/src/main/java/org/jabref/model/entry/Date.java +++ b/src/main/java/org/jabref/model/entry/Date.java @@ -20,18 +20,19 @@ public class Date { private static final DateTimeFormatter SIMPLE_DATE_FORMATS; static { List formatStrings = Arrays.asList( - "uuuu-M-d", // covers 2009-1-15 - "uuuu-M", // covers 2009-11 - "d-M-uuuu", // covers 15-1-2012 - "M-uuuu", // covers 1-2012 - "M/uuuu", // covers 9/2015 and 09/2015 - "M/uu", // covers 9/15 - "MMMM d, uuuu", // covers September 1, 2015 - "MMMM, uuuu", // covers September, 2015 - "d.M.uuuu", // covers 15.1.2015 - "uuuu.M.d", // covers 2015.1.15 - "uuuu", // covers 2015 - "MMM, uuuu"); // covers Jan, 2020 + "uuuu-MM-dd'T'HH:mm:ss[xxx][xx][X]", // covers 2018-10-03T07:24:14+03:00 + "uuuu-M-d", // covers 2009-1-15 + "uuuu-M", // covers 2009-11 + "d-M-uuuu", // covers 15-1-2012 + "M-uuuu", // covers 1-2012 + "M/uuuu", // covers 9/2015 and 09/2015 + "M/uu", // covers 9/15 + "MMMM d, uuuu", // covers September 1, 2015 + "MMMM, uuuu", // covers September, 2015 + "d.M.uuuu", // covers 15.1.2015 + "uuuu.M.d", // covers 2015.1.15 + "uuuu", // covers 2015 + "MMM, uuuu"); // covers Jan, 2020 SIMPLE_DATE_FORMATS = formatStrings.stream() .map(DateTimeFormatter::ofPattern) diff --git a/src/main/java/org/jabref/model/schema/DublinCoreSchemaCustom.java b/src/main/java/org/jabref/model/schema/DublinCoreSchemaCustom.java new file mode 100644 index 00000000000..e4d4cfe3215 --- /dev/null +++ b/src/main/java/org/jabref/model/schema/DublinCoreSchemaCustom.java @@ -0,0 +1,66 @@ +package org.jabref.model.schema; + +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.reflect.FieldUtils; +import org.apache.xmpbox.XMPMetadata; +import org.apache.xmpbox.schema.DublinCoreSchema; +import org.apache.xmpbox.type.AbstractField; +import org.apache.xmpbox.type.ArrayProperty; +import org.apache.xmpbox.type.DateType; +import org.apache.xmpbox.type.StructuredType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A DublinCoreSchema extension Class. + * In case anyone intends to alter standard behaviour. + */ +@StructuredType(preferedPrefix = "dc", namespace = "http://purl.org/dc/elements/1.1/") +public class DublinCoreSchemaCustom extends DublinCoreSchema { + + private static final Logger LOGGER = LoggerFactory.getLogger(DublinCoreSchemaCustom.class); + + public DublinCoreSchemaCustom(XMPMetadata metadata) { + super(metadata); + } + + public static DublinCoreSchema copyDublinCoreSchema(DublinCoreSchema dcSchema) { + if (Objects.isNull(dcSchema)) { + return null; + } + + try { + DublinCoreSchemaCustom dublinCoreSchemaCustom = new DublinCoreSchemaCustom(dcSchema.getMetadata()); + FieldUtils.writeField(dublinCoreSchemaCustom, "container", dcSchema.getContainer(), true); + FieldUtils.writeField(dublinCoreSchemaCustom, "attributes", + FieldUtils.readField(dcSchema, "attributes", true), true); + return dublinCoreSchemaCustom; + } catch (Exception e) { + LOGGER.error("Error making custom DC Schema. Using the default", e); + return dcSchema; + } + } + + /** + * Overloaded XMP Schema method + * Behaviour is same except when seqName is "Date". Will return raw value instead + */ + @Override + public List getUnqualifiedSequenceValueList(String seqName) { + AbstractField abstractProperty = getAbstractProperty(seqName); + if (abstractProperty instanceof ArrayProperty) { + if ("date".equals(seqName)) { + return ((ArrayProperty) abstractProperty).getContainer() + .getAllProperties() + .stream() + .map(field -> (String) ((DateType) field).getRawValue()) + .collect(Collectors.toList()); + } + return ((ArrayProperty) abstractProperty).getElementsAsString(); + } + return null; + } +} diff --git a/src/test/java/org/jabref/logic/xmp/XmpUtilReaderTest.java b/src/test/java/org/jabref/logic/xmp/XmpUtilReaderTest.java index 8f012187d37..fe93d9f0504 100644 --- a/src/test/java/org/jabref/logic/xmp/XmpUtilReaderTest.java +++ b/src/test/java/org/jabref/logic/xmp/XmpUtilReaderTest.java @@ -10,11 +10,11 @@ import java.util.Optional; import org.jabref.logic.importer.ImportFormatPreferences; -import org.jabref.logic.importer.ParseException; import org.jabref.logic.importer.fileformat.BibtexImporter; import org.jabref.logic.importer.fileformat.BibtexParser; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.LinkedFile; +import org.jabref.model.schema.DublinCoreSchemaCustom; import org.jabref.model.util.DummyFileUpdateMonitor; import org.apache.xmpbox.XMPMetadata; @@ -53,15 +53,15 @@ void setUp() { * Tests reading of dublinCore metadata. */ @Test - void testReadArticleDublinCoreReadRawXmp() throws IOException, URISyntaxException, ParseException { - Path path = Path.of(XmpUtilShared.class.getResource("article_dublinCore.pdf").toURI()); + void testReadArticleDublinCoreReadRawXmp() throws IOException, URISyntaxException { + Path path = Path.of(XmpUtilShared.class.getResource("article_dublinCore_without_day.pdf").toURI()); List meta = XmpUtilReader.readRawXmp(path); - DublinCoreSchema dcSchema = meta.get(0).getDublinCoreSchema(); + DublinCoreSchema dcSchema = DublinCoreSchemaCustom.copyDublinCoreSchema(meta.get(0).getDublinCoreSchema()); DublinCoreExtractor dcExtractor = new DublinCoreExtractor(dcSchema, xmpPreferences, new BibEntry()); Optional entry = dcExtractor.extractBibtexEntry(); - Path bibFile = Path.of(XmpUtilShared.class.getResource("article_dublinCore.bib").toURI()); + Path bibFile = Path.of(XmpUtilShared.class.getResource("article_dublinCore_without_day.bib").toURI()); List expected = testImporter.importDatabase(bibFile, StandardCharsets.UTF_8).getDatabase().getEntries(); assertEquals(expected, Collections.singletonList(entry.get())); @@ -85,6 +85,20 @@ void testReadArticleDublinCoreReadXmp() throws IOException, URISyntaxException { assertEquals(expected, entries); } + @Test + void testReadArticleDublinCoreReadXmpPartialDate() throws IOException, URISyntaxException { + Path pathPdf = Path.of(XmpUtilShared.class.getResource("article_dublinCore_partial_date.pdf").toURI()); + List entries = XmpUtilReader.readXmp(pathPdf, xmpPreferences); + Path bibFile = Path.of(XmpUtilShared.class.getResource("article_dublinCore_partial_date.bib").toURI()); + List expected = testImporter.importDatabase(bibFile, StandardCharsets.UTF_8).getDatabase().getEntries(); + + expected.forEach(bibEntry -> bibEntry.setFiles(Arrays.asList( + new LinkedFile("", pathPdf.toAbsolutePath(), "PDF")) + )); + + assertEquals(expected, entries); + } + /** * Tests an pdf file with an empty metadata section. */ diff --git a/src/test/java/org/jabref/logic/xmp/XmpUtilWriterTest.java b/src/test/java/org/jabref/logic/xmp/XmpUtilWriterTest.java index 6013264bea4..537e0d08a42 100644 --- a/src/test/java/org/jabref/logic/xmp/XmpUtilWriterTest.java +++ b/src/test/java/org/jabref/logic/xmp/XmpUtilWriterTest.java @@ -8,8 +8,10 @@ import javax.xml.transform.TransformerException; import org.jabref.model.entry.BibEntry; +import org.jabref.model.entry.Date; import org.jabref.model.entry.Month; import org.jabref.model.entry.field.StandardField; +import org.jabref.model.entry.field.UnknownField; import org.jabref.model.entry.types.StandardEntryType; import org.apache.pdfbox.pdmodel.PDDocument; @@ -18,6 +20,9 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; +import static org.jabref.logic.xmp.DublinCoreExtractor.DC_COVERAGE; +import static org.jabref.logic.xmp.DublinCoreExtractor.DC_RIGHTS; +import static org.jabref.logic.xmp.DublinCoreExtractor.DC_SOURCE; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -68,6 +73,12 @@ private void initBibEntries() { vapnik2000.setField(StandardField.AUTHOR, "Vladimir N. Vapnik"); vapnik2000.setField(StandardField.DOI, "10.1007/978-1-4757-3264-1"); vapnik2000.setField(StandardField.OWNER, "Ich"); + vapnik2000.setField(StandardField.LANGUAGE, "English, Japanese"); + vapnik2000.setDate(new Date(2000, 5)); + + vapnik2000.setField(new UnknownField(DC_COVERAGE), "coverageField"); + vapnik2000.setField(new UnknownField((DC_SOURCE)), "JabRef"); + vapnik2000.setField(new UnknownField(DC_RIGHTS), "Right To X"); } /** diff --git a/src/test/resources/org/jabref/logic/xmp/article_dublinCore.bib b/src/test/resources/org/jabref/logic/xmp/article_dublinCore.bib index 82c5604dd38..f959a333921 100644 --- a/src/test/resources/org/jabref/logic/xmp/article_dublinCore.bib +++ b/src/test/resources/org/jabref/logic/xmp/article_dublinCore.bib @@ -7,6 +7,7 @@ @Article{Olly2018 number = {1}, pages = {1-2}, month = mar, + day = {1}, issn = {978-123-123}, note = {That's a note}, abstract = {That's an abstract}, diff --git a/src/test/resources/org/jabref/logic/xmp/article_dublinCore_partial_date.bib b/src/test/resources/org/jabref/logic/xmp/article_dublinCore_partial_date.bib new file mode 100644 index 00000000000..39c4e5d137e --- /dev/null +++ b/src/test/resources/org/jabref/logic/xmp/article_dublinCore_partial_date.bib @@ -0,0 +1,8 @@ +@Article{, + coverage = {coverageField}, + language = {English,Japanese}, + month = jan, + rights = {Right To X}, + source = {JabRef}, + year = {2005}, +} diff --git a/src/test/resources/org/jabref/logic/xmp/article_dublinCore_partial_date.pdf b/src/test/resources/org/jabref/logic/xmp/article_dublinCore_partial_date.pdf new file mode 100644 index 0000000000000000000000000000000000000000..b9343488134c003a48eeeef8ccaaa42d35814438 GIT binary patch literal 1717 zcmb7Fe`p(39G@sChn*V;IyU5SvnoRJa%nDE;^k)2G|aNJGbygFR(iR6Np88^op&$h zT8BeWk>YftLy%SHkN^Au^9N&jaGb3y%4SwA&E-;Lh%{6|I<`p` zImiMkLCPCd9B12ngi(=WvT;AMNRGw!Pg+HqB0%pJ4T63YuSt5bO7U%DOIT7WdQ2^& zriy)fQB&=b0I349UOTpi>6c7NM>gsJYMQ*{uC#S3s5DD0may&d;3htyVUKCmDb1c6 zOq_Lm3Mxod4YOjFQh*@?3|~@X1sKgg-Kf?-u8EJ~)Ssj@`x4>Xmgw$_$c8*LJg5I2$DBDlAq zRndfnRayHV#q*Fi1M*yI*J;yAI)gI!D)odL~0Zcl^A`e_j4 zg6(NAnBSkn6$TCfVoIwTMizi+jZ`CrWJ5vJXxSJign#Gt%+lPiiwg&h>{Vw!`})`?k;{8FCm#=NlZ1_bEFanQ z%240N_ou#zzWvU2CvfxmlOHRe2OseZE0d*}%+%FE=EK>o7Y-hu`u@N(XL60BFYlXO z8GHVT$5acwZhG>TnNy1oe7TK%Hd%Nzsh@aj?w2#CpE~#S zbuTr3e9<^CKKjFxhri9ecJkH}p(W)Qf2uKX@yN;*d1L!HeL( zA)|y#FBl-)(ihmGew=XIdT` y`*XfgpRa#Z|FquNbma?Mw%l!9zhUd6mo0aQ+{TiH9gBG9LLu@>b@vUXnZE&44IV83 literal 0 HcmV?d00001 diff --git a/src/test/resources/org/jabref/logic/xmp/article_dublinCore_without_day.bib b/src/test/resources/org/jabref/logic/xmp/article_dublinCore_without_day.bib new file mode 100644 index 00000000000..82c5604dd38 --- /dev/null +++ b/src/test/resources/org/jabref/logic/xmp/article_dublinCore_without_day.bib @@ -0,0 +1,23 @@ +@Article{Olly2018, + author = {Olly and Johannes}, + title = {Stefan's palace}, + journal = {Test Journal}, + year = {2018}, + volume = {1}, + number = {1}, + pages = {1-2}, + month = mar, + issn = {978-123-123}, + note = {That's a note}, + abstract = {That's an abstract}, + comment = {That's a comment}, + doi = {10/3212.3123}, + file = {:paper.pdf:PDF}, + groups = {NO}, + howpublished = {Online}, + keywords = {Keyword1, Keyword2}, + owner = {Me}, + review = {Here are the reviews}, + timestamp = {2018-02-15}, + url = {https://www.olly2018.edu}, +} diff --git a/src/test/resources/org/jabref/logic/xmp/article_dublinCore_without_day.pdf b/src/test/resources/org/jabref/logic/xmp/article_dublinCore_without_day.pdf new file mode 100644 index 0000000000000000000000000000000000000000..ae2d982b0a3ce89f65a04cf5d36d32810eabad38 GIT binary patch literal 3072 zcmb7GeQXnD7)P>%aI&~X5r=$Sien3*eebU8SZiC{RvKlD!8X`rGP&NpYp=WB9d}pS zO^7Uh0DtfiA(M>(f#3`(R@5j9Avim41?weE?tSig ze$TJZ`@FyR$)4l!nn_DOmVK?~)^8Yz6S(LLVooOpDjOt-gJN2xdC`x7`A}9kQNRId z$-}@L+7A_+Lhj`lD1|D`B0t;~U%TBH6j%*LTMxj^f`VTS;1o%qa2*wq=O`2JWyd|PExfB=}B4U9-0)E`8XEK z0La4-6jTM3kpw1Oqd@z_u<9}m;2}hoaj=7cak6;)iBm4*Rf8!(fakQl4xSeLE>qOZ z!a6$4t0s44fL3!9oEC7}hpI|5suO5QdCq{Ln~bt0a{^2yj8hZ=*ryekNy@7IQi%zQVOgMgPze4%Saw zr4$to`JfEQRD8vVfLu#c!j&{h1EiTs1z3hlI2ZvhLK)&T`l$hk>$YTFJfwM4E`(}D zha{l2o0*`@q%D=SNJxMtQA$Fi#6-hdARA64eu>D3LojLW^l;;0iJ!C~r%F3&9E&=i ztK*>TCJA7rNXlZ3_sad>G?CRFEkp_Xf{-x^*CP*S32canGW+OFPB}C`p3WGj z>$wqJ%T_1KAzF3QlEiaNTm=D=qquM4lW_~R8~VXI8T-Y^tx#4uhJSb|jB)XN25_Cd z;YN)o)vf5dMk^<{cg4F0M+7u10r zvvCRoUXE9xi~}#aP@o4gA`3O6jMU9;oKB)`3(NcJPZLkws+!RAP36XOC+N_anO}!C ze77r*|^S$DU zrrVX{9XGB%`Pa?%G1$00`^J+ugRv`2udwC9f!OM@H*6X6kLN_rzVd3|=`C-2gOlxd z+hWq4j>g;XZq9jZUHQ&0YEE7wM)mi8M1Ef!YkK*;VA?xVmY)B;WP~}^(A3^F>A?E# zpQmIk!6s~~#cDS#xAiv_JpS56$K|CL_mn6tKl-;`Ue3=oNw+Ik;aB%{ZL=Ki`&%#qzA=T`YXzxekDe2?GOxxet)sT~;wnQQlrXbrAC zwxf0R#5wqf&0psJap`P$bZlDhmP@AAVIy-wzkWvSnA?6jx8umN#ksBLGT)*K4^Qnb z-gW5$eX8$uX4{?2v@6Tre-2FEFy_zftv?;yxwSoWU0>Dl=8u2*Cw6MZo9B108BHo< zKg~Toyk&exTTA~+cvLcvwf!*q{Mj=bkC7`J&CZ=yt5@aBn|HKzd#wM77i`BSC+UKM zp1(c`AJA?FE?K3=9!k$+|q5h59BpG3 zExK{IyYq18x1EPNyE8^?&&smblEa3LTQfYI3FK1eTpWqs)u_3oi@J ADgXcg literal 0 HcmV?d00001