diff --git a/CHANGELOG.md b/CHANGELOG.md index 23f76110599..912e581893b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,11 +26,11 @@ Note that this project **does not** adhere to [Semantic Versioning](http://semve - We changed the button label from "Return to JabRef" to "Return to library" to better indicate the purpose of the action. - We removed "last-search-date" from the SLR feature, because the last-search-date can be deducted from the git logs. - We reworked the External Changes Resolver dialog. [#9021](https://github.com/JabRef/jabref/pull/9021) - +- We reworked the Define study parameters dialog. [#9123](https://github.com/JabRef/jabref/pull/9123) ### Fixed -- We fixed an issue where the possibilty to generate a subdatabase from an aux file was writing empty files when called from the commandline [#9115](https://github.com/JabRef/jabref/issues/9115), [forum#3516](https://discourse.jabref.org/t/export-subdatabase-from-aux-file-on-macos-command-line/3516) +- We fixed an issue where the possibility to generate a subdatabase from an aux file was writing empty files when called from the commandline [#9115](https://github.com/JabRef/jabref/issues/9115), [forum#3516](https://discourse.jabref.org/t/export-subdatabase-from-aux-file-on-macos-command-line/3516) - We fixed the display of issue, number, eid and pages fields in the entry preview. [#8607](https://github.com/JabRef/jabref/pull/8607), [#8372](https://github.com/JabRef/jabref/issues/8372), [Koppor#514](https://github.com/koppor/jabref/issues/514), [forum#2390](https://discourse.jabref.org/t/unable-to-edit-my-bibtex-file-that-i-used-before-vers-5-1/2390), [forum#3462](https://discourse.jabref.org/t/jabref-5-6-need-help-with-export-from-jabref-to-microsoft-word-entry-preview-of-apa-7-not-rendering-correctly/3462) - We fixed the page ranges checker to detect article numbers in the pages field (used at [Check Integrity](https://docs.jabref.org/finding-sorting-and-cleaning-entries/checkintegrity)). [#8607](https://github.com/JabRef/jabref/pull/8607) - The [HtmlToLaTeXFormatter](https://docs.jabref.org/finding-sorting-and-cleaning-entries/saveactions#html-to-latex) keeps single `<` characters. diff --git a/src/main/java/org/jabref/gui/slr/ManageStudyDefinition.fxml b/src/main/java/org/jabref/gui/slr/ManageStudyDefinition.fxml index b6ea1d41f7a..297ee2c1318 100644 --- a/src/main/java/org/jabref/gui/slr/ManageStudyDefinition.fxml +++ b/src/main/java/org/jabref/gui/slr/ManageStudyDefinition.fxml @@ -2,7 +2,6 @@ - @@ -19,50 +18,86 @@ - +
- + - + - + - - + + - - + + - + - - + + - + @@ -70,32 +105,48 @@ - + - + - - + + - + @@ -103,35 +154,54 @@ - + - + - + - - + + - + @@ -139,33 +209,33 @@ - + - - + - + - + @@ -196,6 +277,11 @@
- - + +
diff --git a/src/main/java/org/jabref/gui/slr/ManageStudyDefinitionView.java b/src/main/java/org/jabref/gui/slr/ManageStudyDefinitionView.java index ce1c5f10e3e..ebd7e89619f 100644 --- a/src/main/java/org/jabref/gui/slr/ManageStudyDefinitionView.java +++ b/src/main/java/org/jabref/gui/slr/ManageStudyDefinitionView.java @@ -13,7 +13,6 @@ import javafx.scene.Node; import javafx.scene.control.Button; import javafx.scene.control.ButtonType; -import javafx.scene.control.ComboBox; import javafx.scene.control.Label; import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; @@ -22,6 +21,7 @@ import javafx.scene.control.cell.CheckBoxTableCell; import javafx.scene.control.cell.TextFieldTableCell; import javafx.scene.input.KeyCode; +import javafx.scene.input.MouseButton; import org.jabref.gui.DialogService; import org.jabref.gui.icon.IconTheme; @@ -29,23 +29,26 @@ import org.jabref.gui.util.BaseDialog; import org.jabref.gui.util.DirectoryDialogConfiguration; import org.jabref.gui.util.ValueTableCellFactory; -import org.jabref.gui.util.ViewModelListCellFactory; +import org.jabref.gui.util.ViewModelTableRowFactory; import org.jabref.logic.l10n.Localization; import org.jabref.model.study.Study; import org.jabref.preferences.PreferencesService; import com.airhacks.afterburner.views.ViewLoader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * This class controls the user interface of the study definition management dialog. The UI elements and their layout * are defined in the FXML file. */ public class ManageStudyDefinitionView extends BaseDialog { + private static final Logger LOGGER = LoggerFactory.getLogger(ManageStudyDefinitionView.class); + @FXML private TextField studyTitle; @FXML private TextField addAuthor; @FXML private TextField addResearchQuestion; @FXML private TextField addQuery; - @FXML private ComboBox databaseSelector; @FXML private TextField studyDirectory; @FXML private ButtonType saveButtonType; @@ -66,7 +69,6 @@ public class ManageStudyDefinitionView extends BaseDialog @FXML private TableView databaseTable; @FXML private TableColumn databaseEnabledColumn; @FXML private TableColumn databaseColumn; - @FXML private TableColumn databaseActionColumn; @Inject private DialogService dialogService; @Inject private PreferencesService prefs; @@ -80,7 +82,7 @@ public class ManageStudyDefinitionView extends BaseDialog /** * This can be used to either create new study objects or edit existing ones. * - * @param study null if a new study is created. Otherwise the study object to edit. + * @param study null if a new study is created. Otherwise, the study object to edit. * @param studyDirectory the directory where the study to edit is located (null if a new study is created) */ public ManageStudyDefinitionView(Study study, Path studyDirectory, Path workingDirectory) { @@ -118,11 +120,14 @@ private void setupSaveButton() { @FXML private void initialize() { - viewModel = new ManageStudyDefinitionViewModel( - study, - workingDirectory, - prefs.getImportFormatPreferences(), - prefs.getImporterPreferences()); + if (Objects.isNull(study)) { + viewModel = new ManageStudyDefinitionViewModel( + prefs.getImportFormatPreferences(), + prefs.getImporterPreferences()); + } else { + LOGGER.error("Not yet implemented"); + return; + } // Listen whether any databases are removed from selection -> Add back to the database selector studyTitle.textProperty().bindBidirectional(viewModel.titleProperty()); @@ -161,25 +166,24 @@ private void initQueriesTab() { } private void initDatabasesTab() { - new ViewModelListCellFactory().withText(StudyDatabaseItem::getName) - .install(databaseSelector); - databaseSelector.setItems(viewModel.getNonSelectedDatabases()); + new ViewModelTableRowFactory() + .withOnMouseClickedEvent((entry, event) -> { + if (event.getButton() == MouseButton.PRIMARY) { + entry.setEnabled(!entry.isEnabled()); + } + }) + .install(databaseTable); - setupCommonPropertiesForTables(databaseSelector, this::addDatabase, databaseColumn, databaseActionColumn); + databaseColumn.setReorderable(false); + databaseColumn.setCellFactory(TextFieldTableCell.forTableColumn()); databaseEnabledColumn.setResizable(false); databaseEnabledColumn.setReorderable(false); - databaseEnabledColumn.setCellValueFactory(param -> param.getValue().enabledProperty()); databaseEnabledColumn.setCellFactory(CheckBoxTableCell.forTableColumn(databaseEnabledColumn)); + databaseEnabledColumn.setCellValueFactory(param -> param.getValue().enabledProperty()); + databaseColumn.setEditable(false); databaseColumn.setCellValueFactory(param -> param.getValue().nameProperty()); - databaseActionColumn.setCellValueFactory(param -> param.getValue().nameProperty()); - new ValueTableCellFactory() - .withGraphic(item -> IconTheme.JabRefIcons.DELETE_ENTRY.getGraphicNode()) - .withTooltip(name -> Localization.lang("Remove")) - .withOnMouseClickedEvent(item -> evt -> - viewModel.removeDatabase(item)) - .install(databaseActionColumn); databaseTable.setItems(viewModel.getDatabases()); } @@ -231,14 +235,6 @@ private void addQuery() { addQuery.setText(""); } - /** - * Add selected entry from combobox, push onto database pop from nonselecteddatabase (combobox) - */ - @FXML - private void addDatabase() { - viewModel.addDatabase(databaseSelector.getSelectionModel().getSelectedItem()); - } - @FXML public void selectStudyDirectory() { DirectoryDialogConfiguration directoryDialogConfiguration = new DirectoryDialogConfiguration.Builder() diff --git a/src/main/java/org/jabref/gui/slr/ManageStudyDefinitionViewModel.java b/src/main/java/org/jabref/gui/slr/ManageStudyDefinitionViewModel.java index 01350ab64bb..3f87b2232c3 100644 --- a/src/main/java/org/jabref/gui/slr/ManageStudyDefinitionViewModel.java +++ b/src/main/java/org/jabref/gui/slr/ManageStudyDefinitionViewModel.java @@ -2,9 +2,10 @@ import java.nio.file.InvalidPathException; import java.nio.file.Path; -import java.util.Comparator; +import java.util.List; import java.util.Objects; import java.util.Optional; +import java.util.Set; import java.util.stream.Collectors; import javafx.beans.property.Property; @@ -17,6 +18,11 @@ import org.jabref.logic.importer.ImporterPreferences; import org.jabref.logic.importer.SearchBasedFetcher; import org.jabref.logic.importer.WebFetchers; +import org.jabref.logic.importer.fetcher.ACMPortalFetcher; +import org.jabref.logic.importer.fetcher.CompositeSearchBasedFetcher; +import org.jabref.logic.importer.fetcher.DBLPFetcher; +import org.jabref.logic.importer.fetcher.IEEE; +import org.jabref.logic.importer.fetcher.SpringerFetcher; import org.jabref.model.study.Study; import org.jabref.model.study.StudyDatabase; import org.jabref.model.study.StudyQuery; @@ -31,45 +37,69 @@ public class ManageStudyDefinitionViewModel { private static final Logger LOGGER = LoggerFactory.getLogger(ManageStudyDefinitionViewModel.class); + private static final Set DEFAULT_SELECTION = Set.of( + ACMPortalFetcher.FETCHER_NAME, + IEEE.FETCHER_NAME, + SpringerFetcher.FETCHER_NAME, + DBLPFetcher.FETCHER_NAME); + + private final StringProperty title = new SimpleStringProperty(); private final ObservableList authors = FXCollections.observableArrayList(); private final ObservableList researchQuestions = FXCollections.observableArrayList(); private final ObservableList queries = FXCollections.observableArrayList(); private final ObservableList databases = FXCollections.observableArrayList(); + // Hold the complement of databases for the selector - private final ObservableList nonSelectedDatabases = FXCollections.observableArrayList(); private final SimpleStringProperty directory = new SimpleStringProperty(); - private Study study; + /** + * Constructor for a new study + */ + public ManageStudyDefinitionViewModel(ImportFormatPreferences importFormatPreferences, + ImporterPreferences importerPreferences) { + databases.addAll(WebFetchers.getSearchBasedFetchers(importFormatPreferences, importerPreferences) + .stream() + .map(SearchBasedFetcher::getName) + // The user wants to select specific fetchers + // The fetcher summarizing ALL fetchers can be emulated by selecting ALL fetchers (which happens rarely when doing an SLR) + .filter(name -> !name.equals(CompositeSearchBasedFetcher.FETCHER_NAME)) + .map(name -> { + boolean enabled = DEFAULT_SELECTION.contains(name); + return new StudyDatabaseItem(name, enabled); + }) + .toList()); + } + + /** + * Constructor for an existing study + * + * @param study The study to initialize the UI from + * @param studyDirectory The path where the study resides + */ public ManageStudyDefinitionViewModel(Study study, Path studyDirectory, ImportFormatPreferences importFormatPreferences, ImporterPreferences importerPreferences) { - if (Objects.isNull(study)) { - computeNonSelectedDatabases(importFormatPreferences, importerPreferences); - return; - } - this.study = study; + // copy the content of the study object into the UI fields + authors.addAll(Objects.requireNonNull(study).getAuthors()); title.setValue(study.getTitle()); - authors.addAll(study.getAuthors()); researchQuestions.addAll(study.getResearchQuestions()); queries.addAll(study.getQueries().stream().map(StudyQuery::getQuery).toList()); - databases.addAll(study.getDatabases() - .stream() - .map(studyDatabase -> new StudyDatabaseItem(studyDatabase.getName(), studyDatabase.isEnabled())) - .toList()); - computeNonSelectedDatabases(importFormatPreferences, importerPreferences); - if (!Objects.isNull(studyDirectory)) { - this.directory.set(studyDirectory.toString()); - } - } - - private void computeNonSelectedDatabases(ImportFormatPreferences importFormatPreferences, ImporterPreferences importerPreferences) { - nonSelectedDatabases.addAll(WebFetchers.getSearchBasedFetchers(importFormatPreferences, importerPreferences) - .stream() - .map(SearchBasedFetcher::getName) - .map(s -> new StudyDatabaseItem(s, true)) - .filter(studyDatabase -> !databases.contains(studyDatabase)).toList()); + List studyDatabases = study.getDatabases(); + databases.addAll(WebFetchers.getSearchBasedFetchers(importFormatPreferences, importerPreferences) + .stream() + .map(SearchBasedFetcher::getName) + // The user wants to select specific fetchers + // The fetcher summarizing ALL fetchers can be emulated by selecting ALL fetchers (which happens rarely when doing an SLR) + .filter(name -> !name.equals(CompositeSearchBasedFetcher.FETCHER_NAME)) + .map(name -> { + boolean enabled = studyDatabases.contains(new StudyDatabase(name, true)); + return new StudyDatabaseItem(name, enabled); + }) + .toList()); + + this.directory.set(Objects.requireNonNull(studyDirectory).toString()); } public StringProperty getTitle() { @@ -96,10 +126,6 @@ public ObservableList getDatabases() { return databases; } - public ObservableList getNonSelectedDatabases() { - return nonSelectedDatabases; - } - public void addAuthor(String author) { if (author.isBlank()) { return; @@ -121,29 +147,18 @@ public void addQuery(String query) { queries.add(query); } - public void addDatabase(StudyDatabaseItem database) { - if (Objects.isNull(database)) { - return; - } - nonSelectedDatabases.remove(database); - if (!databases.contains(database)) { - databases.add(database); - } - } - public SlrStudyAndDirectory saveStudy() { - if (Objects.isNull(study)) { - study = new Study(); - } - study.setTitle(title.getValueSafe()); - study.setAuthors(authors); - study.setResearchQuestions(researchQuestions); - study.setQueries(queries.stream().map(StudyQuery::new).collect(Collectors.toList())); - study.setDatabases(databases.stream().map(studyDatabaseItem -> new StudyDatabase(studyDatabaseItem.getName(), studyDatabaseItem.isEnabled())).collect(Collectors.toList())); + Study study = new Study( + authors, + title.getValueSafe(), + researchQuestions, + queries.stream().map(StudyQuery::new).collect(Collectors.toList()), + databases.stream().map(studyDatabaseItem -> new StudyDatabase(studyDatabaseItem.getName(), studyDatabaseItem.isEnabled())).filter(StudyDatabase::isEnabled).collect(Collectors.toList())); Path studyDirectory = null; try { studyDirectory = Path.of(directory.getValueSafe()); - } catch (InvalidPathException e) { + } catch ( + InvalidPathException e) { LOGGER.error("Invalid path was provided: {}", directory); } return new SlrStudyAndDirectory(study, studyDirectory); @@ -153,20 +168,6 @@ public Property titleProperty() { return title; } - public void removeDatabase(String database) { - // If a database is added from the combo box it should be enabled by default - Optional correspondingDatabase = databases.stream().filter(studyDatabaseItem -> studyDatabaseItem.getName().equals(database)).findFirst(); - if (correspondingDatabase.isEmpty()) { - return; - } - StudyDatabaseItem databaseToRemove = correspondingDatabase.get(); - databases.remove(databaseToRemove); - databaseToRemove.setEnabled(true); - nonSelectedDatabases.add(databaseToRemove); - // Resort list - nonSelectedDatabases.sort(Comparator.comparing(StudyDatabaseItem::getName)); - } - public void setStudyDirectory(Optional studyRepositoryRoot) { getDirectory().setValue(studyRepositoryRoot.map(Path::toString).orElseGet(() -> getDirectory().getValueSafe())); } diff --git a/src/main/java/org/jabref/gui/slr/StudyDatabaseItem.java b/src/main/java/org/jabref/gui/slr/StudyDatabaseItem.java index 50ceda09143..c6c77eaaf31 100644 --- a/src/main/java/org/jabref/gui/slr/StudyDatabaseItem.java +++ b/src/main/java/org/jabref/gui/slr/StudyDatabaseItem.java @@ -1,16 +1,23 @@ package org.jabref.gui.slr; +import java.util.Objects; + import javafx.beans.property.BooleanProperty; import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; +import org.jabref.model.study.StudyDatabase; + +/** + * View representation of {@link StudyDatabase} + */ public class StudyDatabaseItem { private final StringProperty name; private final BooleanProperty enabled; public StudyDatabaseItem(String name, boolean enabled) { - this.name = new SimpleStringProperty(name); + this.name = new SimpleStringProperty(Objects.requireNonNull(name)); this.enabled = new SimpleBooleanProperty(enabled); } @@ -38,6 +45,14 @@ public BooleanProperty enabledProperty() { return enabled; } + @Override + public String toString() { + return "StudyDatabaseItem{" + + "name=" + name.get() + + ", enabled=" + enabled.get() + + '}'; + } + @Override public boolean equals(Object o) { if (this == o) { @@ -46,19 +61,12 @@ public boolean equals(Object o) { if (o == null || getClass() != o.getClass()) { return false; } - StudyDatabaseItem that = (StudyDatabaseItem) o; - - if (isEnabled() != that.isEnabled()) { - return false; - } - return getName() != null ? getName().equals(that.getName()) : that.getName() == null; + return Object.equals(getName(),that.getName()) && Object.equals(isEnabled(), that.isEnabled()); } @Override public int hashCode() { - int result = getName() != null ? getName().hashCode() : 0; - result = 31 * result + (isEnabled() ? 1 : 0); - return result; + return Objects.hash(getName(), isEnabled()); } } diff --git a/src/main/java/org/jabref/logic/importer/fetcher/ACMPortalFetcher.java b/src/main/java/org/jabref/logic/importer/fetcher/ACMPortalFetcher.java index 10ba0e1b1b4..5fd153a07f2 100644 --- a/src/main/java/org/jabref/logic/importer/fetcher/ACMPortalFetcher.java +++ b/src/main/java/org/jabref/logic/importer/fetcher/ACMPortalFetcher.java @@ -19,6 +19,8 @@ public class ACMPortalFetcher implements SearchBasedParserFetcher { + public static final String FETCHER_NAME = "ACM Portal"; + private static final String SEARCH_URL = "https://dl.acm.org/action/doSearch"; public ACMPortalFetcher() { @@ -28,7 +30,7 @@ public ACMPortalFetcher() { @Override public String getName() { - return "ACM Portal"; + return FETCHER_NAME; } @Override diff --git a/src/main/java/org/jabref/logic/importer/fetcher/CompositeSearchBasedFetcher.java b/src/main/java/org/jabref/logic/importer/fetcher/CompositeSearchBasedFetcher.java index 97506c284a6..bee6f3c7fc9 100644 --- a/src/main/java/org/jabref/logic/importer/fetcher/CompositeSearchBasedFetcher.java +++ b/src/main/java/org/jabref/logic/importer/fetcher/CompositeSearchBasedFetcher.java @@ -17,6 +17,8 @@ public class CompositeSearchBasedFetcher implements SearchBasedFetcher { + public static final String FETCHER_NAME = "SearchAll"; + private static final Logger LOGGER = LoggerFactory.getLogger(CompositeSearchBasedFetcher.class); private final Set fetchers; @@ -36,7 +38,7 @@ public CompositeSearchBasedFetcher(Set searchBasedFetchers, @Override public String getName() { - return "SearchAll"; + return FETCHER_NAME; } @Override diff --git a/src/main/java/org/jabref/logic/importer/fetcher/DBLPFetcher.java b/src/main/java/org/jabref/logic/importer/fetcher/DBLPFetcher.java index d961ce0b3bc..19d1d67ec1a 100644 --- a/src/main/java/org/jabref/logic/importer/fetcher/DBLPFetcher.java +++ b/src/main/java/org/jabref/logic/importer/fetcher/DBLPFetcher.java @@ -33,6 +33,7 @@ * @see Basic API documentation */ public class DBLPFetcher implements SearchBasedParserFetcher { + public static final String FETCHER_NAME = "DBLP"; private static final String BASIC_SEARCH_URL = "https://dblp.org/search/publ/api"; @@ -76,7 +77,7 @@ public void doPostCleanup(BibEntry entry) { @Override public String getName() { - return "DBLP"; + return FETCHER_NAME; } @Override diff --git a/src/main/java/org/jabref/logic/importer/fetcher/IEEE.java b/src/main/java/org/jabref/logic/importer/fetcher/IEEE.java index 3ca57ff3cbf..fe9860c3f44 100644 --- a/src/main/java/org/jabref/logic/importer/fetcher/IEEE.java +++ b/src/main/java/org/jabref/logic/importer/fetcher/IEEE.java @@ -48,9 +48,9 @@ */ public class IEEE implements FulltextFetcher, PagedSearchBasedParserFetcher, CustomizableKeyFetcher { - private static final Logger LOGGER = LoggerFactory.getLogger(IEEE.class); + public static final String FETCHER_NAME = "IEEEXplore"; - private static final String FETCHER_NAME = "IEEEXplore"; + private static final Logger LOGGER = LoggerFactory.getLogger(IEEE.class); private static final String STAMP_BASE_STRING_DOCUMENT = "/stamp/stamp.jsp?tp=&arnumber="; private static final Pattern STAMP_PATTERN = Pattern.compile("(/stamp/stamp.jsp\\?t?p?=?&?arnumber=[0-9]+)"); diff --git a/src/main/java/org/jabref/logic/importer/fetcher/SpringerFetcher.java b/src/main/java/org/jabref/logic/importer/fetcher/SpringerFetcher.java index d0aa60e4494..e1764120e14 100644 --- a/src/main/java/org/jabref/logic/importer/fetcher/SpringerFetcher.java +++ b/src/main/java/org/jabref/logic/importer/fetcher/SpringerFetcher.java @@ -40,13 +40,14 @@ */ public class SpringerFetcher implements PagedSearchBasedParserFetcher, CustomizableKeyFetcher { + public static final String FETCHER_NAME = "Springer"; + private static final Logger LOGGER = LoggerFactory.getLogger(SpringerFetcher.class); private static final String API_URL = "https://api.springernature.com/meta/v1/json"; private static final String API_KEY = new BuildInfo().springerNatureAPIKey; // Springer query using the parameter 'q=doi:10.1007/s11276-008-0131-4s=1' will respond faster private static final String TEST_URL_WITHOUT_API_KEY = "https://api.springernature.com/meta/v1/json?q=doi:10.1007/s11276-008-0131-4s=1&p=1&api_key="; - private static final String FETCHER_NAME = "Springer"; private final ImporterPreferences importerPreferences; diff --git a/src/main/java/org/jabref/logic/importer/fetcher/SpringerLink.java b/src/main/java/org/jabref/logic/importer/fetcher/SpringerLink.java index 78a7a420718..769e7f6c200 100644 --- a/src/main/java/org/jabref/logic/importer/fetcher/SpringerLink.java +++ b/src/main/java/org/jabref/logic/importer/fetcher/SpringerLink.java @@ -27,12 +27,13 @@ * Uses Springer API, see https://dev.springer.com */ public class SpringerLink implements FulltextFetcher { + public static final String FETCHER_NAME = "Springer"; + private static final Logger LOGGER = LoggerFactory.getLogger(SpringerLink.class); private static final String API_URL = "https://api.springer.com/meta/v1/json"; private static final String API_KEY = new BuildInfo().springerNatureAPIKey; private static final String CONTENT_HOST = "link.springer.com"; - private static final String FETCHER_NAME = "Springer"; private final ImporterPreferences importerPreferences; diff --git a/src/main/java/org/jabref/model/study/Study.java b/src/main/java/org/jabref/model/study/Study.java index 1c85a1d77c2..3748f0962bc 100644 --- a/src/main/java/org/jabref/model/study/Study.java +++ b/src/main/java/org/jabref/model/study/Study.java @@ -35,7 +35,7 @@ public Study(List authors, String title, List researchQuestions, /** * Used for Jackson deserialization */ - public Study() { + private Study() { } public List getAuthors() { diff --git a/src/main/java/org/jabref/model/study/StudyDatabase.java b/src/main/java/org/jabref/model/study/StudyDatabase.java index ac71a7160c2..375b59fb57c 100644 --- a/src/main/java/org/jabref/model/study/StudyDatabase.java +++ b/src/main/java/org/jabref/model/study/StudyDatabase.java @@ -1,5 +1,8 @@ package org.jabref.model.study; +/** + * data model for the view {@link org.jabref.gui.slr.StudyDatabaseItem} + */ public class StudyDatabase { private String name; private boolean enabled; diff --git a/src/main/resources/l10n/JabRef_en.properties b/src/main/resources/l10n/JabRef_en.properties index 6dff22b68d0..d020d8e5691 100644 --- a/src/main/resources/l10n/JabRef_en.properties +++ b/src/main/resources/l10n/JabRef_en.properties @@ -2406,7 +2406,7 @@ Database=Database Databases=Databases Manage\ study\ definition=Manage study definition Add\ Author\:=Add Author\: -Add\ Database\:=Add Database\: +Select\ Databases\:=Select the databases that should be searched\: Add\ Query\:=Add Query\: Add\ Research\ Question\:=Add Research Question\: Perform\ search\ for\ existing\ systematic\ literature\ review=Perform search for existing systematic literature review diff --git a/src/test/java/org/jabref/gui/slr/ManageStudyDefinitionViewModelTest.java b/src/test/java/org/jabref/gui/slr/ManageStudyDefinitionViewModelTest.java new file mode 100644 index 00000000000..f6f9d927909 --- /dev/null +++ b/src/test/java/org/jabref/gui/slr/ManageStudyDefinitionViewModelTest.java @@ -0,0 +1,98 @@ +package org.jabref.gui.slr; + +import java.nio.file.Path; +import java.util.List; + +import org.jabref.logic.bibtex.FieldContentFormatterPreferences; +import org.jabref.logic.importer.ImportFormatPreferences; +import org.jabref.logic.importer.ImporterPreferences; +import org.jabref.model.study.Study; +import org.jabref.model.study.StudyDatabase; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; +import org.mockito.Answers; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +class ManageStudyDefinitionViewModelTest { + private ImportFormatPreferences importFormatPreferences; + private ImporterPreferences importerPreferences; + + @BeforeEach + void setUp() { + // code taken from org.jabref.logic.importer.WebFetchersTest.setUp + importFormatPreferences = mock(ImportFormatPreferences.class, Answers.RETURNS_DEEP_STUBS); + importerPreferences = mock(ImporterPreferences.class); + FieldContentFormatterPreferences fieldContentFormatterPreferences = mock(FieldContentFormatterPreferences.class); + when(importFormatPreferences.getFieldContentFormatterPreferences()).thenReturn(fieldContentFormatterPreferences); + } + + @Test + public void emptyStudyConstructorFillsDatabasesCorrectly() { + ManageStudyDefinitionViewModel manageStudyDefinitionViewModel = new ManageStudyDefinitionViewModel(importFormatPreferences, importerPreferences); + assertEquals(List.of( + new StudyDatabaseItem("ACM Portal", true), + new StudyDatabaseItem("ArXiv", false), + new StudyDatabaseItem("Biodiversity Heritage", false), + new StudyDatabaseItem("CiteSeerX", false), + new StudyDatabaseItem("Collection of Computer Science Bibliographies", false), + new StudyDatabaseItem("Crossref", false), + new StudyDatabaseItem("DBLP", true), + new StudyDatabaseItem("DOAB", false), + new StudyDatabaseItem("DOAJ", false), + new StudyDatabaseItem("GVK", false), + new StudyDatabaseItem("IEEEXplore", true), + new StudyDatabaseItem("INSPIRE", false), + new StudyDatabaseItem("MathSciNet", false), + new StudyDatabaseItem("Medline/PubMed", false), + new StudyDatabaseItem("ResearchGate", false), + new StudyDatabaseItem("SAO/NASA ADS", false), + new StudyDatabaseItem("SemanticScholar", false), + new StudyDatabaseItem("Springer", true), + new StudyDatabaseItem("zbMATH", false) + ), manageStudyDefinitionViewModel.getDatabases()); + } + + @Test + public void studyConstructorFillsDatabasesCorrectly(@TempDir Path tempDir) { + List databases = List.of( + new StudyDatabase("ACM Portal", true)); + Study study = new Study( + List.of("Name"), + "title", + List.of("Q1"), + List.of(), + databases + ); + ManageStudyDefinitionViewModel manageStudyDefinitionViewModel = new ManageStudyDefinitionViewModel( + study, + tempDir, + importFormatPreferences, + importerPreferences); + assertEquals(List.of( + new StudyDatabaseItem("ACM Portal", true), + new StudyDatabaseItem("ArXiv", false), + new StudyDatabaseItem("Biodiversity Heritage", false), + new StudyDatabaseItem("CiteSeerX", false), + new StudyDatabaseItem("Collection of Computer Science Bibliographies", false), + new StudyDatabaseItem("Crossref", false), + new StudyDatabaseItem("DBLP", false), + new StudyDatabaseItem("DOAB", false), + new StudyDatabaseItem("DOAJ", false), + new StudyDatabaseItem("GVK", false), + new StudyDatabaseItem("IEEEXplore", false), + new StudyDatabaseItem("INSPIRE", false), + new StudyDatabaseItem("MathSciNet", false), + new StudyDatabaseItem("Medline/PubMed", false), + new StudyDatabaseItem("ResearchGate", false), + new StudyDatabaseItem("SAO/NASA ADS", false), + new StudyDatabaseItem("SemanticScholar", false), + new StudyDatabaseItem("Springer", false), + new StudyDatabaseItem("zbMATH", false) + ), manageStudyDefinitionViewModel.getDatabases()); + } +}