package org.jabref.logic.importer.fileformat;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.regex.Pattern;
import org.jabref.logic.importer.Importer;
import org.jabref.logic.importer.ParserResult;
import org.jabref.logic.util.FileExtensions;
import org.jabref.model.entry.AuthorList;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.entry.FieldName;
/**
* Imports a SilverPlatter exported file. This is a poor format to parse,
* so it currently doesn't handle everything correctly.
*/
public class SilverPlatterImporter extends Importer {
private static final Pattern START_PATTERN = Pattern.compile("Record.*INSPEC.*");
@Override
public String getName() {
return "SilverPlatter";
}
@Override
public FileExtensions getExtensions() {
return FileExtensions.SILVER_PLATTER;
}
@Override
public String getDescription() {
return "Imports a SilverPlatter exported file.";
}
@Override
public boolean isRecognizedFormat(BufferedReader reader) throws IOException {
// This format is very similar to Inspec, so we have a two-fold strategy:
// If we see the flag signaling that it is an Inspec file, return false.
// This flag should appear above the first entry and prevent us from
// accepting the Inspec format. Then we look for the title entry.
String str;
while ((str = reader.readLine()) != null) {
if (START_PATTERN.matcher(str).find()) {
return false; // This is an Inspec file, so return false.
}
if ((str.length() >= 5) && "TI: ".equals(str.substring(0, 5))) {
return true;
}
}
return false;
}
@Override
public ParserResult importDatabase(BufferedReader reader) throws IOException {
List<BibEntry> bibitems = new ArrayList<>();
boolean isChapter = false;
String str;
StringBuilder sb = new StringBuilder();
while ((str = reader.readLine()) != null) {
if (str.length() < 2) {
sb.append("__::__").append(str);
} else {
sb.append("__NEWFIELD__").append(str);
}
}
String[] entries = sb.toString().split("__::__");
String type = "";
Map<String, String> h = new HashMap<>();
for (String entry : entries) {
if (entry.trim().length() < 6) {
continue;
}
h.clear();
String[] fields = entry.split("__NEWFIELD__");
for (String field : fields) {
if (field.length() < 6) {
continue;
}
String f3 = field.substring(0, 2);
String frest = field.substring(5);
if ("TI".equals(f3)) {
h.put(FieldName.TITLE, frest);
} else if ("AU".equals(f3)) {
if (frest.trim().endsWith("(ed)")) {
String ed = frest.trim();
ed = ed.substring(0, ed.length() - 4);
h.put(FieldName.EDITOR,
AuthorList.fixAuthorLastNameFirst(ed.replace(",-", ", ").replace(";", " and ")));
} else {
h.put(FieldName.AUTHOR,
AuthorList.fixAuthorLastNameFirst(frest.replace(",-", ", ").replace(";", " and ")));
}
} else if ("AB".equals(f3)) {
h.put(FieldName.ABSTRACT, frest);
} else if ("DE".equals(f3)) {
String kw = frest.replace("-;", ",").toLowerCase(Locale.ROOT);
h.put(FieldName.KEYWORDS, kw.substring(0, kw.length() - 1));
} else if ("SO".equals(f3)) {
int m = frest.indexOf('.');
if (m >= 0) {
String jr = frest.substring(0, m);
h.put(FieldName.JOURNAL, jr.replace("-", " "));
frest = frest.substring(m);
m = frest.indexOf(';');
if (m >= 5) {
String yr = frest.substring(m - 5, m).trim();
h.put(FieldName.YEAR, yr);
frest = frest.substring(m);
m = frest.indexOf(':');
int issueIndex = frest.indexOf('(');
int endIssueIndex = frest.indexOf(')');
if (m >= 0) {
String pg = frest.substring(m + 1).trim();
h.put(FieldName.PAGES, pg);
h.put(FieldName.VOLUME, frest.substring(1, issueIndex).trim());
h.put(FieldName.ISSUE, frest.substring(issueIndex + 1, endIssueIndex).trim());
}
}
}
} else if ("PB".equals(f3)) {
int m = frest.indexOf(':');
if (m >= 0) {
String jr = frest.substring(0, m);
h.put(FieldName.PUBLISHER, jr.replace("-", " ").trim());
frest = frest.substring(m);
m = frest.indexOf(", ");
if ((m + 2) < frest.length()) {
String yr = frest.substring(m + 2).trim();
try {
Integer.parseInt(yr);
h.put(FieldName.YEAR, yr);
} catch (NumberFormatException ex) {
// Let's assume that this wasn't a number, since it
// couldn't be parsed as an integer.
}
}
}
} else if ("AF".equals(f3)) {
h.put(FieldName.SCHOOL, frest.trim());
} else if ("DT".equals(f3)) {
frest = frest.trim();
if ("Monograph".equals(frest)) {
type = "book";
} else if (frest.startsWith("Dissertation")) {
type = "phdthesis";
} else if (frest.toLowerCase(Locale.ROOT).contains(FieldName.JOURNAL)) {
type = "article";
} else if ("Contribution".equals(frest) || "Chapter".equals(frest)) {
type = "incollection";
// This entry type contains page numbers and booktitle in the
// title field.
isChapter = true;
} else {
type = frest.replace(" ", "");
}
}
}
if (isChapter) {
String titleO = h.get(FieldName.TITLE);
if (titleO != null) {
String title = titleO.trim();
int inPos = title.indexOf("\" in ");
if (inPos > 1) {
h.put(FieldName.TITLE, title.substring(0, inPos));
}
}
}
BibEntry b = new BibEntry(type);
// create one here
b.setField(h);
bibitems.add(b);
}
return new ParserResult(bibitems);
}
}