-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Add a new field for citation count #13531
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
dcc6076
1a76c57
aaef2ce
150bc2c
fe6b48d
23fbd53
b37475d
f4fa327
1193823
44de54c
05aa416
15baed1
19923b8
db2ffd2
cd836e7
a90024c
9c3facb
84af44f
1d265d3
8bfc988
83709c9
4333732
18f9de0
91c8c62
0cf3850
e4fdd97
e1928d8
18e51bd
d12e8e4
1f7f5cf
ba09528
25e3649
4e0c1af
1accb7c
85190f9
371f9f6
3074fde
41deb2b
fa1297f
4f1250d
49d6d47
827b4a7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
package org.jabref.gui.fieldeditors; | ||
|
||
import javax.swing.undo.UndoManager; | ||
|
||
import javafx.fxml.FXML; | ||
import javafx.scene.Parent; | ||
import javafx.scene.control.Button; | ||
import javafx.scene.control.Tooltip; | ||
import javafx.scene.layout.HBox; | ||
|
||
import org.jabref.gui.DialogService; | ||
import org.jabref.gui.StateManager; | ||
import org.jabref.gui.autocompleter.SuggestionProvider; | ||
import org.jabref.gui.fieldeditors.contextmenu.DefaultMenu; | ||
import org.jabref.gui.preferences.GuiPreferences; | ||
import org.jabref.logic.citation.SearchCitationsRelationsService; | ||
import org.jabref.logic.integrity.FieldCheckers; | ||
import org.jabref.logic.l10n.Localization; | ||
import org.jabref.logic.util.TaskExecutor; | ||
import org.jabref.model.entry.BibEntry; | ||
import org.jabref.model.entry.field.Field; | ||
|
||
import com.airhacks.afterburner.injection.Injector; | ||
import com.airhacks.afterburner.views.ViewLoader; | ||
import jakarta.inject.Inject; | ||
|
||
public class CitationCountEditor extends HBox implements FieldEditorFX { | ||
@FXML private CitationCountEditorViewModel viewModel; | ||
@FXML private EditorTextField textField; | ||
@FXML private Button fetchCitationCountButton; | ||
|
||
@Inject private DialogService dialogService; | ||
@Inject private GuiPreferences preferences; | ||
@Inject private UndoManager undoManager; | ||
@Inject private TaskExecutor taskExecutor; | ||
@Inject private StateManager stateManager; | ||
@Inject private SearchCitationsRelationsService searchCitationsRelationsService; | ||
|
||
public CitationCountEditor(Field field, | ||
SuggestionProvider<?> suggestionProvider, | ||
FieldCheckers fieldCheckers) { | ||
Injector.registerExistingAndInject(this); | ||
this.viewModel = new CitationCountEditorViewModel( | ||
field, | ||
suggestionProvider, | ||
fieldCheckers, | ||
taskExecutor, | ||
dialogService, | ||
undoManager, | ||
stateManager, | ||
preferences, | ||
searchCitationsRelationsService); | ||
|
||
ViewLoader.view(this) | ||
.root(this) | ||
.load(); | ||
|
||
textField.textProperty().bindBidirectional(viewModel.textProperty()); | ||
|
||
fetchCitationCountButton.setTooltip( | ||
new Tooltip(Localization.lang("Look up %0", field.getDisplayName()))); | ||
textField.initContextMenu(new DefaultMenu(textField), preferences.getKeyBindingRepository()); | ||
new EditorValidator(preferences).configureValidation(viewModel.getFieldValidator().getValidationStatus(), textField); | ||
} | ||
|
||
@FXML | ||
private void fetchCitationCount() { | ||
viewModel.getCitationCount(); | ||
} | ||
|
||
public CitationCountEditorViewModel getViewModel() { | ||
return viewModel; | ||
} | ||
|
||
@Override | ||
public void bindToEntry(BibEntry entry) { | ||
viewModel.bindToEntry(entry); | ||
} | ||
|
||
@Override | ||
public Parent getNode() { | ||
return this; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package org.jabref.gui.fieldeditors; | ||
|
||
import java.util.Optional; | ||
|
||
import javax.swing.undo.UndoManager; | ||
|
||
import javafx.beans.property.BooleanProperty; | ||
import javafx.beans.property.SimpleBooleanProperty; | ||
|
||
import org.jabref.gui.DialogService; | ||
import org.jabref.gui.StateManager; | ||
import org.jabref.gui.autocompleter.SuggestionProvider; | ||
import org.jabref.gui.preferences.GuiPreferences; | ||
import org.jabref.logic.citation.SearchCitationsRelationsService; | ||
import org.jabref.logic.integrity.FieldCheckers; | ||
import org.jabref.logic.l10n.Localization; | ||
import org.jabref.logic.util.BackgroundTask; | ||
import org.jabref.logic.util.TaskExecutor; | ||
import org.jabref.model.entry.field.Field; | ||
|
||
public class CitationCountEditorViewModel extends AbstractEditorViewModel { | ||
protected final BooleanProperty fetchCitationCountInProgress = new SimpleBooleanProperty(false); | ||
private final TaskExecutor taskExecutor; | ||
private final DialogService dialogService; | ||
private final UndoManager undoManager; | ||
private final StateManager stateManager; | ||
private final GuiPreferences preferences; | ||
SalvadorRomo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
private final SearchCitationsRelationsService searchCitationsRelationsService; | ||
public CitationCountEditorViewModel( | ||
Field field, | ||
SuggestionProvider<?> suggestionProvider, | ||
FieldCheckers fieldCheckers, | ||
TaskExecutor taskExecutor, | ||
DialogService dialogService, | ||
UndoManager undoManager, | ||
StateManager stateManager, | ||
GuiPreferences preferences, | ||
SearchCitationsRelationsService searchCitationsRelationsService) { | ||
super(field, suggestionProvider, fieldCheckers, undoManager); | ||
this.taskExecutor = taskExecutor; | ||
this.dialogService = dialogService; | ||
this.undoManager = undoManager; | ||
this.stateManager = stateManager; | ||
this.preferences = preferences; | ||
this.searchCitationsRelationsService = searchCitationsRelationsService; | ||
} | ||
|
||
public BooleanProperty fetchCitationCountInProgressProperty() { | ||
return fetchCitationCountInProgress; | ||
} | ||
|
||
public boolean getFetchCitationCountInProgress() { | ||
return fetchCitationCountInProgress.get(); | ||
} | ||
|
||
public void getCitationCount() { | ||
Optional<String> fieldAux = entry.getField(field); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
BackgroundTask.wrap(() -> searchCitationsRelationsService.getCitationCount(this.entry, fieldAux)) | ||
.onRunning(() -> fetchCitationCountInProgress.setValue(true)) | ||
.onFinished(() -> fetchCitationCountInProgress.setValue(false)) | ||
.onFailure(e -> | ||
dialogService.showErrorDialogAndWait(Localization.lang("Error Occurred"))) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not JabRef's style. The text does not contain any information what the user should do.
With 3, there is a log entry, and users can see it in the log viewer accessible in the help menu. |
||
.onSuccess(identifier -> { | ||
entry.setField(field, String.valueOf(identifier)); | ||
}).executeWith(taskExecutor); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
|
||
<?import javafx.scene.control.Button?> | ||
<?import javafx.scene.control.ProgressIndicator?> | ||
<?import javafx.scene.control.Tooltip?> | ||
<?import javafx.scene.layout.HBox?> | ||
<?import javafx.scene.layout.StackPane?> | ||
<?import org.jabref.gui.fieldeditors.EditorTextField?> | ||
<?import org.jabref.gui.icon.JabRefIconView?> | ||
<fx:root xmlns:fx="http://javafx.com/fxml/1" type="HBox" xmlns="http://javafx.com/javafx/8.0.112" | ||
fx:controller="org.jabref.gui.fieldeditors.CitationCountEditor"> | ||
<EditorTextField fx:id="textField" prefHeight="0.0" HBox.hgrow="ALWAYS"/> | ||
<Button fx:id="fetchCitationCountButton" onAction="#fetchCitationCount" styleClass="icon-button"> | ||
<graphic> | ||
<StackPane> | ||
<JabRefIconView glyph="LOOKUP_IDENTIFIER" | ||
visible="${controller.viewModel.fetchCitationCountInProgress == false}"/> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use |
||
<ProgressIndicator maxHeight="12.0" maxWidth="12.0" | ||
visible="${controller.viewModel.fetchCitationCountInProgress}"/> | ||
</StackPane> | ||
</graphic> | ||
</Button> | ||
</fx:root> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,10 @@ | ||
package org.jabref.logic.importer.fetcher.citation; | ||
|
||
import java.util.List; | ||
import java.util.Optional; | ||
|
||
import org.jabref.logic.importer.FetcherException; | ||
import org.jabref.logic.importer.fetcher.citation.semanticscholar.PaperDetails; | ||
import org.jabref.model.entry.BibEntry; | ||
|
||
/** | ||
|
@@ -40,6 +42,14 @@ enum SearchType { | |
*/ | ||
List<BibEntry> searchCiting(BibEntry entry) throws FetcherException; | ||
|
||
/** | ||
* Get the paper details that includes citation count field for a given {@link BibEntry}. | ||
koppor marked this conversation as resolved.
Show resolved
Hide resolved
|
||
* | ||
* @param entry entry to search citation count field | ||
* @return returns a {@link PaperDetails}, that includes citation count field (may be empty) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ajdust JavaDoc to actual return value (Integer is not PaperDetails) |
||
*/ | ||
Optional<Integer> searchCitationCount(BibEntry entry) throws FetcherException; | ||
|
||
/** | ||
* Returns the localized name of this fetcher. | ||
* The title can be used to display the fetcher in the menu and in the side pane. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,7 @@ | |
import java.net.MalformedURLException; | ||
import java.net.URL; | ||
import java.util.List; | ||
import java.util.Optional; | ||
|
||
import org.jabref.logic.importer.FetcherException; | ||
import org.jabref.logic.importer.ImporterPreferences; | ||
|
@@ -33,6 +34,12 @@ public String getAPIUrl(String entry_point, BibEntry entry) { | |
+ "&limit=1000"; | ||
} | ||
|
||
public String getUrlForCitationCount(BibEntry entry) { | ||
return SEMANTIC_SCHOLAR_API + "paper/" + "DOI:" + entry.getDOI().orElseThrow().asString() | ||
+ "?fields=" + "citationCount" | ||
+ "&limit=1"; | ||
} | ||
|
||
@Override | ||
public List<BibEntry> searchCitedBy(BibEntry entry) throws FetcherException { | ||
if (entry.getDOI().isEmpty()) { | ||
|
@@ -84,6 +91,27 @@ public List<BibEntry> searchCitedBy(BibEntry entry) throws FetcherException { | |
.map(referenceDataItem -> referenceDataItem.getCitedPaper().toBibEntry()).toList(); | ||
} | ||
|
||
@Override | ||
public Optional<Integer> searchCitationCount(BibEntry entry) throws FetcherException { | ||
if (entry.getDOI().isEmpty()) { | ||
return Optional.empty(); | ||
} | ||
URL referencesUrl; | ||
try { | ||
referencesUrl = URLUtil.create(getUrlForCitationCount(entry)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Variable name 'referencesUrl' is misleading as it's used for citation count URL, not references. This reduces code readability and maintainability. |
||
} catch (MalformedURLException e) { | ||
throw new FetcherException("Malformed URL", e); | ||
} | ||
URLDownload urlDownload = new URLDownload(referencesUrl); | ||
importerPreferences.getApiKey(getName()).ifPresent(apiKey -> urlDownload.addHeader("x-api-key", apiKey)); | ||
PaperDetails paperDetails = GSON.fromJson(urlDownload.asString(), PaperDetails.class); | ||
|
||
if (paperDetails == null) { | ||
return Optional.empty(); | ||
} | ||
return Optional.of(paperDetails.getCitationCount()); | ||
koppor marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
@Override | ||
public String getName() { | ||
return FETCHER_NAME; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -138,6 +138,7 @@ public enum StandardField implements Field { | |
OWNER("owner"), | ||
TIMESTAMP("timestamp", FieldProperty.DATE), | ||
CREATIONDATE("creationdate", FieldProperty.DATE), | ||
CITATIONCOUNT("Citation count"), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Move at the end - the two fields before and the one after is related to date - this one not. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Made this change, but seems to impact the open office tests, seems the order of this contstants impact how the output will be in files, so don't konw what you think about it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please show the excerpt here. I think, you ened to adapt (And please let us resolve the conversations so that we save one click while reviewing) - otherwise, I need to open all resolved conversations) |
||
MODIFICATIONDATE("modificationdate", FieldProperty.DATE); | ||
|
||
public static final Set<Field> AUTOMATIC_FIELDS = Set.of(OWNER, TIMESTAMP, CREATIONDATE, MODIFICATIONDATE); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using Swing components in a JavaFX application violates the architectural decision to use only JavaFX. The UndoManager should be replaced with a JavaFX-specific implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
JabRef uses this - which is OK.