diff --git a/src/main/java/org/jabref/gui/entryeditor/FieldExtraComponents.java b/src/main/java/org/jabref/gui/entryeditor/FieldExtraComponents.java index 5a73493ddf8..f6b71612967 100644 --- a/src/main/java/org/jabref/gui/entryeditor/FieldExtraComponents.java +++ b/src/main/java/org/jabref/gui/entryeditor/FieldExtraComponents.java @@ -8,9 +8,13 @@ import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import java.util.Locale; import java.util.Optional; import java.util.Set; +import java.util.stream.Collectors; import javax.swing.JButton; import javax.swing.JComboBox; @@ -43,7 +47,7 @@ import org.jabref.model.entry.FieldName; import org.jabref.model.entry.FieldProperty; import org.jabref.model.entry.InternalBibtexFields; -import org.jabref.model.entry.MonthUtil; +import org.jabref.model.entry.Month; import org.jabref.model.entry.identifier.DOI; import org.jabref.model.entry.identifier.ISBN; import org.jabref.preferences.JabRefPreferences; @@ -378,19 +382,19 @@ public static Optional getYesNoExtraComponent(FieldEditor fieldEdito * @return */ public static Optional getMonthExtraComponent(FieldEditor fieldEditor, EntryEditor entryEditor, BibDatabaseMode type) { - final String[] options = new String[13]; - options[0] = Localization.lang("Select"); - for (int i = 1; i <= 12; i++) { - options[i] = MonthUtil.getMonthByNumber(i).fullName; - } - JComboBox month = new JComboBox<>(options); + List monthNames = Arrays.stream(Month.values()).map(Month::getFullName).collect(Collectors.toList()); + List options = new ArrayList<>(13); + options.add(Localization.lang("Select")); + options.addAll(monthNames); + + JComboBox month = new JComboBox<>(options.toArray(new String[0])); month.addActionListener(actionEvent -> { - int monthnumber = month.getSelectedIndex(); - if (monthnumber >= 1) { + int monthNumber = month.getSelectedIndex(); + if (monthNumber >= 1) { if (type == BibDatabaseMode.BIBLATEX) { - fieldEditor.setText(String.valueOf(monthnumber)); + fieldEditor.setText(String.valueOf(monthNumber)); } else { - fieldEditor.setText(MonthUtil.getMonthByNumber(monthnumber).bibtexFormat); + fieldEditor.setText(Month.getMonthByNumber(monthNumber).get().getJabRefFormat()); } } else { fieldEditor.setText(""); diff --git a/src/main/java/org/jabref/gui/importer/fetcher/OAI2Fetcher.java b/src/main/java/org/jabref/gui/importer/fetcher/OAI2Fetcher.java index 360f2342446..8bdce779290 100644 --- a/src/main/java/org/jabref/gui/importer/fetcher/OAI2Fetcher.java +++ b/src/main/java/org/jabref/gui/importer/fetcher/OAI2Fetcher.java @@ -9,6 +9,7 @@ import java.nio.charset.StandardCharsets; import java.util.Date; import java.util.Locale; +import java.util.Optional; import javax.swing.JOptionPane; import javax.swing.JPanel; @@ -24,7 +25,7 @@ import org.jabref.logic.l10n.Localization; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.FieldName; -import org.jabref.model.entry.MonthUtil; +import org.jabref.model.entry.Month; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -188,10 +189,8 @@ protected BibEntry importOai2Entry(String key) throws IOException, SAXException entry.setField(FieldName.YEAR, "20" + fixedKey.substring(0, 2)); int monthNumber = Integer.parseInt(fixedKey.substring(2, 4)); - MonthUtil.Month month = MonthUtil.getMonthByNumber(monthNumber); - if (month.isValid()) { - entry.setField(FieldName.MONTH, month.bibtexFormat); - } + Optional month = Month.getMonthByNumber(monthNumber); + month.ifPresent(entry::setMonth); } } return entry; diff --git a/src/main/java/org/jabref/logic/bibtex/LatexFieldFormatter.java b/src/main/java/org/jabref/logic/bibtex/LatexFieldFormatter.java index 2148b75fc2f..64346eb96cb 100644 --- a/src/main/java/org/jabref/logic/bibtex/LatexFieldFormatter.java +++ b/src/main/java/org/jabref/logic/bibtex/LatexFieldFormatter.java @@ -108,6 +108,11 @@ public String format(String content, String fieldName) throws InvalidFieldValueE return formatAndResolveStrings(result, fieldName); } + /** + * This method handles # in the field content to get valid bibtex strings + * + * For instance, #jan# - #feb# gets jan #{ - } # feb (see @link{org.jabref.logic.bibtex.LatexFieldFormatterTests#makeHashEnclosedWordsRealStringsInMonthField()}) + */ private String formatAndResolveStrings(String content, String fieldName) throws InvalidFieldValueException { stringBuilder = new StringBuilder(); checkBraces(content); @@ -163,7 +168,6 @@ private String formatAndResolveStrings(String content, String fieldName) throws pivot = pos2 + 1; } else { pivot = pos1 + 1; - //if (tell++ > 10) System.exit(0); } } @@ -233,7 +237,7 @@ private void writeText(String text, int startPos, int endPos) { inCommandName = false; inCommand = true; } else { - // Or simply the end of this command altogether: + // Or simply the end of this command alltogether: commandName.delete(0, commandName.length()); inCommandName = false; } diff --git a/src/main/java/org/jabref/logic/bibtex/comparator/FieldComparator.java b/src/main/java/org/jabref/logic/bibtex/comparator/FieldComparator.java index 12714762c69..b8a1fe54ab2 100644 --- a/src/main/java/org/jabref/logic/bibtex/comparator/FieldComparator.java +++ b/src/main/java/org/jabref/logic/bibtex/comparator/FieldComparator.java @@ -13,7 +13,7 @@ import org.jabref.model.entry.FieldName; import org.jabref.model.entry.FieldProperty; import org.jabref.model.entry.InternalBibtexFields; -import org.jabref.model.entry.MonthUtil; +import org.jabref.model.entry.Month; import org.jabref.model.metadata.SaveOrderConfig; import org.jabref.model.strings.StringUtil; @@ -118,7 +118,9 @@ public int compare(BibEntry e1, BibEntry e2) { int comparisonResult = Integer.compare(f1year, f2year); return comparisonResult * multiplier; } else if (fieldType == FieldType.MONTH) { - return Integer.compare(MonthUtil.getMonth(f1).number, MonthUtil.getMonth(f2).number) * multiplier; + int month1 = Month.parse(f1).map(Month::getNumber).orElse(-1); + int month2 = Month.parse(f2).map(Month::getNumber).orElse(-1); + return Integer.compare(month1, month2) * multiplier; } if (isNumeric) { diff --git a/src/main/java/org/jabref/logic/formatter/bibtexfields/NormalizeDateFormatter.java b/src/main/java/org/jabref/logic/formatter/bibtexfields/NormalizeDateFormatter.java index 096a777b507..4d1ec266c43 100644 --- a/src/main/java/org/jabref/logic/formatter/bibtexfields/NormalizeDateFormatter.java +++ b/src/main/java/org/jabref/logic/formatter/bibtexfields/NormalizeDateFormatter.java @@ -1,14 +1,10 @@ package org.jabref.logic.formatter.bibtexfields; -import java.time.format.DateTimeFormatter; -import java.time.format.DateTimeParseException; -import java.time.temporal.TemporalAccessor; -import java.util.Arrays; -import java.util.List; import java.util.Optional; import org.jabref.logic.l10n.Localization; import org.jabref.model.cleanup.Formatter; +import org.jabref.model.entry.Date; /** * This class transforms date to the format yyyy-mm-dd or yyyy-mm.. @@ -34,13 +30,8 @@ public String getKey() { */ @Override public String format(String value) { - Optional parsedDate = tryParseDate(value); - if (!parsedDate.isPresent()) { - return value; - } - - DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("uuuu-MM[-dd]"); - return dateFormatter.format(parsedDate.get()); + Optional parsedDate = Date.parse(value); + return parsedDate.map(Date::getNormalized).orElse(value); } @Override @@ -53,29 +44,6 @@ public String getExampleInput() { return "29.11.2003"; } - /* - * Try to parse the following formats - * "M/y" (covers 9/15, 9/2015, and 09/2015) - * "MMMM (dd), yyyy" (covers September 1, 2015 and September, 2015) - * "yyyy-MM-dd" (covers 2009-1-15) - * "d.M.uuuu" (covers 15.1.2015) - * "uuuu.M.d" (covers 2015.1.15) - * The code is essentially taken from http://stackoverflow.com/questions/4024544/how-to-parse-dates-in-multiple-formats-using-simpledateformat. - */ - private Optional tryParseDate(String dateString) { - List formatStrings = Arrays.asList("uuuu-M-d", "uuuu-M", "M/uu", "M/uuuu", "MMMM d, uuuu", "MMMM, uuuu", - "d.M.uuuu", "uuuu.M.d"); - for (String formatString : formatStrings) { - try { - return Optional.of(DateTimeFormatter.ofPattern(formatString).parse(dateString)); - } catch (DateTimeParseException ignored) { - // Ignored - } - } - - return Optional.empty(); - } - @Override public int hashCode() { return defaultHashCode(); diff --git a/src/main/java/org/jabref/logic/formatter/bibtexfields/NormalizeMonthFormatter.java b/src/main/java/org/jabref/logic/formatter/bibtexfields/NormalizeMonthFormatter.java index e6f15850156..eae778c0fa1 100644 --- a/src/main/java/org/jabref/logic/formatter/bibtexfields/NormalizeMonthFormatter.java +++ b/src/main/java/org/jabref/logic/formatter/bibtexfields/NormalizeMonthFormatter.java @@ -1,10 +1,11 @@ package org.jabref.logic.formatter.bibtexfields; import java.util.Objects; +import java.util.Optional; import org.jabref.logic.l10n.Localization; import org.jabref.model.cleanup.Formatter; -import org.jabref.model.entry.MonthUtil; +import org.jabref.model.entry.Month; public class NormalizeMonthFormatter implements Formatter { @@ -21,12 +22,8 @@ public String getKey() { @Override public String format(String value) { Objects.requireNonNull(value); - MonthUtil.Month month = MonthUtil.getMonth(value); - if (month.isValid()) { - return month.bibtexFormat; - } else { - return value; - } + Optional month = Month.parse(value); + return month.map(Month::getJabRefFormat).orElse(value); } @Override diff --git a/src/main/java/org/jabref/logic/importer/fetcher/MedlineFetcher.java b/src/main/java/org/jabref/logic/importer/fetcher/MedlineFetcher.java index 9351135baca..0ed8ad7acde 100644 --- a/src/main/java/org/jabref/logic/importer/fetcher/MedlineFetcher.java +++ b/src/main/java/org/jabref/logic/importer/fetcher/MedlineFetcher.java @@ -18,6 +18,8 @@ import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; +import org.jabref.logic.formatter.bibtexfields.ClearFormatter; +import org.jabref.logic.formatter.bibtexfields.NormalizeMonthFormatter; import org.jabref.logic.help.HelpFile; import org.jabref.logic.importer.FetcherException; import org.jabref.logic.importer.IdBasedParserFetcher; @@ -26,8 +28,9 @@ import org.jabref.logic.importer.SearchBasedFetcher; import org.jabref.logic.importer.fileformat.MedlineImporter; import org.jabref.logic.l10n.Localization; +import org.jabref.model.cleanup.FieldFormatterCleanup; import org.jabref.model.entry.BibEntry; -import org.jabref.model.entry.MonthUtil; +import org.jabref.model.entry.FieldName; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -144,10 +147,11 @@ public Parser getParser() { @Override public void doPostCleanup(BibEntry entry) { - entry.clearField("journal-abbreviation"); - entry.clearField("status"); - entry.clearField("copyright"); - entry.getField("month").ifPresent(month -> entry.setField("month", MonthUtil.getMonth(month).bibtexFormat)); + new FieldFormatterCleanup("journal-abbreviation", new ClearFormatter()).cleanup(entry); + new FieldFormatterCleanup("status", new ClearFormatter()).cleanup(entry); + new FieldFormatterCleanup("copyright", new ClearFormatter()).cleanup(entry); + + new FieldFormatterCleanup(FieldName.MONTH, new NormalizeMonthFormatter()).cleanup(entry); } @Override 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 df367b0a028..8999fbc697e 100644 --- a/src/main/java/org/jabref/logic/importer/fileformat/IsiImporter.java +++ b/src/main/java/org/jabref/logic/importer/fileformat/IsiImporter.java @@ -8,6 +8,7 @@ import java.util.Locale; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -17,7 +18,7 @@ import org.jabref.logic.util.FileExtensions; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.FieldName; -import org.jabref.model.entry.MonthUtil; +import org.jabref.model.entry.Month; /** * Importer for the ISI Web of Science, INSPEC and Medline format. @@ -338,9 +339,9 @@ public static String parseMonth(String value) { String[] parts = value.split("\\s|\\-"); for (String part1 : parts) { - MonthUtil.Month month = MonthUtil.getMonthByShortName(part1.toLowerCase(Locale.ROOT)); - if (month.isValid()) { - return month.bibtexFormat; + Optional month = Month.getMonthByShortName(part1.toLowerCase(Locale.ROOT)); + if (month.isPresent()) { + return month.get().getJabRefFormat(); } } @@ -348,9 +349,9 @@ public static String parseMonth(String value) { for (String part : parts) { try { int number = Integer.parseInt(part); - MonthUtil.Month month = MonthUtil.getMonthByNumber(number); - if (month.isValid()) { - return month.bibtexFormat; + Optional month = Month.getMonthByNumber(number); + if (month.isPresent()) { + return month.get().getJabRefFormat(); } } catch (NumberFormatException ignored) { // Ignored diff --git a/src/main/java/org/jabref/logic/importer/fileformat/RepecNepImporter.java b/src/main/java/org/jabref/logic/importer/fileformat/RepecNepImporter.java index 8e9b2a0cc1d..4f61ce2ef83 100644 --- a/src/main/java/org/jabref/logic/importer/fileformat/RepecNepImporter.java +++ b/src/main/java/org/jabref/logic/importer/fileformat/RepecNepImporter.java @@ -2,14 +2,9 @@ import java.io.BufferedReader; import java.io.IOException; -import java.text.ParseException; -import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; -import java.util.Calendar; import java.util.Collection; -import java.util.Date; -import java.util.GregorianCalendar; import java.util.List; import java.util.Objects; @@ -18,6 +13,7 @@ import org.jabref.logic.importer.ParserResult; import org.jabref.logic.util.FileExtensions; import org.jabref.model.entry.BibEntry; +import org.jabref.model.entry.Date; import org.jabref.model.entry.FieldName; import org.apache.commons.logging.Log; @@ -148,14 +144,12 @@ public class RepecNepImporter extends Importer { private static final Log LOGGER = LogFactory.getLog(RepecNepImporter.class); private static final Collection RECOGNIZED_FIELDS = Arrays.asList("Keywords", "JEL", "Date", "URL", "By"); - + private final ImportFormatPreferences importFormatPreferences; private int line; private String lastLine = ""; private String preLine = ""; private boolean inOverviewSection; - private final ImportFormatPreferences importFormatPreferences; - public RepecNepImporter(ImportFormatPreferences importFormatPreferences) { this.importFormatPreferences = importFormatPreferences; @@ -347,30 +341,10 @@ private void parseAdditionalFields(BibEntry be, boolean multilineUrlFieldAllowed } else if ("JEL".equals(keyword)) { be.setField("jel", readMultipleLines(in)); - // parse date field } else if (keyword.startsWith("Date")) { - Date date = null; + // parse date field String content = readMultipleLines(in); - String[] recognizedDateFormats = new String[]{"yyyy-MM-dd", "yyyy-MM", "yyyy"}; - int i = 0; - for (; (i < recognizedDateFormats.length) && (date == null); i++) { - try { - date = new SimpleDateFormat(recognizedDateFormats[i]).parse(content); - } catch (ParseException e) { - // wrong format - } - } - - Calendar cal = new GregorianCalendar(); - cal.setTime(date == null ? new Date() : date); - be.setField(FieldName.YEAR, String.valueOf(cal.get(Calendar.YEAR))); - if ((date != null) && recognizedDateFormats[i - 1].contains("MM")) { - be.setField(FieldName.MONTH, String.valueOf(cal.get(Calendar.MONTH) + 1)); - } - if ((date != null) && recognizedDateFormats[i - 1].contains("dd")) { - be.setField(FieldName.DAY, String.valueOf(cal.get(Calendar.DAY_OF_MONTH))); - } - + Date.parse(content).ifPresent(be::setDate); // parse URL field } else if (keyword.startsWith("URL")) { String content; diff --git a/src/main/java/org/jabref/logic/importer/fileformat/RisImporter.java b/src/main/java/org/jabref/logic/importer/fileformat/RisImporter.java index 65b3d309b14..ff927d3638f 100644 --- a/src/main/java/org/jabref/logic/importer/fileformat/RisImporter.java +++ b/src/main/java/org/jabref/logic/importer/fileformat/RisImporter.java @@ -17,7 +17,7 @@ import org.jabref.model.entry.AuthorList; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.FieldName; -import org.jabref.model.entry.MonthUtil; +import org.jabref.model.entry.Month; /** * Imports a Biblioscape Tag File. The format is described on @@ -70,6 +70,7 @@ public ParserResult importDatabase(BufferedReader reader) throws IOException { String startPage = ""; String endPage = ""; String comment = ""; + Optional month = Optional.empty(); Map fields = new HashMap<>(); String[] lines = entry1.split("\n"); @@ -199,10 +200,7 @@ public ParserResult importDatabase(BufferedReader reader) throws IOException { if ((parts.length > 1) && !parts[1].isEmpty()) { try { int monthNumber = Integer.parseInt(parts[1]); - MonthUtil.Month month = MonthUtil.getMonthByNumber(monthNumber); - if (month.isValid()) { - fields.put(FieldName.MONTH, month.bibtexFormat); - } + month = Month.getMonthByNumber(monthNumber); } catch (NumberFormatException ex) { // The month part is unparseable, so we ignore it. } @@ -242,13 +240,16 @@ else if ("ID".equals(tag)) { fields.put(FieldName.PAGES, startPage + endPage); } - BibEntry b = new BibEntry(type); // Remove empty fields: fields.entrySet().removeIf(key -> (key.getValue() == null) || key.getValue().trim().isEmpty()); // create one here + // type is set in the loop above + BibEntry b = new BibEntry(type); b.setField(fields); + // month has a special treatment as we use the separate method "setMonth" of BibEntry instead of directly setting the value + month.ifPresent(parsedMonth -> b.setMonth(parsedMonth)); bibitems.add(b); } diff --git a/src/main/java/org/jabref/logic/importer/util/JSONEntryParser.java b/src/main/java/org/jabref/logic/importer/util/JSONEntryParser.java index d47c48ba8ca..0e2af600f81 100644 --- a/src/main/java/org/jabref/logic/importer/util/JSONEntryParser.java +++ b/src/main/java/org/jabref/logic/importer/util/JSONEntryParser.java @@ -2,10 +2,11 @@ import java.util.ArrayList; import java.util.List; +import java.util.Optional; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.FieldName; -import org.jabref.model.entry.MonthUtil; +import org.jabref.model.entry.Month; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -211,7 +212,8 @@ public static BibEntry parseSpringerJSONtoBibtex(JSONObject springerJsonEntry) { entry.setField(FieldName.DATE, date); // For biblatex String[] dateparts = date.split("-"); entry.setField(FieldName.YEAR, dateparts[0]); - entry.setField(FieldName.MONTH, MonthUtil.getMonthByNumber(Integer.parseInt(dateparts[1])).bibtexFormat); + Optional month = Month.getMonthByNumber(Integer.parseInt(dateparts[1])); + month.ifPresent(entry::setMonth); } // Clean up abstract (often starting with Abstract) diff --git a/src/main/java/org/jabref/logic/layout/format/RisMonth.java b/src/main/java/org/jabref/logic/layout/format/RisMonth.java index 1b191946c6a..02927f9d5bb 100644 --- a/src/main/java/org/jabref/logic/layout/format/RisMonth.java +++ b/src/main/java/org/jabref/logic/layout/format/RisMonth.java @@ -1,9 +1,10 @@ package org.jabref.logic.layout.format; import java.util.Locale; +import java.util.Optional; import org.jabref.logic.layout.LayoutFormatter; -import org.jabref.model.entry.MonthUtil; +import org.jabref.model.entry.Month; public class RisMonth implements LayoutFormatter { @@ -13,12 +14,7 @@ public String format(String month) { return ""; } - MonthUtil.Month m = MonthUtil.getMonthByShortName(month); - if (m.isValid()) { - return m.twoDigitNumber; - } else { - return month.toLowerCase(Locale.ROOT); - } + Optional parsedMonth = Month.getMonthByShortName(month); + return parsedMonth.map(Month::getTwoDigitNumber).orElse(month.toLowerCase(Locale.ROOT)); } - } diff --git a/src/main/java/org/jabref/logic/msbib/BibTeXConverter.java b/src/main/java/org/jabref/logic/msbib/BibTeXConverter.java index 9b9c7ecb079..9fa936c82ac 100644 --- a/src/main/java/org/jabref/logic/msbib/BibTeXConverter.java +++ b/src/main/java/org/jabref/logic/msbib/BibTeXConverter.java @@ -3,14 +3,14 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.FieldName; -import org.jabref.model.entry.MonthUtil; -import org.jabref.model.entry.MonthUtil.Month; +import org.jabref.model.entry.Month; public class BibTeXConverter { @@ -85,13 +85,8 @@ public static BibEntry convert(MSBibEntry entry) { fieldValues.put(FieldName.JOURNAL, entry.journalName); } if (entry.month != null) { - Month month = MonthUtil.getMonth(entry.month); - //if we encouter an invalid month shortname would be null - if (month.isValid()) { - fieldValues.put(FieldName.MONTH, month.shortName); - } else { - fieldValues.put(FieldName.MONTH, ""); - } + Optional month = Month.parse(entry.month); + month.ifPresent(parsedMonth -> result.setMonth(parsedMonth)); } if (entry.number != null) { fieldValues.put(FieldName.NUMBER, entry.number); diff --git a/src/main/java/org/jabref/logic/msbib/MSBibConverter.java b/src/main/java/org/jabref/logic/msbib/MSBibConverter.java index 1094fe34585..8e410f4e351 100644 --- a/src/main/java/org/jabref/logic/msbib/MSBibConverter.java +++ b/src/main/java/org/jabref/logic/msbib/MSBibConverter.java @@ -7,6 +7,7 @@ import org.jabref.model.entry.AuthorList; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.FieldName; +import org.jabref.model.entry.Month; public class MSBibConverter { @@ -56,7 +57,7 @@ public static MSBibEntry convert(BibEntry entry) { } result.day = entry.getFieldOrAlias(FieldName.DAY).orElse(null); - result.month = entry.getFieldOrAlias(FieldName.MONTH).orElse(null); + result.month = entry.getMonth().map(Month::getNumber).map(Object::toString).orElse(null); if (!entry.getField(FieldName.YEAR).isPresent()) { result.year = entry.getFieldOrAlias(FieldName.YEAR).orElse(null); diff --git a/src/main/java/org/jabref/logic/xmp/XMPUtil.java b/src/main/java/org/jabref/logic/xmp/XMPUtil.java index f0036214e26..26a70fc5810 100644 --- a/src/main/java/org/jabref/logic/xmp/XMPUtil.java +++ b/src/main/java/org/jabref/logic/xmp/XMPUtil.java @@ -31,7 +31,7 @@ import org.jabref.model.entry.AuthorList; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.FieldName; -import org.jabref.model.entry.MonthUtil; +import org.jabref.model.entry.Month; import org.jabref.model.strings.StringUtil; import org.apache.commons.logging.Log; @@ -68,10 +68,8 @@ private XMPUtil() { /** * Convenience method for readXMP(File). * - * @param filename - * The filename from which to open the file. + * @param filename The filename from which to open the file. * @return BibtexEntryies found in the PDF or an empty list - * @throws IOException */ public static List readXMP(String filename, XMPPreferences xmpPreferences) throws IOException { return XMPUtil.readXMP(new File(filename), xmpPreferences); @@ -89,33 +87,24 @@ public static List readXMP(String filename, XMPPreferences xmpPreferen * * This is a convenience method for writeXMP(File, BibEntry). * - * @param filename - * The filename from which to open the file. - * @param entry - * The entry to write. - * @param database - * maybenull An optional database which the given bibtex entries - * belong to, which will be used to resolve strings. If the - * database is null the strings will not be resolved. - * @throws TransformerException - * If the entry was malformed or unsupported. - * @throws IOException - * If the file could not be written to or could not be found. + * @param filename The filename from which to open the file. + * @param entry The entry to write. + * @param database maybenull An optional database which the given bibtex entries belong to, which will be used to + * resolve strings. If the database is null the strings will not be resolved. + * @throws TransformerException If the entry was malformed or unsupported. + * @throws IOException If the file could not be written to or could not be found. */ - public static void writeXMP(String filename, BibEntry entry, - BibDatabase database, XMPPreferences xmpPreferences) throws IOException, TransformerException { - XMPUtil.writeXMP(new File(filename), entry, database, xmpPreferences); + public static void writeXMP(String fileName, BibEntry entry, + BibDatabase database, XMPPreferences xmpPreferences) throws IOException, TransformerException { + XMPUtil.writeXMP(new File(fileName), entry, database, xmpPreferences); } /** * Try to read the BibTexEntries from the XMP-stream of the given PDF-file. * - * @param file - * The file to read from. - * - * @throws IOException - * Throws an IOException if the file cannot be read, so the user - * than remove a lock or cancel the operation. + * @param file The file to read from. + * @throws IOException Throws an IOException if the file cannot be read, so the user than remove a lock or cancel + * the operation. */ public static List readXMP(File file, XMPPreferences xmpPreferences) throws IOException { List result = Collections.emptyList(); @@ -145,14 +134,10 @@ public static PDDocument loadWithAutomaticDecryption(InputStream inputStream) th * Try to read the given BibTexEntry from the XMP-stream of the given * inputstream containing a PDF-file. * - * @param inputStream - * The inputstream to read from. - * - * @throws IOException - * Throws an IOException if the file cannot be read, so the user - * than remove a lock or cancel the operation. - * + * @param inputStream The inputstream to read from. * @return list of BibEntries retrieved from the stream. May be empty, but never null + * @throws IOException Throws an IOException if the file cannot be read, so the user than remove a lock or cancel + * the operation. */ public static List readXMP(InputStream inputStream, XMPPreferences xmpPreferences) throws IOException { @@ -198,9 +183,7 @@ public static List readXMP(InputStream inputStream, XMPPreferences xmp // If we did not find any XMP metadata, search for non XMP metadata PDDocumentInformation documentInformation = document.getDocumentInformation(); Optional entry = XMPUtil.getBibtexEntryFromDocumentInformation(documentInformation); - if (entry.isPresent()) { - result.add(entry.get()); - } + entry.ifPresent(result::add); } } @@ -225,9 +208,7 @@ public static Collection readXMP(Path filePath, XMPPreferences xmpPref * The BibEntry is build by mapping individual fields in the document * information (like author, title, keywords) to fields in a bibtex entry. * - * @param di - * The document information from which to build a BibEntry. - * + * @param di The document information from which to build a BibEntry. * @return The bibtex entry found in the document information. */ public static Optional getBibtexEntryFromDocumentInformation( @@ -284,17 +265,15 @@ public static Optional getBibtexEntryFromDocumentInformation( * The BibEntry is build by mapping individual fields in the dublin core * (like creator, title, subject) to fields in a bibtex entry. * - * @param dcSchema - * The document information from which to build a BibEntry. - * + * @param dcSchema The document information from which to build a BibEntry. * @return The bibtex entry found in the document information. */ public static Optional getBibtexEntryFromDublinCore(XMPSchemaDublinCore dcSchema, - XMPPreferences xmpPreferences) { + XMPPreferences xmpPreferences) { BibEntry entry = new BibEntry(); - /** + /* * Contributor -> Editor */ List contributors = dcSchema.getContributors(); @@ -302,7 +281,7 @@ public static Optional getBibtexEntryFromDublinCore(XMPSchemaDublinCor entry.setField(FieldName.EDITOR, String.join(" and ", contributors)); } - /** + /* * Author -> Creator */ List creators = dcSchema.getCreators(); @@ -310,7 +289,7 @@ public static Optional getBibtexEntryFromDublinCore(XMPSchemaDublinCor entry.setField(FieldName.AUTHOR, String.join(" and ", creators)); } - /** + /* * Year + Month -> Date */ List dates = dcSchema.getSequenceList("dc:date"); @@ -325,12 +304,13 @@ public static Optional getBibtexEntryFromDublinCore(XMPSchemaDublinCor if (c != null) { entry.setField(FieldName.YEAR, String.valueOf(c.get(Calendar.YEAR))); if (date.length() > 4) { - entry.setField(FieldName.MONTH, MonthUtil.getMonthByIndex(c.get(Calendar.MONTH)).bibtexFormat); + Optional month = Month.getMonthByNumber(c.get(Calendar.MONTH) + 1); + month.ifPresent(entry::setMonth); } } } - /** + /* * Abstract -> Description */ String s = dcSchema.getDescription(); @@ -338,7 +318,7 @@ public static Optional getBibtexEntryFromDublinCore(XMPSchemaDublinCor entry.setField(FieldName.ABSTRACT, s); } - /** + /* * Identifier -> DOI */ s = dcSchema.getIdentifier(); @@ -346,7 +326,7 @@ public static Optional getBibtexEntryFromDublinCore(XMPSchemaDublinCor entry.setField(FieldName.DOI, s); } - /** + /* * Publisher -> Publisher */ List publishers = dcSchema.getPublishers(); @@ -354,7 +334,7 @@ public static Optional getBibtexEntryFromDublinCore(XMPSchemaDublinCor entry.setField(FieldName.PUBLISHER, String.join(" and ", publishers)); } - /** + /* * Relation -> bibtexkey * * We abuse the relationship attribute to store all other values in the @@ -373,7 +353,7 @@ public static Optional getBibtexEntryFromDublinCore(XMPSchemaDublinCor } } - /** + /* * Rights -> Rights */ s = dcSchema.getRights(); @@ -381,7 +361,7 @@ public static Optional getBibtexEntryFromDublinCore(XMPSchemaDublinCor entry.setField("rights", s); } - /** + /* * Source -> Source */ s = dcSchema.getSource(); @@ -389,7 +369,7 @@ public static Optional getBibtexEntryFromDublinCore(XMPSchemaDublinCor entry.setField("source", s); } - /** + /* * Subject -> Keywords */ List subjects = dcSchema.getSubjects(); @@ -397,7 +377,7 @@ public static Optional getBibtexEntryFromDublinCore(XMPSchemaDublinCor entry.addKeywords(subjects, xmpPreferences.getKeywordSeparator()); } - /** + /* * Title -> Title */ s = dcSchema.getTitle(); @@ -405,7 +385,7 @@ public static Optional getBibtexEntryFromDublinCore(XMPSchemaDublinCor entry.setField(FieldName.TITLE, s); } - /** + /* * Type -> Type */ List l = dcSchema.getTypes(); @@ -431,21 +411,15 @@ public static Optional getBibtexEntryFromDublinCore(XMPSchemaDublinCor * * This is a convenience method for writeXMP(File, Collection). * - * @param file - * The file to write to. - * @param entry - * The entry to write. - * @param database - * maybenull An optional database which the given bibtex entries - * belong to, which will be used to resolve strings. If the - * database is null the strings will not be resolved. - * @throws TransformerException - * If the entry was malformed or unsupported. - * @throws IOException - * If the file could not be written to or could not be found. + * @param file The file to write to. + * @param entry The entry to write. + * @param database maybenull An optional database which the given bibtex entries belong to, which will be used to + * resolve strings. If the database is null the strings will not be resolved. + * @throws TransformerException If the entry was malformed or unsupported. + * @throws IOException If the file could not be written to or could not be found. */ public static void writeXMP(File file, BibEntry entry, - BibDatabase database, XMPPreferences xmpPreferences) throws IOException, TransformerException { + BibDatabase database, XMPPreferences xmpPreferences) throws IOException, TransformerException { List l = new LinkedList<>(); l.add(entry); XMPUtil.writeXMP(file, l, database, true, xmpPreferences); @@ -456,23 +430,16 @@ public static void writeXMP(File file, BibEntry entry, * * The text that is written to the stream contains a complete XMP-document. * - * @param bibtexEntries - * The BibtexEntries to write XMP-metadata for. - * @param database - * maybenull An optional database which the given bibtex entries - * belong to, which will be used to resolve strings. If the - * database is null the strings will not be resolved. - * @throws TransformerException - * Thrown if the bibtexEntries could not transformed to XMP. - * @throws IOException - * Thrown if an IOException occured while writing to the stream. - * - * @see #toXMP(java.util.Collection, BibDatabase) if you don't need strings to be - * resolved. + * @param bibtexEntries The BibtexEntries to write XMP-metadata for. + * @param database maybenull An optional database which the given bibtex entries belong to, which will be used + * to resolve strings. If the database is null the strings will not be resolved. + * @throws TransformerException Thrown if the bibtexEntries could not transformed to XMP. + * @throws IOException Thrown if an IOException occured while writing to the stream. + * @see #toXMP(java.util.Collection, BibDatabase) if you don't need strings to be resolved. */ private static void toXMP(Collection bibtexEntries, - BibDatabase database, OutputStream outputStream, XMPPreferences xmpPreferences) - throws IOException, TransformerException { + BibDatabase database, OutputStream outputStream, XMPPreferences xmpPreferences) + throws IOException, TransformerException { Collection resolvedEntries; if (database == null) { @@ -499,18 +466,14 @@ private static void toXMP(Collection bibtexEntries, * * The resulting metadata string is wrapped as a complete XMP-document. * - * @param bibtexEntries - * The BibtexEntries to return XMP-metadata for. - * @param database - * maybenull An optional database which the given bibtex entries - * belong to, which will be used to resolve strings. If the - * database is null the strings will not be resolved. + * @param bibtexEntries The BibtexEntries to return XMP-metadata for. + * @param database An optional database which the given bibtex entries belong to, which will be used + * to resolve strings. If the database is null the strings will not be resolved. * @return The XMP representation of the given bibtexEntries. - * @throws TransformerException - * Thrown if the bibtexEntries could not transformed to XMP. + * @throws TransformerException Thrown if the bibtexEntries could not transformed to XMP. */ public static String toXMP(Collection bibtexEntries, - BibDatabase database, XMPPreferences xmpPreferences) throws TransformerException { + BibDatabase database, XMPPreferences xmpPreferences) throws TransformerException { try { ByteArrayOutputStream bs = new ByteArrayOutputStream(); XMPUtil.toXMP(bibtexEntries, database, bs, xmpPreferences); @@ -524,9 +487,7 @@ public static String toXMP(Collection bibtexEntries, * Will read the XMPMetadata from the given pdf file, closing the file * afterwards. * - * @param inputStream - * The inputStream representing a PDF-file to read the - * XMPMetadata from. + * @param inputStream The inputStream representing a PDF-file to read the XMPMetadata from. * @return The XMPMetadata object found in the file */ private static Optional readRawXMP(InputStream inputStream) throws IOException { @@ -559,8 +520,7 @@ private static Optional getXMPMetadata(PDDocument document) throws * Will read the XMPMetadata from the given pdf file, closing the file * afterwards. * - * @param file - * The file to read the XMPMetadata from. + * @param file The file to read the XMPMetadata from. * @return The XMPMetadata object found in the file */ public static Optional readRawXMP(File file) throws IOException { @@ -569,8 +529,8 @@ public static Optional readRawXMP(File file) throws IOException { } } - private static void writeToDCSchema(XMPSchemaDublinCore dcSchema, - BibEntry entry, BibDatabase database, XMPPreferences xmpPreferences) { + private static void writeToDCSchema(XMPSchemaDublinCore dcSchema, BibEntry entry, BibDatabase database, + XMPPreferences xmpPreferences) { BibEntry resolvedEntry; if (database == null) { @@ -595,7 +555,7 @@ private static void writeToDCSchema(XMPSchemaDublinCore dcSchema, if (FieldName.EDITOR.equals(field.getKey())) { String authors = field.getValue(); - /** + /* * Editor -> Contributor * * Field: dc:contributor @@ -618,15 +578,13 @@ private static void writeToDCSchema(XMPSchemaDublinCore dcSchema, continue; } - /** + /* * ? -> Coverage * * Unmapped * * dc:coverage Text External The extent or scope of the resource. - */ - - /** + * * Author -> Creator * * Field: dc:creator @@ -657,7 +615,7 @@ private static void writeToDCSchema(XMPSchemaDublinCore dcSchema, if (FieldName.YEAR.equals(field.getKey())) { - /** + /* * Year + Month -> Date * * Field: dc:date @@ -675,7 +633,8 @@ private static void writeToDCSchema(XMPSchemaDublinCore dcSchema, .ifPresent(publicationDate -> dcSchema.addSequenceValue("dc:date", publicationDate)); continue; } - /** + + /* * Abstract -> Description * * Field: dc:description @@ -694,7 +653,7 @@ private static void writeToDCSchema(XMPSchemaDublinCore dcSchema, continue; } - /** + /* * DOI -> identifier * * Field: dc:identifier @@ -712,7 +671,7 @@ private static void writeToDCSchema(XMPSchemaDublinCore dcSchema, continue; } - /** + /* * ? -> Language * * Unmapped @@ -721,7 +680,7 @@ private static void writeToDCSchema(XMPSchemaDublinCore dcSchema, * languages used in the resource. */ - /** + /* * Publisher -> Publisher * * Field: dc:publisher @@ -739,7 +698,7 @@ private static void writeToDCSchema(XMPSchemaDublinCore dcSchema, continue; } - /** + /* * ? -> Rights * * Unmapped @@ -748,7 +707,7 @@ private static void writeToDCSchema(XMPSchemaDublinCore dcSchema, * by language. */ - /** + /* * ? -> Source * * Unmapped @@ -757,7 +716,7 @@ private static void writeToDCSchema(XMPSchemaDublinCore dcSchema, * this resource was derived. */ - /** + /* * Keywords -> Subject * * Field: dc:subject @@ -780,7 +739,7 @@ private static void writeToDCSchema(XMPSchemaDublinCore dcSchema, continue; } - /** + /* * Title -> Title * * Field: dc:title @@ -801,7 +760,7 @@ private static void writeToDCSchema(XMPSchemaDublinCore dcSchema, } - /** + /* * All others (including the bibtex key) get packaged in the * relation attribute */ @@ -809,7 +768,7 @@ private static void writeToDCSchema(XMPSchemaDublinCore dcSchema, dcSchema.addRelation("bibtex/" + field.getKey() + '/' + o); } - /** + /* * ? -> Format * * Unmapped @@ -820,7 +779,7 @@ private static void writeToDCSchema(XMPSchemaDublinCore dcSchema, */ dcSchema.setFormat("application/pdf"); - /** + /* * entrytype -> Type * * Field: dc:type @@ -846,19 +805,13 @@ private static void writeToDCSchema(XMPSchemaDublinCore dcSchema, * * Existing DublinCore schemas in the document are not modified. * - * @param document - * The pdf document to write to. - * @param entry - * The BibTeX entry that is written as a schema. - * @param database - * maybenull An optional database which the given BibTeX entries - * belong to, which will be used to resolve strings. If the - * database is null the strings will not be resolved. - * @throws IOException - * @throws TransformerException + * @param document The pdf document to write to. + * @param entry The BibTeX entry that is written as a schema. + * @param database maybenull An optional database which the given BibTeX entries belong to, which will be used to + * resolve strings. If the database is null the strings will not be resolved. */ public static void writeDublinCore(PDDocument document, BibEntry entry, - BibDatabase database, XMPPreferences xmpPreferences) throws IOException, TransformerException { + BibDatabase database, XMPPreferences xmpPreferences) throws IOException, TransformerException { List entries = new ArrayList<>(); entries.add(entry); @@ -871,20 +824,14 @@ public static void writeDublinCore(PDDocument document, BibEntry entry, * * Existing DublinCore schemas in the document are removed * - * @param document - * The pdf document to write to. - * @param entries - * The BibTeX entries that are written as schemas - * @param database - * maybenull An optional database which the given BibTeX entries - * belong to, which will be used to resolve strings. If the - * database is null the strings will not be resolved. - * @throws IOException - * @throws TransformerException + * @param document The pdf document to write to. + * @param entries The BibTeX entries that are written as schemas + * @param database maybenull An optional database which the given BibTeX entries belong to, which will be used to + * resolve strings. If the database is null the strings will not be resolved. */ private static void writeDublinCore(PDDocument document, - Collection entries, BibDatabase database, XMPPreferences xmpPreferences) - throws IOException, TransformerException { + Collection entries, BibDatabase database, XMPPreferences xmpPreferences) + throws IOException, TransformerException { Collection resolvedEntries; if (database == null) { @@ -931,17 +878,13 @@ private static void writeDublinCore(PDDocument document, * Existing fields values are overriden if the bibtex entry has the * corresponding value set. * - * @param document - * The pdf document to write to. - * @param entry - * The Bibtex entry that is written into the PDF properties. * - * @param database - * maybenull An optional database which the given bibtex entries - * belong to, which will be used to resolve strings. If the - * database is null the strings will not be resolved. + * @param document The pdf document to write to. + * @param entry The Bibtex entry that is written into the PDF properties. * + * @param database maybenull An optional database which the given bibtex entries belong to, which will be used to + * resolve strings. If the database is null the strings will not be resolved. */ private static void writeDocumentInformation(PDDocument document, - BibEntry entry, BibDatabase database, XMPPreferences xmpPreferences) { + BibEntry entry, BibDatabase database, XMPPreferences xmpPreferences) { PDDocumentInformation di = document.getDocumentInformation(); @@ -1004,24 +947,17 @@ private static void writeDocumentInformation(PDDocument document, * The method will overwrite existing BibTeX-XMP-data, but keep other * existing metadata. * - * @param file - * The file to write the entries to. - * @param bibtexEntries - * The entries to write to the file. * - * @param database - * maybenull An optional database which the given bibtex entries - * belong to, which will be used to resolve strings. If the - * database is null the strings will not be resolved. - * @param writePDFInfo - * Write information also in PDF document properties - * @throws TransformerException - * If the entry was malformed or unsupported. - * @throws IOException - * If the file could not be written to or could not be found. + * @param file The file to write the entries to. + * @param bibtexEntries The entries to write to the file. * + * @param database maybenull An optional database which the given bibtex entries belong to, which will be used + * to resolve strings. If the database is null the strings will not be resolved. + * @param writePDFInfo Write information also in PDF document properties + * @throws TransformerException If the entry was malformed or unsupported. + * @throws IOException If the file could not be written to or could not be found. */ public static void writeXMP(File file, - Collection bibtexEntries, BibDatabase database, - boolean writePDFInfo, XMPPreferences xmpPreferences) throws IOException, TransformerException { + Collection bibtexEntries, BibDatabase database, + boolean writePDFInfo, XMPPreferences xmpPreferences) throws IOException, TransformerException { Collection resolvedEntries; if (database == null) { @@ -1103,8 +1039,7 @@ public static boolean hasMetadata(Path path, XMPPreferences xmpPreferences) { * Caution: This method is as expensive as it is reading the actual metadata * itself from the PDF. * - * @param inputStream - * The inputStream to read the PDF from. + * @param inputStream The inputStream to read the PDF from. * @return whether a BibEntry was found in the given PDF. */ public static boolean hasMetadata(InputStream inputStream, XMPPreferences xmpPreferences) { diff --git a/src/main/java/org/jabref/model/database/BibDatabase.java b/src/main/java/org/jabref/model/database/BibDatabase.java index 6bd04c79a28..22a76ec948f 100644 --- a/src/main/java/org/jabref/model/database/BibDatabase.java +++ b/src/main/java/org/jabref/model/database/BibDatabase.java @@ -27,7 +27,7 @@ import org.jabref.model.entry.BibtexString; import org.jabref.model.entry.FieldName; import org.jabref.model.entry.InternalBibtexFields; -import org.jabref.model.entry.MonthUtil; +import org.jabref.model.entry.Month; import org.jabref.model.entry.event.EntryChangedEvent; import org.jabref.model.entry.event.EntryEventSource; import org.jabref.model.entry.event.FieldChangedEvent; @@ -488,12 +488,8 @@ private String resolveString(String label, Set usedIds, Set allU // If we get to this point, the string has obviously not been defined locally. // Check if one of the standard BibTeX month strings has been used: - MonthUtil.Month month = MonthUtil.getMonthByShortName(label); - if (month.isValid()) { - return month.fullName; - } else { - return null; - } + Optional month = Month.getMonthByShortName(label); + return month.map(Month::getFullName).orElse(null); } private String resolveContent(String result, Set usedIds, Set allUsedIds) { diff --git a/src/main/java/org/jabref/model/entry/BibEntry.java b/src/main/java/org/jabref/model/entry/BibEntry.java index feec9a75daf..f86bc470fa1 100644 --- a/src/main/java/org/jabref/model/entry/BibEntry.java +++ b/src/main/java/org/jabref/model/entry/BibEntry.java @@ -1,14 +1,7 @@ package org.jabref.model.entry; -import java.text.DateFormat; -import java.text.FieldPosition; -import java.text.ParseException; -import java.text.ParsePosition; -import java.text.SimpleDateFormat; -import java.util.Calendar; import java.util.Collection; import java.util.Collections; -import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -101,6 +94,10 @@ private BibEntry(String id, String type) { this.sharedBibEntryData = new SharedBibEntryData(); } + public Optional setMonth(Month parsedMonth) { + return setField(FieldName.MONTH, parsedMonth.getJabRefFormat()); + } + public Optional replaceKeywords(KeywordList keywordsToReplace, Optional newValue, Character keywordDelimiter) { KeywordList keywordList = getKeywords(keywordDelimiter); @@ -209,6 +206,13 @@ public String getType() { return type; } + /** + * Sets this entry's type. + */ + public void setType(String type) { + setType(type, EntryEventSource.LOCAL); + } + /** * Sets this entry's type. */ @@ -236,13 +240,6 @@ public void setType(String type, EntryEventSource eventSource) { eventBus.post(new FieldChangedEvent(this, TYPE_HEADER, newType, oldType, eventSource)); } - /** - * Sets this entry's type. - */ - public void setType(String type) { - setType(type, EntryEventSource.LOCAL); - } - /** * Returns an set containing the names of all fields that are * set for this particular entry. @@ -299,73 +296,34 @@ private Optional genericGetFieldOrAlias(String name, GetFieldInterface g // Finally, handle dates if (FieldName.DATE.equals(name)) { - Optional year = getFieldInterface.getValueForField(FieldName.YEAR); - if (year.isPresent()) { - MonthUtil.Month month = MonthUtil - .getMonth(getFieldInterface.getValueForField(FieldName.MONTH).orElse("")); - if (month.isValid()) { - return Optional.of(year.get() + '-' + month.twoDigitNumber); - } else { - return year; - } - } + Optional date = Date.parse( + getFieldInterface.getValueForField(FieldName.YEAR), + getFieldInterface.getValueForField(FieldName.MONTH), + getFieldInterface.getValueForField(FieldName.DAY)); + + return date.map(Date::getNormalized); } + if (FieldName.YEAR.equals(name) || FieldName.MONTH.equals(name) || FieldName.DAY.equals(name)) { Optional date = getFieldInterface.getValueForField(FieldName.DATE); if (!date.isPresent()) { return Optional.empty(); } - // Create date format matching dates with year and month - DateFormat df = new DateFormat() { - - static final String FORMAT1 = "yyyy-MM-dd"; - static final String FORMAT2 = "yyyy-MM"; - final SimpleDateFormat sdf1 = new SimpleDateFormat(FORMAT1); - final SimpleDateFormat sdf2 = new SimpleDateFormat(FORMAT2); - - @Override - public StringBuffer format(Date dDate, StringBuffer toAppendTo, FieldPosition fieldPosition) { - throw new UnsupportedOperationException(); - } - - @Override - public Date parse(String source, ParsePosition pos) { - if ((source.length() - pos.getIndex()) == FORMAT1.length()) { - return sdf1.parse(source, pos); - } - return sdf2.parse(source, pos); - } - }; - - try { - Date parsedDate = df.parse(date.get()); - Calendar calendar = Calendar.getInstance(); - calendar.setTime(parsedDate); + Optional parsedDate = Date.parse(date.get()); + if (parsedDate.isPresent()) { if (FieldName.YEAR.equals(name)) { - return Optional.of(Integer.toString(calendar.get(Calendar.YEAR))); + return parsedDate.get().getYear().map(Object::toString); } if (FieldName.MONTH.equals(name)) { - return Optional.of(Integer.toString(calendar.get(Calendar.MONTH) + 1)); // Shift by 1 since in this calendar Jan = 0 + return parsedDate.get().getMonth().map(Month::getJabRefFormat); } if (FieldName.DAY.equals(name)) { - return Optional.of(Integer.toString(calendar.get(Calendar.DAY_OF_MONTH))); - } - } catch (ParseException e) { - // So not a date with year and month, try just to parse years - df = new SimpleDateFormat("yyyy"); - - try { - Date parsedDate = df.parse(date.get()); - Calendar calendar = Calendar.getInstance(); - calendar.setTime(parsedDate); - if (FieldName.YEAR.equals(name)) { - return Optional.of(Integer.toString(calendar.get(Calendar.YEAR))); - } - } catch (ParseException e2) { - LOGGER.warn("Could not parse entry " + name, e2); - return Optional.empty(); // Date field not in valid format + return parsedDate.get().getDay().map(Object::toString); } + } else { + LOGGER.warn("Could not parse date " + date.get()); + return Optional.empty(); // Date field not in valid format } } return Optional.empty(); @@ -629,20 +587,7 @@ public Optional getTitle() { * @return will return the publication date of the entry or null if no year was found. */ public Optional getPublicationDate() { - if (!hasField(FieldName.YEAR)) { - return Optional.empty(); - } - - Optional year = getField(FieldName.YEAR); - - Optional monthString = getField(FieldName.MONTH); - if (monthString.isPresent()) { - MonthUtil.Month month = MonthUtil.getMonth(monthString.get()); - if (month.isValid()) { - return Optional.of(year.orElse("") + "-" + month.twoDigitNumber); - } - } - return year; + return getFieldOrAlias(FieldName.DATE); } public String getParsedSerialization() { @@ -847,6 +792,16 @@ public Optional setFiles(List files) { return this.setField(FieldName.FILE, newValue); } + public void setDate(Date date) { + date.getYear().ifPresent(year -> setField(FieldName.YEAR, year.toString())); + date.getMonth().ifPresent(this::setMonth); + date.getDay().ifPresent(day -> setField(FieldName.DAY, day.toString())); + } + + public Optional getMonth() { + return getFieldOrAlias(FieldName.MONTH).flatMap(Month::parse); + } + private interface GetFieldInterface { Optional getValueForField(String fieldName); diff --git a/src/main/java/org/jabref/model/entry/Date.java b/src/main/java/org/jabref/model/entry/Date.java new file mode 100644 index 00000000000..77109b8b83f --- /dev/null +++ b/src/main/java/org/jabref/model/entry/Date.java @@ -0,0 +1,126 @@ +package org.jabref.model.entry; + +import java.time.LocalDate; +import java.time.Year; +import java.time.YearMonth; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import java.time.temporal.ChronoField; +import java.time.temporal.TemporalAccessor; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.Optional; + +public class Date { + + private final TemporalAccessor date; + + public Date(TemporalAccessor date) { + this.date = date; + } + + /** + * Try to parse the following formats + * - "M/y" (covers 9/15, 9/2015, and 09/2015) + * - "MMMM (dd), yyyy" (covers September 1, 2015 and September, 2015) + * - "yyyy-MM-dd" (covers 2009-1-15) + * - "dd-MM-yyyy" (covers 15-1-2009) + * - "d.M.uuuu" (covers 15.1.2015) + * - "uuuu.M.d" (covers 2015.1.15) + * The code is essentially taken from http://stackoverflow.com/questions/4024544/how-to-parse-dates-in-multiple-formats-using-simpledateformat. + */ + public static Optional parse(String dateString) { + List formatStrings = Arrays.asList("uuuu-M-d", "uuuu-M", "d-M-uuuu", "M/uu", "M/uuuu", "MMMM d, uuuu", "MMMM, uuuu", + "d.M.uuuu", "uuuu.M.d", "uuuu"); + for (String formatString : formatStrings) { + try { + TemporalAccessor parsedDate = DateTimeFormatter.ofPattern(formatString).parse(dateString); + return Optional.of(new Date(parsedDate)); + } catch (DateTimeParseException ignored) { + // Ignored + } + } + + return Optional.empty(); + } + + public static Optional parse(Optional yearValue, Optional monthValue, Optional dayValue) { + Optional year = yearValue.flatMap(Date::convertToInt).map(Year::of); + Optional month = monthValue.flatMap(Month::parse); + Optional day = dayValue.flatMap(Date::convertToInt); + + + if (year.isPresent()) { + TemporalAccessor date; + if (month.isPresent()) { + if (day.isPresent()) { + date = LocalDate.of(year.get().getValue(), month.get().getNumber(), day.get()); + } else { + date = YearMonth.of(year.get().getValue(), month.get().getNumber()); + } + } else { + date = year.get(); + } + + return Optional.of(new Date(date)); + } + + return Optional.empty(); + } + + private static Optional convertToInt(String value) { + try { + return Optional.of(Integer.valueOf(value)); + } catch (NumberFormatException ex) { + return Optional.empty(); + } + } + + public String getNormalized() { + DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("uuuu[-MM][-dd]"); + return dateFormatter.format(date); + } + + public Optional getYear() { + return get(ChronoField.YEAR); + } + + public Optional get(ChronoField field) { + if (date.isSupported(field)) { + return Optional.of(date.get(field)); + } else { + return Optional.empty(); + } + } + + public Optional getMonth() { + return get(ChronoField.MONTH_OF_YEAR).flatMap(Month::getMonthByNumber); + } + + public Optional getDay() { + return get(ChronoField.DAY_OF_MONTH); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Date date1 = (Date) o; + return Objects.equals(getYear(), date1.getYear()) && + Objects.equals(getMonth(), date1.getMonth()) && + Objects.equals(getDay(), date1.getDay()); + } + + @Override + public String toString() { + return "Date{" + + "date=" + date + + '}'; + } + + @Override + public int hashCode() { + return Objects.hash(date); + } +} diff --git a/src/main/java/org/jabref/model/entry/Month.java b/src/main/java/org/jabref/model/entry/Month.java new file mode 100644 index 00000000000..5c50e1fd877 --- /dev/null +++ b/src/main/java/org/jabref/model/entry/Month.java @@ -0,0 +1,145 @@ +package org.jabref.model.entry; + +import java.util.Optional; + +import org.jabref.model.strings.StringUtil; + +/** + * Represents a Month of the Year. + */ +public enum Month { + + JANUARY("January", "jan", 1), + FEBRUARY("February", "feb", 2), + MARCH("March", "mar", 3), + APRIL("April", "apr", 4), + MAY("May", "may", 5), + JUNE("June", "jun", 6), + JULY("July", "jul", 7), + AUGUST("August", "aug", 8), + SEPTEMBER("September", "sep", 9), + OCTOBER("October", "oct", 10), + NOVEMBER("November", "nov", 11), + DECEMBER("December", "dec", 12); + + private final String fullName; + private final String shortName; + private final String twoDigitNumber; + private final int number; + + Month(String fullName, String shortName, int number) { + this.fullName = fullName; + this.shortName = shortName; + this.twoDigitNumber = String.format("%02d", number); + this.number = number; + } + + + /** + * Find month by one-based number. + * If the number is not in the valid range, then an empty Optional is returned. + * + * @param number 1-12 is valid + */ + public static Optional getMonthByNumber(int number) { + for (Month month : Month.values()) { + if (month.number == number) { + return Optional.of(month); + } + } + return Optional.empty(); + } + + /** + * Find month by shortName (3 letters) case insensitive. + * If no matching month is found, then an empty Optional is returned. + * + * @param shortName "jan", "feb", ... + */ + public static Optional getMonthByShortName(String shortName) { + for (Month month : Month.values()) { + if (month.shortName.equalsIgnoreCase(shortName)) { + return Optional.of(month); + } + } + return Optional.empty(); + } + + /** + * This method accepts three types of months: + * - Single and Double Digit months from 1 to 12 (01 to 12) + * - 3 Digit BibTeX strings (jan, feb, mar...) possibly with # prepended + * - Full English Month identifiers. + * + * @param value the given value + * @return the corresponding Month instance + */ + public static Optional parse(String value) { + if (StringUtil.isBlank(value)) { + return Optional.empty(); + } + + // Much more liberal matching covering most known abbreviations etc. + String testString = value.replace("#", "").trim(); + if (testString.length() > 3) { + testString = testString.substring(0, 3); + } + Optional month = Month.getMonthByShortName(testString); + if (month.isPresent()) { + return month; + } + + try { + int number = Integer.parseInt(value); + return Month.getMonthByNumber(number); + } catch (NumberFormatException e) { + return Optional.empty(); + } + } + + /** + * Returns the name of a Month in a short (3-letter) format. (jan, feb, mar, ...) + * + * @return 3-letter identifier for a Month + */ + public String getShortName() { + return shortName; + } + + /** + * Returns the month in JabRef format. The format is the short 3-digit name surrounded by a '#'. + * Example: #jan#, #feb#, etc. + * + * See https://github.com/JabRef/jabref/issues/263#issuecomment-151246595 for a discussion on that thing. + * This seems to be an invalid format in terms of plain BiBTeX, but a valid format in the case of JabRef + * + * @return Month in JabRef format + */ + public String getJabRefFormat() { + return String.format("#%s#", shortName); + } + + /** + * Returns the number of the Month in a 1-indexed fashion: 1 -> January, 2 -> February etc. + * @return number of the month in the Year + */ + public int getNumber() { + return number; + } + + /** + * Returns the name of the long in unabbreviated english. + * @return Month + */ + public String getFullName() { + return fullName; + } + + /** + * Returns the number of the Month in a 1-indexed fashion using exactly two digits: 01 -> January, 02 -> February... + * @return number of the month in the Year with two digits + */ + public String getTwoDigitNumber() { + return twoDigitNumber; + } +} diff --git a/src/main/java/org/jabref/model/entry/MonthUtil.java b/src/main/java/org/jabref/model/entry/MonthUtil.java deleted file mode 100644 index 802542be146..00000000000 --- a/src/main/java/org/jabref/model/entry/MonthUtil.java +++ /dev/null @@ -1,141 +0,0 @@ -package org.jabref.model.entry; - -import java.util.Arrays; -import java.util.List; - -/** - * Utility class for everything related to months. - */ -public class MonthUtil { - - - private static final Month NULL_OBJECT = new UnknownMonth(); - - private static final List MONTHS = Arrays.asList( - new Month("January", "jan", "01", "#jan#", 1, 0), - new Month("February", "feb", "02", "#feb#", 2, 1), - new Month("March", "mar", "03", "#mar#", 3, 2), - new Month("April", "apr", "04", "#apr#", 4, 3), - new Month("May", "may", "05", "#may#", 5, 4), - new Month("June", "jun", "06", "#jun#", 6, 5), - new Month("July", "jul", "07", "#jul#", 7, 6), - new Month("August", "aug", "08", "#aug#", 8, 7), - new Month("September", "sep", "09", "#sep#", 9, 8), - new Month("October", "oct", "10", "#oct#", 10, 9), - new Month("November", "nov", "11", "#nov#", 11, 10), - new Month("December", "dec", "12", "#dec#", 12, 11) - ); - - - public static class Month { - - public final String fullName; - public final String shortName; - public final String twoDigitNumber; - public final String bibtexFormat; - public final int number; - public final int index; - - - public Month(String fullName, String shortName, String twoDigitNumber, String bibtexFormat, int number, int index) { - this.fullName = fullName; - this.shortName = shortName; - this.twoDigitNumber = twoDigitNumber; - this.bibtexFormat = bibtexFormat; - this.number = number; - this.index = index; - } - - public boolean isValid() { - return true; - } - } - - private static class UnknownMonth extends Month { - - public UnknownMonth() { - super(null, null, null, null, 0, -1); - } - - @Override - public boolean isValid() { - return false; - } - } - - private MonthUtil() { - } - - /** - * Find month by number - * - * @param number 1-12 is valid - * @return if valid number -> month.isValid() == true, else otherwise - */ - public static Month getMonthByNumber(int number) { - return MonthUtil.getMonthByIndex(number - 1); - } - - /** - * Find month by index - * - * @param index 0-11 is valid - * @return if valid index -> month.isValid() == true, else otherwise - */ - public static Month getMonthByIndex(int index) { - for (Month month : MonthUtil.MONTHS) { - if (month.index == index) { - return month; - } - } - return MonthUtil.NULL_OBJECT; - } - - /** - * Find month by shortName (3 letters) case insensitive - * - * @param shortName "jan", "feb", ... - * @return if valid shortName -> month.isValid() == true, else otherwise - */ - public static Month getMonthByShortName(String shortName) { - for (Month month : MonthUtil.MONTHS) { - if (month.shortName.equalsIgnoreCase(shortName)) { - return month; - } - } - return MonthUtil.NULL_OBJECT; - } - - /** - * This method accepts three types of months given: - * - Single and Double Digit months from 1 to 12 (01 to 12) - * - 3 Digit BibTex strings (jan, feb, mar...) - * - Full English Month identifiers. - * - * @param value the given value - * @return the corresponding Month instance - */ - public static Month getMonth(String value) { - if (value == null) { - return MonthUtil.NULL_OBJECT; - } - - // Much more liberal matching covering most known abbreviations etc. - String testString = value.replace("#", "").trim(); - if (testString.length() > 3) { - testString = testString.substring(0, 3); - } - Month month = MonthUtil.getMonthByShortName(testString); - if (month.isValid()) { - return month; - } - - try { - int number = Integer.parseInt(value); - return MonthUtil.getMonthByNumber(number); - } catch (NumberFormatException e) { - return MonthUtil.NULL_OBJECT; - } - } - -} diff --git a/src/test/java/org/jabref/logic/bibtex/LatexFieldFormatterTests.java b/src/test/java/org/jabref/logic/bibtex/LatexFieldFormatterTests.java index cd63c42116f..be5be454be9 100644 --- a/src/test/java/org/jabref/logic/bibtex/LatexFieldFormatterTests.java +++ b/src/test/java/org/jabref/logic/bibtex/LatexFieldFormatterTests.java @@ -1,5 +1,7 @@ package org.jabref.logic.bibtex; +import java.util.Collections; + import org.jabref.logic.util.OS; import org.jabref.preferences.JabRefPreferences; @@ -109,4 +111,20 @@ public void tolerateEscapeCharacters() throws Exception { assertEquals("{" + text + "}", formatter.format(text, "anyfield")); } + + @Test + public void hashEnclosedWordsGetRealStringsInMonthField() throws Exception { + String text = "#jan# - #feb#"; + assertEquals("jan #{ - } # feb", formatter.format(text, "month")); + } + + @Test + public void hashEnclosedWordsGetRealStringsInMonthFieldBecauseMonthIsStandardField() throws Exception { + LatexFieldFormatterPreferences latexFieldFormatterPreferences = new LatexFieldFormatterPreferences( + false, Collections.emptyList(), new FieldContentParserPreferences()); + LatexFieldFormatter formatter = new LatexFieldFormatter(latexFieldFormatterPreferences); + String text = "#jan# - #feb#"; + assertEquals("jan #{ - } # feb", formatter.format(text, "month")); + } + } diff --git a/src/test/java/org/jabref/logic/importer/fileformat/MsBibImporterTestfiles.java b/src/test/java/org/jabref/logic/importer/fileformat/MsBibImporterTestFiles.java similarity index 92% rename from src/test/java/org/jabref/logic/importer/fileformat/MsBibImporterTestfiles.java rename to src/test/java/org/jabref/logic/importer/fileformat/MsBibImporterTestFiles.java index 2f7e26da754..76eaa4b1003 100644 --- a/src/test/java/org/jabref/logic/importer/fileformat/MsBibImporterTestfiles.java +++ b/src/test/java/org/jabref/logic/importer/fileformat/MsBibImporterTestFiles.java @@ -23,7 +23,7 @@ import org.junit.runners.Parameterized.Parameters; @RunWith(Parameterized.class) -public class MsBibImporterTestfiles { +public class MsBibImporterTestFiles { @Parameter public String fileName; @@ -32,12 +32,12 @@ public class MsBibImporterTestfiles { @Before public void setUp() throws Exception { - resourceDir = Paths.get(MsBibImporterTestfiles.class.getResource("").toURI()); + resourceDir = Paths.get(MsBibImporterTestFiles.class.getResource("").toURI()); } @Parameters(name = "{0}") public static Collection fileNames() throws IOException, URISyntaxException { - try (Stream stream = Files.list(Paths.get(MsBibImporterTestfiles.class.getResource("").toURI()))) { + try (Stream stream = Files.list(Paths.get(MsBibImporterTestFiles.class.getResource("").toURI()))) { return stream.map(n -> n.getFileName().toString()).filter(n -> n.endsWith(".xml")) .filter(n -> n.startsWith("MsBib")).collect(Collectors.toList()); } diff --git a/src/test/java/org/jabref/model/entry/BibEntryTests.java b/src/test/java/org/jabref/model/entry/BibEntryTests.java index 48014efc5d7..b737b34cff2 100644 --- a/src/test/java/org/jabref/model/entry/BibEntryTests.java +++ b/src/test/java/org/jabref/model/entry/BibEntryTests.java @@ -169,13 +169,13 @@ public void getFieldOrAliasMonthWithDateYYYYReturnsNull() { @Test public void getFieldOrAliasMonthWithDateYYYYMM() { emptyEntry.setField("date", "2003-03"); - assertEquals(Optional.of("3"), emptyEntry.getFieldOrAlias("month")); + assertEquals(Optional.of("#mar#"), emptyEntry.getFieldOrAlias("month")); } @Test public void getFieldOrAliasMonthWithDateYYYYMMDD() { emptyEntry.setField("date", "2003-03-30"); - assertEquals(Optional.of("3"), emptyEntry.getFieldOrAlias("month")); + assertEquals(Optional.of("#mar#"), emptyEntry.getFieldOrAlias("month")); } @Test @@ -208,12 +208,6 @@ public void getFieldOrAliasLatexFreeComplexConversionInAlias() { assertEquals(Optional.of("A 32 mA ΣΔ-modulator"), emptyEntry.getFieldOrAliasLatexFree("journaltitle")); } - @Test - public void getFieldOrAliasLatexFreeDoesNotChangeDateSemantics() { - emptyEntry.setField("date", "2003-03-30"); - assertEquals(Optional.of("3"), emptyEntry.getFieldOrAliasLatexFree("month")); - } - @Test(expected = NullPointerException.class) public void setNullField() { emptyEntry.setField(null); diff --git a/src/test/java/org/jabref/model/entry/DateTest.java b/src/test/java/org/jabref/model/entry/DateTest.java new file mode 100644 index 00000000000..5c55cc92179 --- /dev/null +++ b/src/test/java/org/jabref/model/entry/DateTest.java @@ -0,0 +1,17 @@ +package org.jabref.model.entry; + +import java.time.LocalDate; +import java.util.Optional; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class DateTest { + + @Test + public void parseCorrectlyDayMonthYearDate() throws Exception { + Date expected = new Date(LocalDate.of(2014, 6, 19)); + assertEquals(Optional.of(expected), Date.parse("19-06-2014")); + } +} diff --git a/src/test/java/org/jabref/model/entry/MonthTest.java b/src/test/java/org/jabref/model/entry/MonthTest.java new file mode 100644 index 00000000000..943f29fbf1b --- /dev/null +++ b/src/test/java/org/jabref/model/entry/MonthTest.java @@ -0,0 +1,102 @@ +package org.jabref.model.entry; + +import java.util.Optional; + +import org.junit.Assert; +import org.junit.Test; + +public class MonthTest { + + @Test + public void parseCorrectlyByShortName() { + Assert.assertEquals(Optional.of(Month.JANUARY), Month.parse("jan")); + Assert.assertEquals(Optional.of(Month.FEBRUARY), Month.parse("feb")); + Assert.assertEquals(Optional.of(Month.MARCH), Month.parse("mar")); + Assert.assertEquals(Optional.of(Month.APRIL), Month.parse("apr")); + Assert.assertEquals(Optional.of(Month.MAY), Month.parse("may")); + Assert.assertEquals(Optional.of(Month.JUNE), Month.parse("jun")); + Assert.assertEquals(Optional.of(Month.JULY), Month.parse("jul")); + Assert.assertEquals(Optional.of(Month.AUGUST), Month.parse("aug")); + Assert.assertEquals(Optional.of(Month.SEPTEMBER), Month.parse("sep")); + Assert.assertEquals(Optional.of(Month.OCTOBER), Month.parse("oct")); + Assert.assertEquals(Optional.of(Month.NOVEMBER), Month.parse("nov")); + Assert.assertEquals(Optional.of(Month.DECEMBER), Month.parse("dec")); + } + + @Test + public void parseCorrectlyByBibtexName() { + Assert.assertEquals(Optional.of(Month.JANUARY), Month.parse("#jan#")); + Assert.assertEquals(Optional.of(Month.FEBRUARY), Month.parse("#feb#")); + Assert.assertEquals(Optional.of(Month.MARCH), Month.parse("#mar#")); + Assert.assertEquals(Optional.of(Month.APRIL), Month.parse("#apr#")); + Assert.assertEquals(Optional.of(Month.MAY), Month.parse("#may#")); + Assert.assertEquals(Optional.of(Month.JUNE), Month.parse("#jun#")); + Assert.assertEquals(Optional.of(Month.JULY), Month.parse("#jul#")); + Assert.assertEquals(Optional.of(Month.AUGUST), Month.parse("#aug#")); + Assert.assertEquals(Optional.of(Month.SEPTEMBER), Month.parse("#sep#")); + Assert.assertEquals(Optional.of(Month.OCTOBER), Month.parse("#oct#")); + Assert.assertEquals(Optional.of(Month.NOVEMBER), Month.parse("#nov#")); + Assert.assertEquals(Optional.of(Month.DECEMBER), Month.parse("#dec#")); + } + + @Test + public void parseCorrectlyByFullName() { + Assert.assertEquals(Optional.of(Month.JANUARY), Month.parse("January")); + Assert.assertEquals(Optional.of(Month.FEBRUARY), Month.parse("February")); + Assert.assertEquals(Optional.of(Month.MARCH), Month.parse("March")); + Assert.assertEquals(Optional.of(Month.APRIL), Month.parse("April")); + Assert.assertEquals(Optional.of(Month.MAY), Month.parse("May")); + Assert.assertEquals(Optional.of(Month.JUNE), Month.parse("June")); + Assert.assertEquals(Optional.of(Month.JULY), Month.parse("July")); + Assert.assertEquals(Optional.of(Month.AUGUST), Month.parse("August")); + Assert.assertEquals(Optional.of(Month.SEPTEMBER), Month.parse("September")); + Assert.assertEquals(Optional.of(Month.OCTOBER), Month.parse("October")); + Assert.assertEquals(Optional.of(Month.NOVEMBER), Month.parse("November")); + Assert.assertEquals(Optional.of(Month.DECEMBER), Month.parse("December")); + } + + @Test + public void parseCorrectlyByTwoDigitNumber() { + Assert.assertEquals(Optional.of(Month.JANUARY), Month.parse("01")); + Assert.assertEquals(Optional.of(Month.FEBRUARY), Month.parse("02")); + Assert.assertEquals(Optional.of(Month.MARCH), Month.parse("03")); + Assert.assertEquals(Optional.of(Month.APRIL), Month.parse("04")); + Assert.assertEquals(Optional.of(Month.MAY), Month.parse("05")); + Assert.assertEquals(Optional.of(Month.JUNE), Month.parse("06")); + Assert.assertEquals(Optional.of(Month.JULY), Month.parse("07")); + Assert.assertEquals(Optional.of(Month.AUGUST), Month.parse("08")); + Assert.assertEquals(Optional.of(Month.SEPTEMBER), Month.parse("09")); + Assert.assertEquals(Optional.of(Month.OCTOBER), Month.parse("10")); + Assert.assertEquals(Optional.of(Month.NOVEMBER), Month.parse("11")); + Assert.assertEquals(Optional.of(Month.DECEMBER), Month.parse("12")); + } + + @Test + public void parseCorrectlyByNumber() { + Assert.assertEquals(Optional.of(Month.JANUARY), Month.parse("1")); + Assert.assertEquals(Optional.of(Month.FEBRUARY), Month.parse("2")); + Assert.assertEquals(Optional.of(Month.MARCH), Month.parse("3")); + Assert.assertEquals(Optional.of(Month.APRIL), Month.parse("4")); + Assert.assertEquals(Optional.of(Month.MAY), Month.parse("5")); + Assert.assertEquals(Optional.of(Month.JUNE), Month.parse("6")); + Assert.assertEquals(Optional.of(Month.JULY), Month.parse("7")); + Assert.assertEquals(Optional.of(Month.AUGUST), Month.parse("8")); + Assert.assertEquals(Optional.of(Month.SEPTEMBER), Month.parse("9")); + Assert.assertEquals(Optional.of(Month.OCTOBER), Month.parse("10")); + Assert.assertEquals(Optional.of(Month.NOVEMBER), Month.parse("11")); + Assert.assertEquals(Optional.of(Month.DECEMBER), Month.parse("12")); + } + + @Test + public void parseReturnsEmptyOptionalForInvalidInput() { + Assert.assertEquals(Optional.empty(), Month.parse(";lkjasdf")); + Assert.assertEquals(Optional.empty(), Month.parse("3.2")); + Assert.assertEquals(Optional.empty(), Month.parse("#test#")); + Assert.assertEquals(Optional.empty(), Month.parse("8,")); + } + + @Test + public void parseReturnsEmptyOptionalForEmptyInput() { + Assert.assertEquals(Optional.empty(), Month.parse("")); + } +} diff --git a/src/test/java/org/jabref/model/entry/MonthUtilTest.java b/src/test/java/org/jabref/model/entry/MonthUtilTest.java deleted file mode 100644 index 37036224972..00000000000 --- a/src/test/java/org/jabref/model/entry/MonthUtilTest.java +++ /dev/null @@ -1,80 +0,0 @@ -package org.jabref.model.entry; - -import org.junit.Assert; -import org.junit.Test; - -public class MonthUtilTest { - - @Test - public void testToMonthNumber() { - Assert.assertEquals(0, MonthUtil.getMonth("jan").index); - Assert.assertEquals(1, MonthUtil.getMonth("feb").index); - Assert.assertEquals(2, MonthUtil.getMonth("mar").index); - Assert.assertEquals(3, MonthUtil.getMonth("apr").index); - Assert.assertEquals(4, MonthUtil.getMonth("may").index); - Assert.assertEquals(5, MonthUtil.getMonth("jun").index); - Assert.assertEquals(6, MonthUtil.getMonth("jul").index); - Assert.assertEquals(7, MonthUtil.getMonth("aug").index); - Assert.assertEquals(8, MonthUtil.getMonth("sep").index); - Assert.assertEquals(9, MonthUtil.getMonth("oct").index); - Assert.assertEquals(10, MonthUtil.getMonth("nov").index); - Assert.assertEquals(11, MonthUtil.getMonth("dec").index); - - Assert.assertEquals(0, MonthUtil.getMonth("#jan#").index); - Assert.assertEquals(1, MonthUtil.getMonth("#feb#").index); - Assert.assertEquals(2, MonthUtil.getMonth("#mar#").index); - Assert.assertEquals(3, MonthUtil.getMonth("#apr#").index); - Assert.assertEquals(4, MonthUtil.getMonth("#may#").index); - Assert.assertEquals(5, MonthUtil.getMonth("#jun#").index); - Assert.assertEquals(6, MonthUtil.getMonth("#jul#").index); - Assert.assertEquals(7, MonthUtil.getMonth("#aug#").index); - Assert.assertEquals(8, MonthUtil.getMonth("#sep#").index); - Assert.assertEquals(9, MonthUtil.getMonth("#oct#").index); - Assert.assertEquals(10, MonthUtil.getMonth("#nov#").index); - Assert.assertEquals(11, MonthUtil.getMonth("#dec#").index); - - Assert.assertEquals(0, MonthUtil.getMonth("January").index); - Assert.assertEquals(1, MonthUtil.getMonth("February").index); - Assert.assertEquals(2, MonthUtil.getMonth("March").index); - Assert.assertEquals(3, MonthUtil.getMonth("April").index); - Assert.assertEquals(4, MonthUtil.getMonth("May").index); - Assert.assertEquals(5, MonthUtil.getMonth("June").index); - Assert.assertEquals(6, MonthUtil.getMonth("July").index); - Assert.assertEquals(7, MonthUtil.getMonth("August").index); - Assert.assertEquals(8, MonthUtil.getMonth("September").index); - Assert.assertEquals(9, MonthUtil.getMonth("October").index); - Assert.assertEquals(10, MonthUtil.getMonth("November").index); - Assert.assertEquals(11, MonthUtil.getMonth("December").index); - - Assert.assertEquals(0, MonthUtil.getMonth("01").index); - Assert.assertEquals(1, MonthUtil.getMonth("02").index); - Assert.assertEquals(2, MonthUtil.getMonth("03").index); - Assert.assertEquals(3, MonthUtil.getMonth("04").index); - Assert.assertEquals(4, MonthUtil.getMonth("05").index); - Assert.assertEquals(5, MonthUtil.getMonth("06").index); - Assert.assertEquals(6, MonthUtil.getMonth("07").index); - Assert.assertEquals(7, MonthUtil.getMonth("08").index); - Assert.assertEquals(8, MonthUtil.getMonth("09").index); - Assert.assertEquals(9, MonthUtil.getMonth("10").index); - - Assert.assertEquals(0, MonthUtil.getMonth("1").index); - Assert.assertEquals(1, MonthUtil.getMonth("2").index); - Assert.assertEquals(2, MonthUtil.getMonth("3").index); - Assert.assertEquals(3, MonthUtil.getMonth("4").index); - Assert.assertEquals(4, MonthUtil.getMonth("5").index); - Assert.assertEquals(5, MonthUtil.getMonth("6").index); - Assert.assertEquals(6, MonthUtil.getMonth("7").index); - Assert.assertEquals(7, MonthUtil.getMonth("8").index); - Assert.assertEquals(8, MonthUtil.getMonth("9").index); - - Assert.assertEquals(10, MonthUtil.getMonth("11").index); - Assert.assertEquals(11, MonthUtil.getMonth("12").index); - - Assert.assertEquals(-1, MonthUtil.getMonth(";lkjasdf").index); - Assert.assertEquals(-1, MonthUtil.getMonth("3.2").index); - Assert.assertEquals(-1, MonthUtil.getMonth("#test#").index); - Assert.assertEquals(-1, MonthUtil.getMonth("").index); - Assert.assertFalse(MonthUtil.getMonth("8,").isValid()); - Assert.assertTrue(MonthUtil.getMonth("jan").isValid()); - } -} diff --git a/src/test/resources/org/jabref/logic/importer/fileformat/MsBibImporterTest7.bib b/src/test/resources/org/jabref/logic/importer/fileformat/MsBibImporterTest7.bib index 88e71a36951..fe777516649 100644 --- a/src/test/resources/org/jabref/logic/importer/fileformat/MsBibImporterTest7.bib +++ b/src/test/resources/org/jabref/logic/importer/fileformat/MsBibImporterTest7.bib @@ -5,7 +5,7 @@ @Article{Orlowski;2011 title = {Application of Ontology In the ITIL Domain}, journal = {Information Systems Architecture and Technology: Service Oriented Networked Systems}, year = {2011}, - month = {mar}, + month = mar, volume = {5}, issue = {3}, pages = {99--108}, diff --git a/src/test/resources/org/jabref/logic/importer/fileformat/RepecNepImporterTest1.bib b/src/test/resources/org/jabref/logic/importer/fileformat/RepecNepImporterTest1.bib index 77ca5eaf3c0..863bbc34d18 100644 --- a/src/test/resources/org/jabref/logic/importer/fileformat/RepecNepImporterTest1.bib +++ b/src/test/resources/org/jabref/logic/importer/fileformat/RepecNepImporterTest1.bib @@ -1,7 +1,7 @@ @TechReport{, Title = {Innovation races: An experimental study on strategic research activities}, Year = {2005}, - Month = {11}, + Month = nov, day = {7}, Abstract = {Lorem ipsum abstract}, author = {Uwe Cantner and Andreas Nicklisch and Torsten Weiland}, diff --git a/src/test/resources/org/jabref/logic/importer/fileformat/RepecNepImporterTest2.bib b/src/test/resources/org/jabref/logic/importer/fileformat/RepecNepImporterTest2.bib index 1b7aa9402a7..9f24d3e4249 100644 --- a/src/test/resources/org/jabref/logic/importer/fileformat/RepecNepImporterTest2.bib +++ b/src/test/resources/org/jabref/logic/importer/fileformat/RepecNepImporterTest2.bib @@ -4,7 +4,7 @@ @TechReport{ author = {M?ller,Rudolf and Perea,Andr?s and Wolf,Sascha}, title = {Weak Monotonicity and Bayes-Nash Incentive Compatibility}, year = {2005}, - month = {8}, + month = aug, abstract = {Lorem ipsum abstract}, day = {31}, keywords = {mathematical economics}, diff --git a/src/test/resources/org/jabref/logic/importer/fileformat/RepecNepImporterTest3.bib b/src/test/resources/org/jabref/logic/importer/fileformat/RepecNepImporterTest3.bib index dd91a985130..25b69b52242 100644 --- a/src/test/resources/org/jabref/logic/importer/fileformat/RepecNepImporterTest3.bib +++ b/src/test/resources/org/jabref/logic/importer/fileformat/RepecNepImporterTest3.bib @@ -2,6 +2,5 @@ @TechReport{, title = {Commercial Television and Voter Information}, - year = {2016}, url = {http://d.repec.org/n?u=RePEc:cla:levrem:784828000000000363&r=ict} }