package org.jabref.logic.importer.util;
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.Month;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONArray;
import org.json.JSONObject;
public class JSONEntryParser {
private static final Log LOGGER = LogFactory.getLog(JSONEntryParser.class);
/**
* Convert a JSONObject containing a bibJSON entry to a BibEntry
*
* @param bibJsonEntry The JSONObject to convert
* @return the converted BibEntry
*/
public BibEntry parseBibJSONtoBibtex(JSONObject bibJsonEntry, Character keywordSeparator) {
// Fields that are directly accessible at the top level BibJson object
String[] singleFieldStrings = {FieldName.YEAR, FieldName.TITLE, FieldName.ABSTRACT, FieldName.MONTH};
// Fields that are accessible in the journal part of the BibJson object
String[] journalSingleFieldStrings = {FieldName.PUBLISHER, FieldName.NUMBER, FieldName.VOLUME};
BibEntry entry = new BibEntry();
entry.setType("article");
// Authors
if (bibJsonEntry.has("author")) {
JSONArray authors = bibJsonEntry.getJSONArray("author");
List<String> authorList = new ArrayList<>();
for (int i = 0; i < authors.length(); i++) {
if (authors.getJSONObject(i).has("name")) {
authorList.add(authors.getJSONObject(i).getString("name"));
} else {
LOGGER.info("Empty author name.");
}
}
entry.setField(FieldName.AUTHOR, String.join(" and ", authorList));
} else {
LOGGER.info("No author found.");
}
// Direct accessible fields
for (String field : singleFieldStrings) {
if (bibJsonEntry.has(field)) {
entry.setField(field, bibJsonEntry.getString(field));
}
}
// Page numbers
if (bibJsonEntry.has("start_page")) {
if (bibJsonEntry.has("end_page")) {
entry.setField(FieldName.PAGES,
bibJsonEntry.getString("start_page") + "--" + bibJsonEntry.getString("end_page"));
} else {
entry.setField(FieldName.PAGES, bibJsonEntry.getString("start_page"));
}
}
// Journal
if (bibJsonEntry.has("journal")) {
JSONObject journal = bibJsonEntry.getJSONObject("journal");
// Journal title
if (journal.has("title")) {
entry.setField(FieldName.JOURNAL, journal.getString("title"));
} else {
LOGGER.info("No journal title found.");
}
// Other journal related fields
for (String field : journalSingleFieldStrings) {
if (journal.has(field)) {
entry.setField(field, journal.getString(field));
}
}
} else {
LOGGER.info("No journal information found.");
}
// Keywords
if (bibJsonEntry.has("keywords")) {
JSONArray keywords = bibJsonEntry.getJSONArray("keywords");
for (int i = 0; i < keywords.length(); i++) {
if (!keywords.isNull(i)) {
entry.addKeyword(keywords.getString(i), keywordSeparator);
}
}
}
// Identifiers
if (bibJsonEntry.has("identifier")) {
JSONArray identifiers = bibJsonEntry.getJSONArray("identifier");
for (int i = 0; i < identifiers.length(); i++) {
String type = identifiers.getJSONObject(i).getString("type");
if ("doi".equals(type)) {
entry.setField(FieldName.DOI, identifiers.getJSONObject(i).getString("id"));
} else if ("pissn".equals(type)) {
entry.setField(FieldName.ISSN, identifiers.getJSONObject(i).getString("id"));
} else if ("eissn".equals(type)) {
entry.setField(FieldName.ISSN, identifiers.getJSONObject(i).getString("id"));
}
}
}
// Links
if (bibJsonEntry.has("link")) {
JSONArray links = bibJsonEntry.getJSONArray("link");
for (int i = 0; i < links.length(); i++) {
if (links.getJSONObject(i).has("type")) {
String type = links.getJSONObject(i).getString("type");
if ("fulltext".equals(type) && links.getJSONObject(i).has("url")) {
entry.setField(FieldName.URL, links.getJSONObject(i).getString("url"));
}
}
}
}
return entry;
}
/**
* Convert a JSONObject obtained from http://api.springer.com/metadata/json to a BibEntry
*
* @param springerJsonEntry the JSONObject from search results
* @return the converted BibEntry
*/
public static BibEntry parseSpringerJSONtoBibtex(JSONObject springerJsonEntry) {
// Fields that are directly accessible at the top level Json object
String[] singleFieldStrings = {FieldName.ISSN, FieldName.VOLUME, FieldName.ABSTRACT, FieldName.DOI, FieldName.TITLE, FieldName.NUMBER,
FieldName.PUBLISHER};
BibEntry entry = new BibEntry();
String nametype;
// Guess publication type
String isbn = springerJsonEntry.optString("isbn");
if (com.google.common.base.Strings.isNullOrEmpty(isbn)) {
// Probably article
entry.setType("article");
nametype = FieldName.JOURNAL;
} else {
// Probably book chapter or from proceeding, go for book chapter
entry.setType("incollection");
nametype = FieldName.BOOKTITLE;
entry.setField(FieldName.ISBN, isbn);
}
// Authors
if (springerJsonEntry.has("creators")) {
JSONArray authors = springerJsonEntry.getJSONArray("creators");
List<String> authorList = new ArrayList<>();
for (int i = 0; i < authors.length(); i++) {
if (authors.getJSONObject(i).has("creator")) {
authorList.add(authors.getJSONObject(i).getString("creator"));
} else {
LOGGER.info("Empty author name.");
}
}
entry.setField(FieldName.AUTHOR, String.join(" and ", authorList));
} else {
LOGGER.info("No author found.");
}
// Direct accessible fields
for (String field : singleFieldStrings) {
if (springerJsonEntry.has(field)) {
String text = springerJsonEntry.getString(field);
if (!text.isEmpty()) {
entry.setField(field, text);
}
}
}
// Page numbers
if (springerJsonEntry.has("startingPage") && !(springerJsonEntry.getString("startingPage").isEmpty())) {
if (springerJsonEntry.has("endPage") && !(springerJsonEntry.getString("endPage").isEmpty())) {
entry.setField(FieldName.PAGES,
springerJsonEntry.getString("startingPage") + "--" + springerJsonEntry.getString("endPage"));
} else {
entry.setField(FieldName.PAGES, springerJsonEntry.getString("startingPage"));
}
}
// Journal
if (springerJsonEntry.has("publicationName")) {
entry.setField(nametype, springerJsonEntry.getString("publicationName"));
}
// URL
if (springerJsonEntry.has("url")) {
JSONArray urlarray = springerJsonEntry.optJSONArray("url");
if (urlarray == null) {
entry.setField(FieldName.URL, springerJsonEntry.optString("url"));
} else {
entry.setField(FieldName.URL, urlarray.getJSONObject(0).optString("value"));
}
}
// Date
if (springerJsonEntry.has("publicationDate")) {
String date = springerJsonEntry.getString("publicationDate");
entry.setField(FieldName.DATE, date); // For biblatex
String[] dateparts = date.split("-");
entry.setField(FieldName.YEAR, dateparts[0]);
Optional<Month> month = Month.getMonthByNumber(Integer.parseInt(dateparts[1]));
month.ifPresent(entry::setMonth);
}
// Clean up abstract (often starting with Abstract)
entry.getField(FieldName.ABSTRACT).ifPresent(abstractContents -> {
if (abstractContents.startsWith("Abstract")) {
entry.setField(FieldName.ABSTRACT, abstractContents.substring(8));
}
});
return entry;
}
}