Project

General

Profile

1
package eu.dnetlib.data.utils;
2

    
3
import java.io.IOException;
4
import java.io.StringWriter;
5
import java.io.Writer;
6
import java.util.Collection;
7
import java.util.regex.Matcher;
8
import java.util.regex.Pattern;
9
import java.util.stream.Collectors;
10

    
11
import org.apache.commons.lang3.StringUtils;
12
import org.apache.commons.logging.Log;
13
import org.apache.commons.logging.LogFactory;
14
import org.jbibtex.BibTeXDatabase;
15
import org.jbibtex.BibTeXEntry;
16
import org.jbibtex.BibTeXFormatter;
17
import org.jbibtex.Key;
18
import org.jbibtex.StringValue;
19
import org.jbibtex.StringValue.Style;
20

    
21
import eu.dnetlib.data.mdstore.plugins.objects.Author;
22
import eu.dnetlib.data.mdstore.plugins.objects.MdRecord;
23

    
24
public class BibTexConverter {
25

    
26
	private static final Log log = LogFactory.getLog(BibTexConverter.class);
27

    
28
	public static String asBibTex(final MdRecord record) {
29
		try {
30

    
31
			final BibTeXEntry dbEntry = new BibTeXEntry(findBibTexType(record.getType()), new Key(record.getId()));
32

    
33
			addSimpleStringValue(dbEntry, BibTeXEntry.KEY_TITLE, record.getTitle());
34
			addMultipleAuthorValue(dbEntry, BibTeXEntry.KEY_AUTHOR, record.getCreators());
35
			addSimpleStringValue(dbEntry, BibTeXEntry.KEY_PUBLISHER, record.getPublisher());
36
			addMultipleStringValue(dbEntry, BibTeXEntry.KEY_DOI, record.getDois());
37

    
38
			addSourceAndDate(dbEntry, record);
39

    
40
			final BibTeXFormatter formatter = new BibTeXFormatter();
41
			final Writer res = new StringWriter();
42
			final BibTeXDatabase db = new BibTeXDatabase();
43
			db.addObject(dbEntry);
44
			formatter.format(db, res);
45
			return res.toString();
46
		} catch (final IOException e) {
47
			log.warn("Error generating bibtex", e);
48
			return "";
49
		}
50
	}
51

    
52
	private static void addSimpleStringValue(final BibTeXEntry dbEntry, final Key key, final Object value) {
53
		if ((value != null) && StringUtils.isNotBlank(value.toString())) {
54
			dbEntry.addField(key, new StringValue(escapeString(value.toString()), Style.BRACED));
55
		}
56
	}
57

    
58
	private static void addMultipleStringValue(final BibTeXEntry dbEntry, final Key key, final Collection<String> list) {
59
		final String val = list.stream()
60
				.map(String::trim)
61
				.filter(StringUtils::isNotBlank)
62
				.map(BibTexConverter::escapeString)
63
				.collect(Collectors.joining(" and "));
64

    
65
		if (StringUtils.isNotBlank(val)) {
66
			dbEntry.addField(key, new StringValue(val, Style.BRACED));
67
		}
68
	}
69

    
70
	private static void addMultipleAuthorValue(final BibTeXEntry dbEntry, final Key key, final Collection<Author> list) {
71
		final String val = list.stream()
72
				.map(Author::getName)
73
				.map(String::trim)
74
				.filter(StringUtils::isNotBlank)
75
				.map(BibTexConverter::escapeString)
76
				.collect(Collectors.joining(" and "));
77

    
78
		if (StringUtils.isNotBlank(val)) {
79
			dbEntry.addField(key, new StringValue(val, Style.BRACED));
80
		}
81
	}
82

    
83
	private static String escapeString(final String s) {
84
		return s.replaceAll("&", "\\\\&");
85
	}
86

    
87
	private static void addSourceAndDate(final BibTeXEntry dbEntry, final MdRecord record) {
88
		String year = Integer.toString(record.getDate());
89

    
90
		if (record.getSource() != null) {
91
			switch (record.getType().toLowerCase()) {
92
			case "conference article":
93
			case "contribution to conference":
94
				addSimpleStringValue(dbEntry, BibTeXEntry.KEY_BOOKTITLE, record.getSource());
95
				break;
96
			case "contribution to book":
97
				addSimpleStringValue(dbEntry, BibTeXEntry.KEY_BOOKTITLE, record.getSource());
98
				break;
99
			case "report":
100
				addSimpleStringValue(dbEntry, BibTeXEntry.KEY_INSTITUTION, record.getSource());
101
				break;
102
			case "journal article":
103
				final String regex = "^(.+) (\\d*) \\((\\d{4})\\)(: (\\d+\\–?\\d*))?";
104
				final Pattern pattern = Pattern.compile(regex);
105
				final Matcher matcher = pattern.matcher(record.getSource());
106

    
107
				if (matcher.find()) {
108
					if (matcher.groupCount() >= 1) {
109
						addSimpleStringValue(dbEntry, BibTeXEntry.KEY_JOURNAL, matcher.group(1));
110
					}
111
					if (matcher.groupCount() >= 2) {
112
						addSimpleStringValue(dbEntry, BibTeXEntry.KEY_VOLUME, matcher.group(2));
113
					}
114
					if (matcher.groupCount() >= 3) {
115
						year = matcher.group(3);
116
					}
117
					if (matcher.groupCount() >= 5) {
118
						addSimpleStringValue(dbEntry, BibTeXEntry.KEY_PAGES, matcher.group(5));
119
					}
120
				}
121
				break;
122
			case "patent":
123
				addSimpleStringValue(dbEntry, BibTeXEntry.KEY_HOWPUBLISHED, record.getSource());
124
				break;
125
			}
126
		}
127

    
128
		addSimpleStringValue(dbEntry, BibTeXEntry.KEY_YEAR, year);
129
	}
130

    
131
	private static Key findBibTexType(final String resourceType) {
132
		switch (resourceType.toLowerCase()) {
133
		case "conference article":
134
		case "contribution to conference":
135
			return BibTeXEntry.TYPE_INPROCEEDINGS;
136
		case "report":
137
			return BibTeXEntry.TYPE_TECHREPORT;
138
		case "journal article":
139
			return BibTeXEntry.TYPE_ARTICLE;
140
		case "other":
141
			return BibTeXEntry.TYPE_MISC;
142
		case "contribution to book":
143
			return BibTeXEntry.TYPE_INBOOK;
144
		case "book":
145
			return BibTeXEntry.TYPE_BOOK;
146
		case "bachelor thesis":
147
			return BibTeXEntry.TYPE_MASTERSTHESIS;
148
		case "doctoral thesis":
149
			return BibTeXEntry.TYPE_PHDTHESIS;
150
		case "patent":
151
			return BibTeXEntry.TYPE_MISC;
152
		case "master thesis":
153
			return BibTeXEntry.TYPE_MASTERSTHESIS;
154
		default:
155
			return BibTeXEntry.TYPE_MISC;
156
		}
157
	}
158
}
(1-1/5)