Skip to content

Commit 2ac5335

Browse files
ror3dSiedlerchr
andauthored
Improve citation relations (#11016)
* Collect DOI and publication type from semantich scholar to be able to expand the information of the new entries later by search through DOI * Include abstract in the request. This lets the GUI show the abstract since that was implemented already. Refactor api request string since most of it is shared * Add button to open the relation paper's DOI URL. Fix DOI for some ArXiv entries. * Don't show the open link button if there is no link to open. * Make field value null error a bit more useful * Include SemanticScholar url in the request and use it as the URL field. * Add changes to changelog * Change tooltip text to an existing, more informative one * Run rewriter to fix pull request * improve url optional handling --------- Co-authored-by: Siedlerchr <siedlerkiller@gmail.com>
1 parent a902524 commit 2ac5335

File tree

5 files changed

+130
-20
lines changed

5 files changed

+130
-20
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv
4949
- We enhanced the dialog for adding new fields in the content selector with a selection box containing a list of standard fields. [#10912](https://github.com/JabRef/jabref/pull/10912)
5050
- We store the citation relations in an LRU cache to avoid bloating the memory and out-of-memory exceptions. [#10958](https://github.com/JabRef/jabref/issues/10958)
5151
- Keywords filed are now displayed as tags. [#10910](https://github.com/JabRef/jabref/pull/10910)
52+
- Citation relations now get more information, and have quick access to view the articles in a browser without adding them to the library [#10869](https://github.com/JabRef/jabref/issues/10869)
5253

5354
### Fixed
5455

src/main/java/org/jabref/gui/entryeditor/citationrelationtab/CitationRelationsTab.java

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package org.jabref.gui.entryeditor.citationrelationtab;
22

3+
import java.io.IOException;
4+
import java.net.URI;
35
import java.util.Arrays;
46
import java.util.List;
57
import java.util.stream.Collectors;
@@ -28,6 +30,7 @@
2830
import org.jabref.gui.Globals;
2931
import org.jabref.gui.LibraryTab;
3032
import org.jabref.gui.StateManager;
33+
import org.jabref.gui.desktop.JabRefDesktop;
3134
import org.jabref.gui.entryeditor.EntryEditorPreferences;
3235
import org.jabref.gui.entryeditor.EntryEditorTab;
3336
import org.jabref.gui.entryeditor.citationrelationtab.semanticscholar.CitationFetcher;
@@ -40,6 +43,9 @@
4043
import org.jabref.logic.l10n.Localization;
4144
import org.jabref.model.database.BibDatabaseContext;
4245
import org.jabref.model.entry.BibEntry;
46+
import org.jabref.model.entry.field.StandardField;
47+
import org.jabref.model.entry.identifier.DOI;
48+
import org.jabref.model.strings.StringUtil;
4349
import org.jabref.model.util.FileUpdateMonitor;
4450
import org.jabref.preferences.PreferencesService;
4551

@@ -201,6 +207,8 @@ private void styleFetchedListView(CheckListView<CitationRelationItem> listView)
201207
HBox hContainer = new HBox();
202208
hContainer.prefWidthProperty().bind(listView.widthProperty().subtract(25));
203209

210+
VBox vContainer = new VBox();
211+
204212
if (entry.isLocal()) {
205213
Button jumpTo = IconTheme.JabRefIcons.LINK.asButton();
206214
jumpTo.setTooltip(new Tooltip(Localization.lang("Jump to entry in library")));
@@ -211,7 +219,7 @@ private void styleFetchedListView(CheckListView<CitationRelationItem> listView)
211219
citingTask.cancel();
212220
citedByTask.cancel();
213221
});
214-
hContainer.getChildren().addAll(entryNode, separator, jumpTo);
222+
vContainer.getChildren().add(jumpTo);
215223
} else {
216224
ToggleButton addToggle = IconTheme.JabRefIcons.ADD.asToggleButton();
217225
addToggle.setTooltip(new Tooltip(Localization.lang("Select entry")));
@@ -224,8 +232,28 @@ private void styleFetchedListView(CheckListView<CitationRelationItem> listView)
224232
});
225233
addToggle.getStyleClass().add("addEntryButton");
226234
addToggle.selectedProperty().bindBidirectional(listView.getItemBooleanProperty(entry));
227-
hContainer.getChildren().addAll(entryNode, separator, addToggle);
235+
vContainer.getChildren().add(addToggle);
236+
}
237+
238+
if (entry.entry().getDOI().isPresent() || entry.entry().getField(StandardField.URL).isPresent()) {
239+
Button openWeb = IconTheme.JabRefIcons.OPEN_LINK.asButton();
240+
openWeb.setTooltip(new Tooltip(Localization.lang("Open URL or DOI")));
241+
openWeb.setOnMouseClicked(event -> {
242+
String url = entry.entry().getDOI().flatMap(DOI::getExternalURI).map(URI::toString)
243+
.or(() -> entry.entry().getField(StandardField.URL)).orElse("");
244+
if (StringUtil.isNullOrEmpty(url)) {
245+
return;
246+
}
247+
try {
248+
JabRefDesktop.openBrowser(url, preferencesService.getFilePreferences());
249+
} catch (IOException ex) {
250+
dialogService.notify(Localization.lang("Unable to open link."));
251+
}
252+
});
253+
vContainer.getChildren().addLast(openWeb);
228254
}
255+
256+
hContainer.getChildren().addAll(entryNode, separator, vContainer);
229257
hContainer.getStyleClass().add("entry-container");
230258

231259
return hContainer;
@@ -392,8 +420,6 @@ private void showNodes(Node... nodes) {
392420
Arrays.stream(nodes).forEach(node -> node.setVisible(true));
393421
}
394422

395-
// Absolute-phase phenomena in photoionization with few-cycle laser pulses
396-
397423
/**
398424
* Function to import selected entries to the database. Also writes the entries to import to the CITING/CITED field
399425
*

src/main/java/org/jabref/gui/entryeditor/citationrelationtab/semanticscholar/PaperDetails.java

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,28 @@
11
package org.jabref.gui.entryeditor.citationrelationtab.semanticscholar;
22

33
import java.util.List;
4+
import java.util.Map;
45
import java.util.stream.Collectors;
56

67
import org.jabref.model.entry.BibEntry;
78
import org.jabref.model.entry.field.StandardField;
9+
import org.jabref.model.entry.types.StandardEntryType;
10+
11+
import com.google.gson.annotations.SerializedName;
812

913
public class PaperDetails {
1014
private String paperId;
1115
private String title;
1216
private String year;
17+
18+
@SerializedName("abstract")
19+
private String abstr;
20+
private String url;
1321
private int citationCount;
1422
private int referenceCount;
1523
private List<AuthorResponse> authors;
24+
private List<String> publicationTypes;
25+
private Map<String, String> externalIds;
1626

1727
public String getPaperId() {
1828
return paperId;
@@ -38,6 +48,22 @@ public void setYear(String year) {
3848
this.year = year;
3949
}
4050

51+
public String getAbstract() {
52+
return abstr;
53+
}
54+
55+
public void setAbstract(String abstr) {
56+
this.abstr = abstr;
57+
}
58+
59+
public String getURL() {
60+
return url;
61+
}
62+
63+
public void setURL(String url) {
64+
this.url = url;
65+
}
66+
4167
public int getCitationCount() {
4268
return citationCount;
4369
}
@@ -58,6 +84,56 @@ public List<AuthorResponse> getAuthors() {
5884
return authors;
5985
}
6086

87+
public String getPublicationType() {
88+
if (publicationTypes == null || publicationTypes.isEmpty()) {
89+
return "Misc";
90+
}
91+
if (publicationTypes.contains("Conference")) {
92+
return "InProceedings";
93+
} else if (publicationTypes.contains("JournalArticle")) {
94+
return "Article";
95+
} else {
96+
return switch (publicationTypes.getFirst()) {
97+
case "Review" ->
98+
"Misc";
99+
case "CaseReport" ->
100+
"Report";
101+
case "ClinicalTrial" ->
102+
"Report";
103+
case "Dataset" ->
104+
"Dataset";
105+
case "Editorial" ->
106+
"Misc";
107+
case "LettersAndComments" ->
108+
"Misc";
109+
case "MetaAnalysis" ->
110+
"Article";
111+
case "News" ->
112+
"Misc";
113+
case "Study" ->
114+
"Article";
115+
case "Book" ->
116+
"Book";
117+
case "BookSection" ->
118+
"InBook";
119+
default ->
120+
"Misc";
121+
};
122+
}
123+
}
124+
125+
public String getDOI() {
126+
if (externalIds != null) {
127+
if (externalIds.containsKey("DOI")) {
128+
return externalIds.get("DOI");
129+
} else if (externalIds.containsKey("ArXiv")) {
130+
// Some ArXiv articles don't return the DOI, even though it's easy to obtain from the ArXiv ID
131+
return "10.48550/arXiv." + externalIds.get("ArXiv");
132+
}
133+
}
134+
return "";
135+
}
136+
61137
public BibEntry toBibEntry() {
62138
BibEntry bibEntry = new BibEntry();
63139
bibEntry.setField(StandardField.TITLE, getTitle());
@@ -70,6 +146,20 @@ public BibEntry toBibEntry() {
70146
.collect(Collectors.joining(" and "));
71147
bibEntry.setField(StandardField.AUTHOR, authors);
72148

149+
bibEntry.setType(StandardEntryType.valueOf(getPublicationType()));
150+
151+
if (getDOI() != null) {
152+
bibEntry.setField(StandardField.DOI, getDOI());
153+
}
154+
155+
if (getURL() != null) {
156+
bibEntry.setField(StandardField.URL, getURL());
157+
}
158+
159+
if (getAbstract() != null) {
160+
bibEntry.setField(StandardField.ABSTRACT, getAbstract());
161+
}
162+
73163
return bibEntry;
74164
}
75165

src/main/java/org/jabref/gui/entryeditor/citationrelationtab/semanticscholar/SemanticScholarFetcher.java

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,17 @@ public SemanticScholarFetcher(ImporterPreferences importerPreferences) {
2525
this.importerPreferences = importerPreferences;
2626
}
2727

28+
public String getAPIUrl(String entry_point, BibEntry entry) {
29+
return SEMANTIC_SCHOLAR_API + "paper/" + "DOI:" + entry.getDOI().orElseThrow().getDOI() + "/" + entry_point
30+
+ "?fields=" + "title,authors,year,citationCount,referenceCount,externalIds,publicationTypes,abstract,url"
31+
+ "&limit=1000";
32+
}
33+
2834
@Override
2935
public List<BibEntry> searchCitedBy(BibEntry entry) throws FetcherException {
3036
if (entry.getDOI().isPresent()) {
31-
StringBuilder urlBuilder = new StringBuilder(SEMANTIC_SCHOLAR_API)
32-
.append("paper/")
33-
.append("DOI:").append(entry.getDOI().get().getDOI())
34-
.append("/citations")
35-
.append("?fields=").append("title,authors,year,citationCount,referenceCount")
36-
.append("&limit=1000");
3737
try {
38-
URL citationsUrl = URI.create(urlBuilder.toString()).toURL();
38+
URL citationsUrl = URI.create(getAPIUrl("citations", entry)).toURL();
3939
URLDownload urlDownload = new URLDownload(citationsUrl);
4040

4141
String apiKey = getApiKey();
@@ -58,15 +58,8 @@ public List<BibEntry> searchCitedBy(BibEntry entry) throws FetcherException {
5858
@Override
5959
public List<BibEntry> searchCiting(BibEntry entry) throws FetcherException {
6060
if (entry.getDOI().isPresent()) {
61-
StringBuilder urlBuilder = new StringBuilder(SEMANTIC_SCHOLAR_API)
62-
.append("paper/")
63-
.append("DOI:").append(entry.getDOI().get().getDOI())
64-
.append("/references")
65-
.append("?fields=")
66-
.append("title,authors,year,citationCount,referenceCount")
67-
.append("&limit=1000");
6861
try {
69-
URL referencesUrl = URI.create(urlBuilder.toString()).toURL();
62+
URL referencesUrl = URI.create(getAPIUrl("references", entry)).toURL();
7063
URLDownload urlDownload = new URLDownload(referencesUrl);
7164
String apiKey = getApiKey();
7265
if (!apiKey.isEmpty()) {

src/main/java/org/jabref/model/entry/BibEntry.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -602,7 +602,7 @@ public void setField(Map<Field, String> fields) {
602602
*/
603603
public Optional<FieldChange> setField(Field field, String value, EntriesEventSource eventSource) {
604604
Objects.requireNonNull(field, "field name must not be null");
605-
Objects.requireNonNull(value, "field value must not be null");
605+
Objects.requireNonNull(value, "field value for field " + field.getName() + " must not be null");
606606
Objects.requireNonNull(eventSource, "field eventSource must not be null");
607607

608608
if (value.isEmpty()) {

0 commit comments

Comments
 (0)