diff --git a/CHANGELOG.md b/CHANGELOG.md index a410e8c5a0f..4325cc45e7b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - Made it possible to download multiple entries in one action - [#1813](https://github.com/JabRef/jabref/issues/1813) Import/Export preferences dialog default directory set to working directory - [#1897](https://github.com/JabRef/jabref/issues/1897) Implemented integrity check for `year` field: Last four nonpunctuation characters should be numerals +- Address in MS-Office 2007 xml format is now imported as `location` + ### Fixed - Fixed NullPointerException when opening search result window for an untitled database @@ -24,6 +26,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - Fixed [#1757](https://github.com/JabRef/jabref/issues/1757): Crash after saving illegal argument in entry editor - Fixed [#1663](https://github.com/JabRef/jabref/issues/1663): Better multi-monitor support - Fixed [#1882](https://github.com/JabRef/jabref/issues/1882): Crash after saving illegal bibtexkey in entry editor +- Fixed field `location` containing only city is not exported correctly to MS-Office 2007 xml format ### Removed - The non-supported feature of being able to define file directories for any extension is removed. Still, it should work for older databases using the legacy `ps` and `pdf` fields, although we strongly encourage using the `file` field. diff --git a/src/main/java/net/sf/jabref/logic/exporter/MSBibExportFormat.java b/src/main/java/net/sf/jabref/logic/exporter/MSBibExportFormat.java index de5082a5c92..96f93433e09 100644 --- a/src/main/java/net/sf/jabref/logic/exporter/MSBibExportFormat.java +++ b/src/main/java/net/sf/jabref/logic/exporter/MSBibExportFormat.java @@ -43,7 +43,7 @@ public void performExport(final BibDatabaseContext databaseContext, final String try (VerifyingWriter ps = session.getWriter()) { try { - DOMSource source = new DOMSource(msBibDatabase.getDOM()); + DOMSource source = new DOMSource(msBibDatabase.getDomForExport()); StreamResult result = new StreamResult(ps); Transformer trans = TransformerFactory.newInstance().newTransformer(); trans.setOutputProperty(OutputKeys.INDENT, "yes"); diff --git a/src/main/java/net/sf/jabref/logic/importer/fileformat/MsBibImporter.java b/src/main/java/net/sf/jabref/logic/importer/fileformat/MsBibImporter.java index 77fad942d97..3fd2017f22b 100644 --- a/src/main/java/net/sf/jabref/logic/importer/fileformat/MsBibImporter.java +++ b/src/main/java/net/sf/jabref/logic/importer/fileformat/MsBibImporter.java @@ -46,7 +46,7 @@ public ParserResult importDatabase(BufferedReader reader) throws IOException { Objects.requireNonNull(reader); MSBibDatabase dbase = new MSBibDatabase(); - return new ParserResult(dbase.importEntries(reader)); + return new ParserResult(dbase.importEntriesFromXml(reader)); } @Override diff --git a/src/main/java/net/sf/jabref/logic/msbib/BibTeXConverter.java b/src/main/java/net/sf/jabref/logic/msbib/BibTeXConverter.java index 824143364ff..fd4acacf2cb 100644 --- a/src/main/java/net/sf/jabref/logic/msbib/BibTeXConverter.java +++ b/src/main/java/net/sf/jabref/logic/msbib/BibTeXConverter.java @@ -19,6 +19,11 @@ public class BibTeXConverter { private static final String MSBIB_PREFIX = "msbib-"; + /** + * Converts an {@link MSBibEntry} to a {@link BibEntry} for import + * @param entry The MsBibEntry to convert + * @return The bib entry + */ public static BibEntry convert(MSBibEntry entry) { BibEntry result; Map fieldValues = new HashMap<>(); @@ -72,7 +77,7 @@ public static BibEntry convert(MSBibEntry entry) { parseStandardNumber(entry.standardNumber, fieldValues); if (entry.address != null) { - fieldValues.put(FieldName.ADDRESS, entry.address); + fieldValues.put(FieldName.LOCATION, entry.address); } // TODO: ConferenceName is saved as booktitle when converting from MSBIB to BibTeX if (entry.conferenceName != null) { diff --git a/src/main/java/net/sf/jabref/logic/msbib/MSBibDatabase.java b/src/main/java/net/sf/jabref/logic/msbib/MSBibDatabase.java index beb7a954f15..1eeb5e70705 100644 --- a/src/main/java/net/sf/jabref/logic/msbib/MSBibDatabase.java +++ b/src/main/java/net/sf/jabref/logic/msbib/MSBibDatabase.java @@ -26,7 +26,7 @@ /** * Microsoft Word bibliography. - * + * The class is uesed both for import and export * See http://www.ecma-international.org/publications/standards/Ecma-376.htm */ public class MSBibDatabase { @@ -39,20 +39,33 @@ public class MSBibDatabase { private Set entries; + /** + * Creates a {@link MSBibDatabase} for import + */ public MSBibDatabase() { entries = new HashSet<>(); } // TODO: why an additonal entry list? entries are included inside database! + /** + * Creates a new {@link MSBibDatabase} for export + * @param database The bib database + * @param entries List of {@link BibEntry} + */ public MSBibDatabase(BibDatabase database, List entries) { if (entries == null) { - addEntries(database.getEntries()); + addEntriesForExport(database.getEntries()); } else { - addEntries(entries); + addEntriesForExport(entries); } } - public List importEntries(BufferedReader reader) { + /** + * Imports entries from an office xml file + * @param reader + * @return List of {@link BibEntry} + */ + public List importEntriesFromXml(BufferedReader reader) { entries = new HashSet<>(); Document inputDocument; try { @@ -83,7 +96,7 @@ public List importEntries(BufferedReader reader) { return bibitems; } - private void addEntries(List entriesToAdd) { + private void addEntriesForExport(List entriesToAdd) { entries = new HashSet<>(); for (BibEntry entry : entriesToAdd) { MSBibEntry newMods = MSBibConverter.convert(entry); @@ -91,7 +104,11 @@ private void addEntries(List entriesToAdd) { } } - public Document getDOM() { + /** + * Gets the assembled dom for export + * @return XML Document + */ + public Document getDomForExport() { Document document = null; try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); @@ -106,7 +123,7 @@ public Document getDOM() { rootNode.setAttribute("SelectedStyle", ""); for (MSBibEntry entry : entries) { - Node node = entry.getDOM(document); + Node node = entry.getEntryDom(document); rootNode.appendChild(node); } document.appendChild(rootNode); diff --git a/src/main/java/net/sf/jabref/logic/msbib/MSBibEntry.java b/src/main/java/net/sf/jabref/logic/msbib/MSBibEntry.java index f42a5868a56..90e3990f475 100644 --- a/src/main/java/net/sf/jabref/logic/msbib/MSBibEntry.java +++ b/src/main/java/net/sf/jabref/logic/msbib/MSBibEntry.java @@ -64,24 +64,32 @@ class MSBibEntry { private String bibtexEntryType; - // reduced subset, supports only "CITY , STATE, COUNTRY" - // \b(\w+)\s?[,]?\s?(\w+)\s?[,]?\s?(\w+)\b - // WORD SPACE , SPACE WORD SPACE , SPACE WORD - // tested using http://www.javaregex.com/test.html - private static final Pattern ADDRESS_PATTERN = Pattern.compile("\\b(\\w+)\\s?[,]?\\s?(\\w+)\\s?[,]?\\s?(\\w+)\\b"); - - // Allows 20.3-2007|||20/3- 2007 etc. - // (\d{1,2})\s?[.,-/]\s?(\d{1,2})\s?[.,-/]\s?(\d{2,4}) - // 1-2 DIGITS SPACE SEPERATOR SPACE 1-2 DIGITS SPACE SEPERATOR SPACE 2-4 DIGITS - // tested using http://www.javaregex.com/test.html + /** + * reduced subset, supports only "CITY , STATE, COUNTRY"
+ * \b(\w+)\s?[,]?\s?(\w+)\s?[,]?\s?(\w*)\b
+ * WORD SPACE , SPACE WORD SPACE (Can be zero or more) , SPACE WORD (Can be zero or more)
+ * Matches both single locations (only city) like Berlin and full locations like Stroudsburg, PA, USA
+ * tested using http://www.regexpal.com/ + */ + private final Pattern ADDRESS_PATTERN = Pattern.compile("\\b(\\w+)\\s?[,]?\\s?(\\w*)\\s?[,]?\\s?(\\w*)\\b"); + + /** + * Allows 20.3-2007|||20/3- 2007 etc. + * (\d{1,2})\s?[.,-/]\s?(\d{1,2})\s?[.,-/]\s?(\d{2,4}) + * 1-2 DIGITS SPACE SEPERATOR SPACE 1-2 DIGITS SPACE SEPERATOR SPACE 2-4 DIGITS + */ private static final Pattern DATE_PATTERN = Pattern .compile("(\\d{1,2})\\s*[.,-/]\\s*(\\d{1,2})\\s*[.,-/]\\s*(\\d{2,4})"); public MSBibEntry() { - + //empty } + /** + * Createa new {@link MsBibEntry} to import from an xml element + * @param entry + */ public MSBibEntry(Element entry) { populateFromXml(entry); } @@ -128,14 +136,17 @@ private void populateFromXml(Element entry) { String city = getXmlElementTextContent("City", entry); String state = getXmlElementTextContent("StateProvince", entry); String country = getXmlElementTextContent("CountryRegion", entry); + StringBuilder addressBuffer = new StringBuilder(); if (city != null) { - addressBuffer.append(city).append(", "); + addressBuffer.append(city); } - if (state != null) { - addressBuffer.append(state).append(' '); + if (((state != null) && !state.isEmpty()) && ((city != null) && !city.isEmpty())) { + addressBuffer.append(",").append(' '); + addressBuffer.append(state); } - if (country != null) { + if ((country != null) && !country.isEmpty()) { + addressBuffer.append(",").append(' '); addressBuffer.append(country); } address = addressBuffer.toString().trim(); @@ -231,7 +242,12 @@ private List getSpecificAuthors(String type, Element authors) { return result; } - public Element getDOM(Document document) { + /** + * Gets the dom representation for one entry, used for export + * @param document XmlDocument + * @return XmlElement represenation of one entry + */ + public Element getEntryDom(Document document) { Element rootNode = document.createElementNS(MSBibDatabase.NAMESPACE, MSBibDatabase.PREFIX + "Source"); for (Map.Entry entry : fields.entrySet()) { @@ -318,18 +334,18 @@ private void addAuthor(Document document, Element allAuthors, String entryName, allAuthors.appendChild(authorTop); } - private void addAddress(Document document, Element parent, String address) { - if (address == null) { + private void addAddress(Document document, Element parent, String addressToSplit) { + if (addressToSplit == null) { return; } - Matcher matcher = ADDRESS_PATTERN.matcher(address); + Matcher matcher = ADDRESS_PATTERN.matcher(addressToSplit); if (matcher.matches() && (matcher.groupCount() >= 3)) { addField(document, parent, "City", matcher.group(1)); addField(document, parent, "StateProvince", matcher.group(2)); addField(document, parent, "CountryRegion", matcher.group(3)); } else { - addField(document, parent, "City", address); + addField(document, parent, "City", addressToSplit); } } } diff --git a/src/test/resources/net/sf/jabref/logic/exporter/MsBibExportFormatTest2.xml b/src/test/resources/net/sf/jabref/logic/exporter/MsBibExportFormatTest2.xml index 54b1476c210..4e33f07d9d8 100644 --- a/src/test/resources/net/sf/jabref/logic/exporter/MsBibExportFormatTest2.xml +++ b/src/test/resources/net/sf/jabref/logic/exporter/MsBibExportFormatTest2.xml @@ -15,6 +15,8 @@ 237-248 Wirtschaftsinformatik a + + type diff --git a/src/test/resources/net/sf/jabref/logic/exporter/MsBibLocationTest.bib b/src/test/resources/net/sf/jabref/logic/exporter/MsBibLocationTest.bib new file mode 100644 index 00000000000..c05724a7f90 --- /dev/null +++ b/src/test/resources/net/sf/jabref/logic/exporter/MsBibLocationTest.bib @@ -0,0 +1,10 @@ +% Encoding: UTF-8 + +@InProceedings{LocationTest, + author = {LocationTest}, + location = {Berlin}, + owner = {Christoph Schwentker}, + timestamp = {2016.09.04}, +} + +@Comment{jabref-meta: databaseType:biblatex;} diff --git a/src/test/resources/net/sf/jabref/logic/exporter/MsBibLocationTest.xml b/src/test/resources/net/sf/jabref/logic/exporter/MsBibLocationTest.xml new file mode 100644 index 00000000000..e6c3485a37f --- /dev/null +++ b/src/test/resources/net/sf/jabref/logic/exporter/MsBibLocationTest.xml @@ -0,0 +1,20 @@ + + + +inproceedings +ConferenceProceedings +LocationTest + + + + +LocationTest + + + + +Berlin + + + + diff --git a/src/test/resources/net/sf/jabref/logic/exporter/MsBibMultiAddressTest.bib b/src/test/resources/net/sf/jabref/logic/exporter/MsBibMultiAddressTest.bib new file mode 100644 index 00000000000..c2b6a59a7e6 --- /dev/null +++ b/src/test/resources/net/sf/jabref/logic/exporter/MsBibMultiAddressTest.bib @@ -0,0 +1,11 @@ +% Encoding: UTF-8 + +@InProceedings{MultiAddressTest, + author = {MultiAddressTest}, + location = {Berlin}, + address = {Stroudsburg, PA, USA}, + owner = {Christoph Schwentker}, + timestamp = {2016.09.04}, +} + +@Comment{jabref-meta: databaseType:biblatex;} diff --git a/src/test/resources/net/sf/jabref/logic/exporter/MsBibMultiAddressTest.xml b/src/test/resources/net/sf/jabref/logic/exporter/MsBibMultiAddressTest.xml new file mode 100644 index 00000000000..bd817c1ffcd --- /dev/null +++ b/src/test/resources/net/sf/jabref/logic/exporter/MsBibMultiAddressTest.xml @@ -0,0 +1,20 @@ + + + +inproceedings +ConferenceProceedings +MultiAddressTest + + + + +MultiAddressTest + + + + +Stroudsburg +PA +USA + + diff --git a/src/test/resources/net/sf/jabref/logic/importer/fileformat/MsBibLocationTest.bib b/src/test/resources/net/sf/jabref/logic/importer/fileformat/MsBibLocationTest.bib new file mode 100644 index 00000000000..b84d4086a4b --- /dev/null +++ b/src/test/resources/net/sf/jabref/logic/importer/fileformat/MsBibLocationTest.bib @@ -0,0 +1,8 @@ +% Encoding: UTF-8 + +@InProceedings{LocationTest, + author = {LocationTest}, + location = {Berlin}, +} + +@Comment{jabref-meta: databaseType:biblatex;} diff --git a/src/test/resources/net/sf/jabref/logic/importer/fileformat/MsBibLocationTest.xml b/src/test/resources/net/sf/jabref/logic/importer/fileformat/MsBibLocationTest.xml new file mode 100644 index 00000000000..e6c3485a37f --- /dev/null +++ b/src/test/resources/net/sf/jabref/logic/importer/fileformat/MsBibLocationTest.xml @@ -0,0 +1,20 @@ + + + +inproceedings +ConferenceProceedings +LocationTest + + + + +LocationTest + + + + +Berlin + + + + diff --git a/src/test/resources/net/sf/jabref/logic/importer/fileformat/MsBibMultiLocationAddressTest.bib b/src/test/resources/net/sf/jabref/logic/importer/fileformat/MsBibMultiLocationAddressTest.bib new file mode 100644 index 00000000000..d1a912a8d4e --- /dev/null +++ b/src/test/resources/net/sf/jabref/logic/importer/fileformat/MsBibMultiLocationAddressTest.bib @@ -0,0 +1,8 @@ +% Encoding: UTF-8 + +@InProceedings{LocationTest, + author = {LocationTest}, + location = {Stroudsburg, PA, USA}, +} + +@Comment{jabref-meta: databaseType:biblatex;} diff --git a/src/test/resources/net/sf/jabref/logic/importer/fileformat/MsBibMultiLocationAddressTest.xml b/src/test/resources/net/sf/jabref/logic/importer/fileformat/MsBibMultiLocationAddressTest.xml new file mode 100644 index 00000000000..3453b3850ca --- /dev/null +++ b/src/test/resources/net/sf/jabref/logic/importer/fileformat/MsBibMultiLocationAddressTest.xml @@ -0,0 +1,20 @@ + + + +inproceedings +ConferenceProceedings +LocationTest + + + + +LocationTest + + + + +Stroudsburg +PA +USA + +