From 30f1c3547c78babbb9e8cfaddd0aa4e400677980 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Tue, 11 Apr 2017 22:07:21 +0200 Subject: [PATCH 01/17] Extract date parse logic to new class and slightly improve it --- .../bibtexfields/NormalizeDateFormatter.java | 38 +------ .../importer/fileformat/RepecNepImporter.java | 33 ++---- .../java/org/jabref/model/entry/BibEntry.java | 76 +++---------- .../java/org/jabref/model/entry/Date.java | 102 ++++++++++++++++++ .../org/jabref/model/entry/MonthUtil.java | 28 +++-- 5 files changed, 146 insertions(+), 131 deletions(-) create mode 100644 src/main/java/org/jabref/model/entry/Date.java 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/importer/fileformat/RepecNepImporter.java b/src/main/java/org/jabref/logic/importer/fileformat/RepecNepImporter.java index 8e9b2a0cc1d..ec1eddaa629 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; @@ -347,29 +343,14 @@ 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(date -> { + date.getYear().ifPresent(year -> be.setField(FieldName.YEAR, year.toString())); + date.getMonth().ifPresent(month -> be.setField(FieldName.MONTH, month.toString())); + date.getDay().ifPresent(day -> be.setField(FieldName.DAY, day.toString())); + }); // parse URL field } else if (keyword.startsWith("URL")) { diff --git a/src/main/java/org/jabref/model/entry/BibEntry.java b/src/main/java/org/jabref/model/entry/BibEntry.java index feec9a75daf..1b3114b2a70 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; @@ -299,73 +292,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(Object::toString); } 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(); 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..be5443d6060 --- /dev/null +++ b/src/main/java/org/jabref/model/entry/Date.java @@ -0,0 +1,102 @@ +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.Optional; + +public class Date { + + private final TemporalAccessor date; + + public Date(TemporalAccessor date) { + this.date = date; + } + + 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); + } + + public Optional getDay() { + return get(ChronoField.DAY_OF_MONTH); + } + + /** + * 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. + */ + public static Optional parse(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", "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(MonthUtil::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().number, day.get()); + } else { + date = YearMonth.of(year.get().getValue(), month.get().number); + } + } 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(); + } + } +} diff --git a/src/main/java/org/jabref/model/entry/MonthUtil.java b/src/main/java/org/jabref/model/entry/MonthUtil.java index 802542be146..e455bcfc006 100644 --- a/src/main/java/org/jabref/model/entry/MonthUtil.java +++ b/src/main/java/org/jabref/model/entry/MonthUtil.java @@ -2,6 +2,9 @@ import java.util.Arrays; import java.util.List; +import java.util.Optional; + +import org.jabref.model.strings.StringUtil; /** * Utility class for everything related to months. @@ -107,17 +110,25 @@ public static Month getMonthByShortName(String shortName) { } /** - * This method accepts three types of months given: + * @deprecated use {@link #parse(String)} instead + */ + @Deprecated + public static Month getMonth(String value) { + return parse(value).orElse(MonthUtil.NULL_OBJECT); + } + + /** + * 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...) + * - 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 Month getMonth(String value) { - if (value == null) { - return MonthUtil.NULL_OBJECT; + public static Optional parse(String value) { + if (StringUtil.isBlank(value)) { + return Optional.empty(); } // Much more liberal matching covering most known abbreviations etc. @@ -127,15 +138,14 @@ public static Month getMonth(String value) { } Month month = MonthUtil.getMonthByShortName(testString); if (month.isValid()) { - return month; + return Optional.of(month); } try { int number = Integer.parseInt(value); - return MonthUtil.getMonthByNumber(number); + return Optional.of(MonthUtil.getMonthByNumber(number)); } catch (NumberFormatException e) { - return MonthUtil.NULL_OBJECT; + return Optional.empty(); } } - } From 2fcda7961ddb100bc1090283da33e10e330bd254 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 12 Apr 2017 12:02:05 +0200 Subject: [PATCH 02/17] Convert MonthUtil to enum --- .../gui/entryeditor/FieldExtraComponents.java | 26 +-- .../gui/importer/fetcher/OAI2Fetcher.java | 9 +- .../bibtex/comparator/FieldComparator.java | 6 +- .../bibtexfields/NormalizeMonthFormatter.java | 11 +- .../importer/fetcher/MedlineFetcher.java | 14 +- .../importer/fileformat/IsiImporter.java | 15 +- .../importer/fileformat/RisImporter.java | 8 +- .../logic/importer/util/JSONEntryParser.java | 6 +- .../jabref/logic/layout/format/RisMonth.java | 12 +- .../jabref/logic/msbib/BibTeXConverter.java | 13 +- .../java/org/jabref/logic/xmp/XMPUtil.java | 5 +- .../jabref/model/database/BibDatabase.java | 10 +- .../java/org/jabref/model/entry/BibEntry.java | 19 +-- .../java/org/jabref/model/entry/Date.java | 6 +- .../java/org/jabref/model/entry/Month.java | 134 ++++++++++++++++ .../org/jabref/model/entry/MonthUtil.java | 151 ------------------ .../org/jabref/model/entry/MonthTest.java | 102 ++++++++++++ .../org/jabref/model/entry/MonthUtilTest.java | 80 ---------- 18 files changed, 309 insertions(+), 318 deletions(-) create mode 100644 src/main/java/org/jabref/model/entry/Month.java delete mode 100644 src/main/java/org/jabref/model/entry/MonthUtil.java create mode 100644 src/test/java/org/jabref/model/entry/MonthTest.java delete mode 100644 src/test/java/org/jabref/model/entry/MonthUtilTest.java diff --git a/src/main/java/org/jabref/gui/entryeditor/FieldExtraComponents.java b/src/main/java/org/jabref/gui/entryeditor/FieldExtraComponents.java index 1cf3758c0fa..730cb3c202e 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; @@ -41,7 +45,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; @@ -368,19 +372,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().getBibtexFormat()); } } 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/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/NormalizeMonthFormatter.java b/src/main/java/org/jabref/logic/formatter/bibtexfields/NormalizeMonthFormatter.java index e6f15850156..5a53780e05b 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::getBibtexFormat).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..8be23cb1639 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().getBibtexFormat(); } } @@ -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().getBibtexFormat(); } } catch (NumberFormatException ignored) { // Ignored 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..ad2947a949e 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 @@ -199,10 +199,8 @@ 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); - } + Optional month = Month.getMonthByNumber(monthNumber); + month.ifPresent(parsedMonth -> fields.put(FieldName.MONTH, parsedMonth.getBibtexFormat())); } catch (NumberFormatException ex) { // The month part is unparseable, so we ignore it. } 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..823760b9b8e 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 -> fieldValues.put(FieldName.MONTH, parsedMonth.getBibtexFormat())); } if (entry.number != null) { fieldValues.put(FieldName.NUMBER, entry.number); diff --git a/src/main/java/org/jabref/logic/xmp/XMPUtil.java b/src/main/java/org/jabref/logic/xmp/XMPUtil.java index f0036214e26..302cf30beda 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; @@ -325,7 +325,8 @@ 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.getMonthByIndex(c.get(Calendar.MONTH)); + month.ifPresent(entry::setMonth); } } } 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 1b3114b2a70..14bb0386f1c 100644 --- a/src/main/java/org/jabref/model/entry/BibEntry.java +++ b/src/main/java/org/jabref/model/entry/BibEntry.java @@ -94,6 +94,10 @@ private BibEntry(String id, String type) { this.sharedBibEntryData = new SharedBibEntryData(); } + public Optional setMonth(Month parsedMonth) { + return setField(FieldName.MONTH, parsedMonth.getBibtexFormat()); + } + public Optional replaceKeywords(KeywordList keywordsToReplace, Optional newValue, Character keywordDelimiter) { KeywordList keywordList = getKeywords(keywordDelimiter); @@ -583,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() { diff --git a/src/main/java/org/jabref/model/entry/Date.java b/src/main/java/org/jabref/model/entry/Date.java index be5443d6060..f2ff8e0600f 100644 --- a/src/main/java/org/jabref/model/entry/Date.java +++ b/src/main/java/org/jabref/model/entry/Date.java @@ -70,7 +70,7 @@ public static Optional parse(String dateString) { public static Optional parse(Optional yearValue, Optional monthValue, Optional dayValue) { Optional year = yearValue.flatMap(Date::convertToInt).map(Year::of); - Optional month = monthValue.flatMap(MonthUtil::parse); + Optional month = monthValue.flatMap(Month::parse); Optional day = dayValue.flatMap(Date::convertToInt); @@ -78,9 +78,9 @@ public static Optional parse(Optional yearValue, Optional TemporalAccessor date; if (month.isPresent()) { if (day.isPresent()) { - date = LocalDate.of(year.get().getValue(), month.get().number, day.get()); + date = LocalDate.of(year.get().getValue(), month.get().getNumber(), day.get()); } else { - date = YearMonth.of(year.get().getValue(), month.get().number); + date = YearMonth.of(year.get().getValue(), month.get().getNumber()); } } else { date = year.get(); 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..43e538f0514 --- /dev/null +++ b/src/main/java/org/jabref/model/entry/Month.java @@ -0,0 +1,134 @@ +package org.jabref.model.entry; + +import java.util.Optional; + +import org.jabref.model.strings.StringUtil; + +/** + * Represents a month object. + */ +public enum Month { + + JANUARY("January", "jan", "01", "#jan#", 0), + FEBRUARY("February", "feb", "02", "#feb#", 1), + MARCH("March", "mar", "03", "#mar#", 2), + APRIL("April", "apr", "04", "#apr#", 3), + MAY("May", "may", "05", "#may#", 4), + JUNE("June", "jun", "06", "#jun#", 5), + JULY("July", "jul", "07", "#jul#", 6), + AUGUST("August", "aug", "08", "#aug#", 7), + SEPTEMBER("September", "sep", "09", "#sep#", 8), + OCTOBER("October", "oct", "10", "#oct#", 9), + NOVEMBER("November", "nov", "11", "#nov#", 10), + DECEMBER("December", "dec", "12", "#dec#", 11); + + private final String fullName; + private final String shortName; + private final String twoDigitNumber; + private final String bibtexFormat; + private final int index; + + Month(String fullName, String shortName, String twoDigitNumber, String bibtexFormat, int index) { + this.fullName = fullName; + this.shortName = shortName; + this.twoDigitNumber = twoDigitNumber; + this.bibtexFormat = bibtexFormat; + this.index = index; + } + + /** + * 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) { + return Month.getMonthByIndex(number - 1); + } + + /** + * Find month by zero-based index. + * If the index is not in the valid range, then an empty Optional is returned. + * + * @param index 0-11 is valid + */ + public static Optional getMonthByIndex(int index) { + for (Month month : Month.values()) { + if (month.index == index) { + 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(); + } + } + + public String getShortName() { + return shortName; + } + + public String getBibtexFormat() { + return bibtexFormat; + } + + public int getIndex() { + return index; + } + + public int getNumber() { + return index + 1; + } + + public String getFullName() { + return fullName; + } + + 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 e455bcfc006..00000000000 --- a/src/main/java/org/jabref/model/entry/MonthUtil.java +++ /dev/null @@ -1,151 +0,0 @@ -package org.jabref.model.entry; - -import java.util.Arrays; -import java.util.List; -import java.util.Optional; - -import org.jabref.model.strings.StringUtil; - -/** - * 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; - } - - /** - * @deprecated use {@link #parse(String)} instead - */ - @Deprecated - public static Month getMonth(String value) { - return parse(value).orElse(MonthUtil.NULL_OBJECT); - } - - /** - * 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); - } - Month month = MonthUtil.getMonthByShortName(testString); - if (month.isValid()) { - return Optional.of(month); - } - - try { - int number = Integer.parseInt(value); - return Optional.of(MonthUtil.getMonthByNumber(number)); - } catch (NumberFormatException e) { - return Optional.empty(); - } - } -} 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()); - } -} From d555c920fa268cab51052570d0aec73c95ea019b Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 12 Apr 2017 12:20:01 +0200 Subject: [PATCH 03/17] Add additional possible date format --- .../java/org/jabref/model/entry/Date.java | 76 ++++++++++++------- .../java/org/jabref/model/entry/DateTest.java | 17 +++++ 2 files changed, 67 insertions(+), 26 deletions(-) create mode 100644 src/test/java/org/jabref/model/entry/DateTest.java diff --git a/src/main/java/org/jabref/model/entry/Date.java b/src/main/java/org/jabref/model/entry/Date.java index f2ff8e0600f..589ed32f609 100644 --- a/src/main/java/org/jabref/model/entry/Date.java +++ b/src/main/java/org/jabref/model/entry/Date.java @@ -9,6 +9,7 @@ import java.time.temporal.TemporalAccessor; import java.util.Arrays; import java.util.List; +import java.util.Objects; import java.util.Optional; public class Date { @@ -19,42 +20,18 @@ public Date(TemporalAccessor date) { this.date = date; } - 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); - } - - public Optional getDay() { - return get(ChronoField.DAY_OF_MONTH); - } - /** * 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", "M/uu", "M/uuuu", "MMMM d, uuuu", "MMMM, uuuu", + 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 { @@ -99,4 +76,51 @@ private static Optional convertToInt(String value) { 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); + } + + 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/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")); + } +} From 91ed929e1bff5708475c8793684adc2aebf979a9 Mon Sep 17 00:00:00 2001 From: Linus Dietz Date: Sun, 16 Apr 2017 22:58:00 +0200 Subject: [PATCH 04/17] Replace indices with numbers in Month --- .../java/org/jabref/logic/xmp/XMPUtil.java | 264 +++++++----------- .../java/org/jabref/model/entry/Month.java | 49 ++-- 2 files changed, 117 insertions(+), 196 deletions(-) diff --git a/src/main/java/org/jabref/logic/xmp/XMPUtil.java b/src/main/java/org/jabref/logic/xmp/XMPUtil.java index 302cf30beda..26a70fc5810 100644 --- a/src/main/java/org/jabref/logic/xmp/XMPUtil.java +++ b/src/main/java/org/jabref/logic/xmp/XMPUtil.java @@ -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,13 +304,13 @@ public static Optional getBibtexEntryFromDublinCore(XMPSchemaDublinCor if (c != null) { entry.setField(FieldName.YEAR, String.valueOf(c.get(Calendar.YEAR))); if (date.length() > 4) { - Optional month = Month.getMonthByIndex(c.get(Calendar.MONTH)); + Optional month = Month.getMonthByNumber(c.get(Calendar.MONTH) + 1); month.ifPresent(entry::setMonth); } } } - /** + /* * Abstract -> Description */ String s = dcSchema.getDescription(); @@ -339,7 +318,7 @@ public static Optional getBibtexEntryFromDublinCore(XMPSchemaDublinCor entry.setField(FieldName.ABSTRACT, s); } - /** + /* * Identifier -> DOI */ s = dcSchema.getIdentifier(); @@ -347,7 +326,7 @@ public static Optional getBibtexEntryFromDublinCore(XMPSchemaDublinCor entry.setField(FieldName.DOI, s); } - /** + /* * Publisher -> Publisher */ List publishers = dcSchema.getPublishers(); @@ -355,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 @@ -374,7 +353,7 @@ public static Optional getBibtexEntryFromDublinCore(XMPSchemaDublinCor } } - /** + /* * Rights -> Rights */ s = dcSchema.getRights(); @@ -382,7 +361,7 @@ public static Optional getBibtexEntryFromDublinCore(XMPSchemaDublinCor entry.setField("rights", s); } - /** + /* * Source -> Source */ s = dcSchema.getSource(); @@ -390,7 +369,7 @@ public static Optional getBibtexEntryFromDublinCore(XMPSchemaDublinCor entry.setField("source", s); } - /** + /* * Subject -> Keywords */ List subjects = dcSchema.getSubjects(); @@ -398,7 +377,7 @@ public static Optional getBibtexEntryFromDublinCore(XMPSchemaDublinCor entry.addKeywords(subjects, xmpPreferences.getKeywordSeparator()); } - /** + /* * Title -> Title */ s = dcSchema.getTitle(); @@ -406,7 +385,7 @@ public static Optional getBibtexEntryFromDublinCore(XMPSchemaDublinCor entry.setField(FieldName.TITLE, s); } - /** + /* * Type -> Type */ List l = dcSchema.getTypes(); @@ -432,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); @@ -457,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) { @@ -500,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); @@ -525,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 { @@ -560,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 { @@ -570,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) { @@ -596,7 +555,7 @@ private static void writeToDCSchema(XMPSchemaDublinCore dcSchema, if (FieldName.EDITOR.equals(field.getKey())) { String authors = field.getValue(); - /** + /* * Editor -> Contributor * * Field: dc:contributor @@ -619,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 @@ -658,7 +615,7 @@ private static void writeToDCSchema(XMPSchemaDublinCore dcSchema, if (FieldName.YEAR.equals(field.getKey())) { - /** + /* * Year + Month -> Date * * Field: dc:date @@ -676,7 +633,8 @@ private static void writeToDCSchema(XMPSchemaDublinCore dcSchema, .ifPresent(publicationDate -> dcSchema.addSequenceValue("dc:date", publicationDate)); continue; } - /** + + /* * Abstract -> Description * * Field: dc:description @@ -695,7 +653,7 @@ private static void writeToDCSchema(XMPSchemaDublinCore dcSchema, continue; } - /** + /* * DOI -> identifier * * Field: dc:identifier @@ -713,7 +671,7 @@ private static void writeToDCSchema(XMPSchemaDublinCore dcSchema, continue; } - /** + /* * ? -> Language * * Unmapped @@ -722,7 +680,7 @@ private static void writeToDCSchema(XMPSchemaDublinCore dcSchema, * languages used in the resource. */ - /** + /* * Publisher -> Publisher * * Field: dc:publisher @@ -740,7 +698,7 @@ private static void writeToDCSchema(XMPSchemaDublinCore dcSchema, continue; } - /** + /* * ? -> Rights * * Unmapped @@ -749,7 +707,7 @@ private static void writeToDCSchema(XMPSchemaDublinCore dcSchema, * by language. */ - /** + /* * ? -> Source * * Unmapped @@ -758,7 +716,7 @@ private static void writeToDCSchema(XMPSchemaDublinCore dcSchema, * this resource was derived. */ - /** + /* * Keywords -> Subject * * Field: dc:subject @@ -781,7 +739,7 @@ private static void writeToDCSchema(XMPSchemaDublinCore dcSchema, continue; } - /** + /* * Title -> Title * * Field: dc:title @@ -802,7 +760,7 @@ private static void writeToDCSchema(XMPSchemaDublinCore dcSchema, } - /** + /* * All others (including the bibtex key) get packaged in the * relation attribute */ @@ -810,7 +768,7 @@ private static void writeToDCSchema(XMPSchemaDublinCore dcSchema, dcSchema.addRelation("bibtex/" + field.getKey() + '/' + o); } - /** + /* * ? -> Format * * Unmapped @@ -821,7 +779,7 @@ private static void writeToDCSchema(XMPSchemaDublinCore dcSchema, */ dcSchema.setFormat("application/pdf"); - /** + /* * entrytype -> Type * * Field: dc:type @@ -847,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); @@ -872,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) { @@ -932,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(); @@ -1005,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) { @@ -1104,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/entry/Month.java b/src/main/java/org/jabref/model/entry/Month.java index 43e538f0514..8b82e8c9722 100644 --- a/src/main/java/org/jabref/model/entry/Month.java +++ b/src/main/java/org/jabref/model/entry/Month.java @@ -9,33 +9,34 @@ */ public enum Month { - JANUARY("January", "jan", "01", "#jan#", 0), - FEBRUARY("February", "feb", "02", "#feb#", 1), - MARCH("March", "mar", "03", "#mar#", 2), - APRIL("April", "apr", "04", "#apr#", 3), - MAY("May", "may", "05", "#may#", 4), - JUNE("June", "jun", "06", "#jun#", 5), - JULY("July", "jul", "07", "#jul#", 6), - AUGUST("August", "aug", "08", "#aug#", 7), - SEPTEMBER("September", "sep", "09", "#sep#", 8), - OCTOBER("October", "oct", "10", "#oct#", 9), - NOVEMBER("November", "nov", "11", "#nov#", 10), - DECEMBER("December", "dec", "12", "#dec#", 11); + JANUARY("January", "jan", "01", "#jan#", 1), + FEBRUARY("February", "feb", "02", "#feb#", 2), + MARCH("March", "mar", "03", "#mar#", 3), + APRIL("April", "apr", "04", "#apr#", 4), + MAY("May", "may", "05", "#may#", 5), + JUNE("June", "jun", "06", "#jun#", 6), + JULY("July", "jul", "07", "#jul#", 7), + AUGUST("August", "aug", "08", "#aug#", 8), + SEPTEMBER("September", "sep", "09", "#sep#", 9), + OCTOBER("October", "oct", "10", "#oct#", 10), + NOVEMBER("November", "nov", "11", "#nov#", 11), + DECEMBER("December", "dec", "12", "#dec#", 12); private final String fullName; private final String shortName; private final String twoDigitNumber; private final String bibtexFormat; - private final int index; + private final int number; - Month(String fullName, String shortName, String twoDigitNumber, String bibtexFormat, int index) { + Month(String fullName, String shortName, String twoDigitNumber, String bibtexFormat, int number) { this.fullName = fullName; this.shortName = shortName; this.twoDigitNumber = twoDigitNumber; this.bibtexFormat = bibtexFormat; - this.index = index; + this.number = number; } + /** * Find month by one-based number. * If the number is not in the valid range, then an empty Optional is returned. @@ -43,18 +44,8 @@ public enum Month { * @param number 1-12 is valid */ public static Optional getMonthByNumber(int number) { - return Month.getMonthByIndex(number - 1); - } - - /** - * Find month by zero-based index. - * If the index is not in the valid range, then an empty Optional is returned. - * - * @param index 0-11 is valid - */ - public static Optional getMonthByIndex(int index) { for (Month month : Month.values()) { - if (month.index == index) { + if (month.number == number) { return Optional.of(month); } } @@ -116,12 +107,8 @@ public String getBibtexFormat() { return bibtexFormat; } - public int getIndex() { - return index; - } - public int getNumber() { - return index + 1; + return number; } public String getFullName() { From faa0e5b3a936b47e986e8c13d82d13fe64d8f28a Mon Sep 17 00:00:00 2001 From: Linus Dietz Date: Sun, 16 Apr 2017 23:06:46 +0200 Subject: [PATCH 05/17] fixed camelcase --- ...ibImporterTestfiles.java => MsBibImporterTestFiles.java} | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename src/test/java/org/jabref/logic/importer/fileformat/{MsBibImporterTestfiles.java => MsBibImporterTestFiles.java} (92%) 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()); } From dea34246e095d619f8f0d92edcb49a6be95e4732 Mon Sep 17 00:00:00 2001 From: Linus Dietz Date: Sun, 16 Apr 2017 23:34:45 +0200 Subject: [PATCH 06/17] add javadoc, remove redundant constructor fields --- .../java/org/jabref/model/entry/Month.java | 59 +++++++++++++------ 1 file changed, 40 insertions(+), 19 deletions(-) diff --git a/src/main/java/org/jabref/model/entry/Month.java b/src/main/java/org/jabref/model/entry/Month.java index 8b82e8c9722..54a07167211 100644 --- a/src/main/java/org/jabref/model/entry/Month.java +++ b/src/main/java/org/jabref/model/entry/Month.java @@ -5,34 +5,32 @@ import org.jabref.model.strings.StringUtil; /** - * Represents a month object. + * Represents a Month of the Year. */ public enum Month { - JANUARY("January", "jan", "01", "#jan#", 1), - FEBRUARY("February", "feb", "02", "#feb#", 2), - MARCH("March", "mar", "03", "#mar#", 3), - APRIL("April", "apr", "04", "#apr#", 4), - MAY("May", "may", "05", "#may#", 5), - JUNE("June", "jun", "06", "#jun#", 6), - JULY("July", "jul", "07", "#jul#", 7), - AUGUST("August", "aug", "08", "#aug#", 8), - SEPTEMBER("September", "sep", "09", "#sep#", 9), - OCTOBER("October", "oct", "10", "#oct#", 10), - NOVEMBER("November", "nov", "11", "#nov#", 11), - DECEMBER("December", "dec", "12", "#dec#", 12); + 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 String bibtexFormat; private final int number; - Month(String fullName, String shortName, String twoDigitNumber, String bibtexFormat, int number) { + Month(String fullName, String shortName, int number) { this.fullName = fullName; this.shortName = shortName; - this.twoDigitNumber = twoDigitNumber; - this.bibtexFormat = bibtexFormat; + this.twoDigitNumber = String.format("%02d", number); this.number = number; } @@ -70,7 +68,7 @@ public static Optional getMonthByShortName(String shortName) { /** * 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 + * - 3 Digit BibTeX strings (jan, feb, mar...) possibly with # prepended * - Full English Month identifiers. * * @param value the given value @@ -99,22 +97,45 @@ public static Optional parse(String value) { } } + /** + * 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 BibTeX format. The format is the short 3-digit name surrounded by a '#'. + * Example: #jan#, #feb#, etc. + * + * @return Month in BibTeX format + */ public String getBibtexFormat() { - return bibtexFormat; + 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; } From 52a568be5dc2e80400eddd4426678f06eefa8a14 Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Mon, 17 Apr 2017 13:02:34 +0200 Subject: [PATCH 07/17] Change month on MSXMLimport to numeric --- src/main/java/org/jabref/logic/msbib/BibTeXConverter.java | 2 +- .../org/jabref/logic/importer/fileformat/MsBibImporterTest7.bib | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/jabref/logic/msbib/BibTeXConverter.java b/src/main/java/org/jabref/logic/msbib/BibTeXConverter.java index 823760b9b8e..b4a186dd68b 100644 --- a/src/main/java/org/jabref/logic/msbib/BibTeXConverter.java +++ b/src/main/java/org/jabref/logic/msbib/BibTeXConverter.java @@ -86,7 +86,7 @@ public static BibEntry convert(MSBibEntry entry) { } if (entry.month != null) { Optional month = Month.parse(entry.month); - month.ifPresent(parsedMonth -> fieldValues.put(FieldName.MONTH, parsedMonth.getBibtexFormat())); + month.ifPresent(parsedMonth -> fieldValues.put(FieldName.MONTH, parsedMonth.getTwoDigitNumber())); } if (entry.number != null) { fieldValues.put(FieldName.NUMBER, entry.number); 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..bab15e30db5 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 = {03}, volume = {5}, issue = {3}, pages = {99--108}, From 8cacfb7e7771b6b66d62db6c5a4175e765435e7a Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Mon, 17 Apr 2017 13:31:19 +0200 Subject: [PATCH 08/17] Use BibEntry#setMonth at RisImporter --- .../org/jabref/logic/importer/fileformat/RisImporter.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 ad2947a949e..6f98e6bf660 100644 --- a/src/main/java/org/jabref/logic/importer/fileformat/RisImporter.java +++ b/src/main/java/org/jabref/logic/importer/fileformat/RisImporter.java @@ -70,6 +70,7 @@ public ParserResult importDatabase(BufferedReader reader) throws IOException { String startPage = ""; String endPage = ""; String comment = ""; + BibEntry b = new BibEntry(type); Map fields = new HashMap<>(); String[] lines = entry1.split("\n"); @@ -200,7 +201,7 @@ public ParserResult importDatabase(BufferedReader reader) throws IOException { try { int monthNumber = Integer.parseInt(parts[1]); Optional month = Month.getMonthByNumber(monthNumber); - month.ifPresent(parsedMonth -> fields.put(FieldName.MONTH, parsedMonth.getBibtexFormat())); + month.ifPresent(parsedMonth -> b.setMonth(parsedMonth)); } catch (NumberFormatException ex) { // The month part is unparseable, so we ignore it. } @@ -240,7 +241,6 @@ 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()); From d2d9a97e9c0d74317b6775be0fe6a8f057919363 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Mon, 17 Apr 2017 13:32:12 +0200 Subject: [PATCH 09/17] Use BibEntry#parseMonth at BibTeXConverter --- src/main/java/org/jabref/logic/msbib/BibTeXConverter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/jabref/logic/msbib/BibTeXConverter.java b/src/main/java/org/jabref/logic/msbib/BibTeXConverter.java index b4a186dd68b..9fa936c82ac 100644 --- a/src/main/java/org/jabref/logic/msbib/BibTeXConverter.java +++ b/src/main/java/org/jabref/logic/msbib/BibTeXConverter.java @@ -86,7 +86,7 @@ public static BibEntry convert(MSBibEntry entry) { } if (entry.month != null) { Optional month = Month.parse(entry.month); - month.ifPresent(parsedMonth -> fieldValues.put(FieldName.MONTH, parsedMonth.getTwoDigitNumber())); + month.ifPresent(parsedMonth -> result.setMonth(parsedMonth)); } if (entry.number != null) { fieldValues.put(FieldName.NUMBER, entry.number); From 436645fba069aa775f4938db92af4e1d8ebaca15 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Mon, 17 Apr 2017 13:50:12 +0200 Subject: [PATCH 10/17] Rename getBibtexFormat to getJabRefFormat as this string is something special for JabRef --- .../org/jabref/gui/entryeditor/FieldExtraComponents.java | 2 +- .../formatter/bibtexfields/NormalizeMonthFormatter.java | 2 +- .../jabref/logic/importer/fileformat/IsiImporter.java | 4 ++-- src/main/java/org/jabref/model/entry/BibEntry.java | 2 +- src/main/java/org/jabref/model/entry/Month.java | 9 ++++++--- 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/jabref/gui/entryeditor/FieldExtraComponents.java b/src/main/java/org/jabref/gui/entryeditor/FieldExtraComponents.java index 730cb3c202e..6489b27bd06 100644 --- a/src/main/java/org/jabref/gui/entryeditor/FieldExtraComponents.java +++ b/src/main/java/org/jabref/gui/entryeditor/FieldExtraComponents.java @@ -384,7 +384,7 @@ public static Optional getMonthExtraComponent(FieldEditor fieldEdito if (type == BibDatabaseMode.BIBLATEX) { fieldEditor.setText(String.valueOf(monthNumber)); } else { - fieldEditor.setText(Month.getMonthByNumber(monthNumber).get().getBibtexFormat()); + fieldEditor.setText(Month.getMonthByNumber(monthNumber).get().getJabRefFormat()); } } else { fieldEditor.setText(""); 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 5a53780e05b..eae778c0fa1 100644 --- a/src/main/java/org/jabref/logic/formatter/bibtexfields/NormalizeMonthFormatter.java +++ b/src/main/java/org/jabref/logic/formatter/bibtexfields/NormalizeMonthFormatter.java @@ -23,7 +23,7 @@ public String getKey() { public String format(String value) { Objects.requireNonNull(value); Optional month = Month.parse(value); - return month.map(Month::getBibtexFormat).orElse(value); + return month.map(Month::getJabRefFormat).orElse(value); } @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 8be23cb1639..8999fbc697e 100644 --- a/src/main/java/org/jabref/logic/importer/fileformat/IsiImporter.java +++ b/src/main/java/org/jabref/logic/importer/fileformat/IsiImporter.java @@ -341,7 +341,7 @@ public static String parseMonth(String value) { for (String part1 : parts) { Optional month = Month.getMonthByShortName(part1.toLowerCase(Locale.ROOT)); if (month.isPresent()) { - return month.get().getBibtexFormat(); + return month.get().getJabRefFormat(); } } @@ -351,7 +351,7 @@ public static String parseMonth(String value) { int number = Integer.parseInt(part); Optional month = Month.getMonthByNumber(number); if (month.isPresent()) { - return month.get().getBibtexFormat(); + return month.get().getJabRefFormat(); } } catch (NumberFormatException ignored) { // Ignored diff --git a/src/main/java/org/jabref/model/entry/BibEntry.java b/src/main/java/org/jabref/model/entry/BibEntry.java index 14bb0386f1c..30b08af98e7 100644 --- a/src/main/java/org/jabref/model/entry/BibEntry.java +++ b/src/main/java/org/jabref/model/entry/BibEntry.java @@ -95,7 +95,7 @@ private BibEntry(String id, String type) { } public Optional setMonth(Month parsedMonth) { - return setField(FieldName.MONTH, parsedMonth.getBibtexFormat()); + return setField(FieldName.MONTH, parsedMonth.getJabRefFormat()); } public Optional replaceKeywords(KeywordList keywordsToReplace, Optional newValue, diff --git a/src/main/java/org/jabref/model/entry/Month.java b/src/main/java/org/jabref/model/entry/Month.java index 54a07167211..5c50e1fd877 100644 --- a/src/main/java/org/jabref/model/entry/Month.java +++ b/src/main/java/org/jabref/model/entry/Month.java @@ -107,12 +107,15 @@ public String getShortName() { } /** - * Returns the month in BibTeX format. The format is the short 3-digit name surrounded by a '#'. + * Returns the month in JabRef format. The format is the short 3-digit name surrounded by a '#'. * Example: #jan#, #feb#, etc. * - * @return Month in BibTeX format + * 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 getBibtexFormat() { + public String getJabRefFormat() { return String.format("#%s#", shortName); } From ad3b605be534f6e6bbb1f597e751e88da47091e0 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Mon, 17 Apr 2017 14:13:43 +0200 Subject: [PATCH 11/17] Add test case for month format behavior --- .../logic/bibtex/LatexFieldFormatter.java | 8 ++++++-- .../logic/bibtex/LatexFieldFormatterTests.java | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) 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/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")); + } + } From e1e0816a4197bec019d594b5c6d3c79f919ebddd Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Mon, 17 Apr 2017 14:20:17 +0200 Subject: [PATCH 12/17] Remove year from RepecNepImporterTest as this case does not seem to appear in the wild [ciskip] --- .../jabref/logic/importer/fileformat/RepecNepImporterTest3.bib | 1 - 1 file changed, 1 deletion(-) 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} } From 4ee21080734fe190bb4bdf89e90c0fc9eee7a8b8 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Mon, 17 Apr 2017 15:00:29 +0200 Subject: [PATCH 13/17] Fix test output --- .../org/jabref/logic/importer/fileformat/MsBibImporterTest7.bib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 bab15e30db5..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 = {03}, + month = mar, volume = {5}, issue = {3}, pages = {99--108}, From 80202542e9f469d9a150ae13f4e6a45c5bac8d35 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Mon, 17 Apr 2017 15:12:23 +0200 Subject: [PATCH 14/17] Fix RisImporter --- .../jabref/logic/importer/fileformat/RisImporter.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) 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 6f98e6bf660..ff927d3638f 100644 --- a/src/main/java/org/jabref/logic/importer/fileformat/RisImporter.java +++ b/src/main/java/org/jabref/logic/importer/fileformat/RisImporter.java @@ -70,7 +70,7 @@ public ParserResult importDatabase(BufferedReader reader) throws IOException { String startPage = ""; String endPage = ""; String comment = ""; - BibEntry b = new BibEntry(type); + Optional month = Optional.empty(); Map fields = new HashMap<>(); String[] lines = entry1.split("\n"); @@ -200,8 +200,7 @@ public ParserResult importDatabase(BufferedReader reader) throws IOException { if ((parts.length > 1) && !parts[1].isEmpty()) { try { int monthNumber = Integer.parseInt(parts[1]); - Optional month = Month.getMonthByNumber(monthNumber); - month.ifPresent(parsedMonth -> b.setMonth(parsedMonth)); + month = Month.getMonthByNumber(monthNumber); } catch (NumberFormatException ex) { // The month part is unparseable, so we ignore it. } @@ -246,7 +245,11 @@ else if ("ID".equals(tag)) { 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); } From d3886450911104440727cc83d9c65a2486414ac6 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Mon, 17 Apr 2017 15:15:50 +0200 Subject: [PATCH 15/17] Extract setDate to new method --- .../importer/fileformat/RepecNepImporter.java | 10 ++-------- .../java/org/jabref/model/entry/BibEntry.java | 20 ++++++++++++------- .../java/org/jabref/model/entry/Date.java | 4 ++-- 3 files changed, 17 insertions(+), 17 deletions(-) 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 ec1eddaa629..66bc71c0514 100644 --- a/src/main/java/org/jabref/logic/importer/fileformat/RepecNepImporter.java +++ b/src/main/java/org/jabref/logic/importer/fileformat/RepecNepImporter.java @@ -144,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; @@ -346,11 +344,7 @@ private void parseAdditionalFields(BibEntry be, boolean multilineUrlFieldAllowed } else if (keyword.startsWith("Date")) { // parse date field String content = readMultipleLines(in); - Date.parse(content).ifPresent(date -> { - date.getYear().ifPresent(year -> be.setField(FieldName.YEAR, year.toString())); - date.getMonth().ifPresent(month -> be.setField(FieldName.MONTH, month.toString())); - date.getDay().ifPresent(day -> be.setField(FieldName.DAY, day.toString())); - }); + Date.parse(content).ifPresent(be::setDate); // parse URL field } else if (keyword.startsWith("URL")) { diff --git a/src/main/java/org/jabref/model/entry/BibEntry.java b/src/main/java/org/jabref/model/entry/BibEntry.java index 14bb0386f1c..73b7affbc73 100644 --- a/src/main/java/org/jabref/model/entry/BibEntry.java +++ b/src/main/java/org/jabref/model/entry/BibEntry.java @@ -206,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. */ @@ -233,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. @@ -792,6 +792,12 @@ 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())); + } + 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 index 589ed32f609..77109b8b83f 100644 --- a/src/main/java/org/jabref/model/entry/Date.java +++ b/src/main/java/org/jabref/model/entry/Date.java @@ -94,8 +94,8 @@ public Optional get(ChronoField field) { } } - public Optional getMonth() { - return get(ChronoField.MONTH_OF_YEAR); + public Optional getMonth() { + return get(ChronoField.MONTH_OF_YEAR).flatMap(Month::getMonthByNumber); } public Optional getDay() { From 794322bb2a811afb6c5217f60eea841f4c655da1 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Mon, 17 Apr 2017 15:21:07 +0200 Subject: [PATCH 16/17] Return month in JabRef format --- src/main/java/org/jabref/model/entry/BibEntry.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/jabref/model/entry/BibEntry.java b/src/main/java/org/jabref/model/entry/BibEntry.java index e7884d5cb2c..074388e0a62 100644 --- a/src/main/java/org/jabref/model/entry/BibEntry.java +++ b/src/main/java/org/jabref/model/entry/BibEntry.java @@ -209,15 +209,15 @@ public String getType() { /** * Sets this entry's type. */ - public void setType(String type) { - setType(type, EntryEventSource.LOCAL); + public void setType(EntryType type) { + this.setType(type.getName()); } /** * Sets this entry's type. */ - public void setType(EntryType type) { - this.setType(type.getName()); + public void setType(String type) { + setType(type, EntryEventSource.LOCAL); } /** @@ -316,7 +316,7 @@ private Optional genericGetFieldOrAlias(String name, GetFieldInterface g return parsedDate.get().getYear().map(Object::toString); } if (FieldName.MONTH.equals(name)) { - return parsedDate.get().getMonth().map(Object::toString); + return parsedDate.get().getMonth().map(Month::getJabRefFormat); } if (FieldName.DAY.equals(name)) { return parsedDate.get().getDay().map(Object::toString); From 7c34880143aff2691982c098f8694989d8bf7062 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Mon, 17 Apr 2017 15:48:08 +0200 Subject: [PATCH 17/17] Fix tests --- .../logic/importer/fileformat/RepecNepImporter.java | 1 - .../java/org/jabref/logic/msbib/MSBibConverter.java | 3 ++- src/main/java/org/jabref/model/entry/BibEntry.java | 12 ++++++++---- .../java/org/jabref/model/entry/BibEntryTests.java | 10 ++-------- .../importer/fileformat/RepecNepImporterTest1.bib | 2 +- .../importer/fileformat/RepecNepImporterTest2.bib | 2 +- 6 files changed, 14 insertions(+), 16 deletions(-) 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 66bc71c0514..4f61ce2ef83 100644 --- a/src/main/java/org/jabref/logic/importer/fileformat/RepecNepImporter.java +++ b/src/main/java/org/jabref/logic/importer/fileformat/RepecNepImporter.java @@ -345,7 +345,6 @@ private void parseAdditionalFields(BibEntry be, boolean multilineUrlFieldAllowed // parse date field String content = readMultipleLines(in); 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/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/model/entry/BibEntry.java b/src/main/java/org/jabref/model/entry/BibEntry.java index 074388e0a62..f86bc470fa1 100644 --- a/src/main/java/org/jabref/model/entry/BibEntry.java +++ b/src/main/java/org/jabref/model/entry/BibEntry.java @@ -209,15 +209,15 @@ public String getType() { /** * Sets this entry's type. */ - public void setType(EntryType type) { - this.setType(type.getName()); + public void setType(String type) { + setType(type, EntryEventSource.LOCAL); } /** * Sets this entry's type. */ - public void setType(String type) { - setType(type, EntryEventSource.LOCAL); + public void setType(EntryType type) { + this.setType(type.getName()); } /** @@ -798,6 +798,10 @@ public void setDate(Date date) { 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/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/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},