Skip to content

Commit

Permalink
Merge branch 'main' into postgresql
Browse files Browse the repository at this point in the history
  • Loading branch information
LoayGhreeb committed Sep 30, 2024
2 parents 51f1655 + a47b338 commit 3cbac93
Show file tree
Hide file tree
Showing 62 changed files with 244 additions and 161 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pr-comment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:
token: ${{ secrets.GITHUB_TOKEN }}
- name: jbang
if: ${{ steps.read-pr_number.outputs.pr_number != '' }}
uses: jbangdev/jbang-action@v0.118.0
uses: jbangdev/jbang-action@v0.119.0
with:
script: ghprcomment@koppor/ghprcomment
scriptargs: "-r JabRef/jabref -p ${{ steps.read-pr_number.outputs.pr_number }} -w ${{ github.event.workflow_run.id }}"
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,12 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv
- ⚠️ Renamed command line parameters `embeddBibfileInPdf` to `embedBibFileInPdf`, `writeMetadatatoPdf` to `writeMetadataToPdf`, and `writeXMPtoPdf` to `writeXmpToPdf`. [#11575](https://github.com/JabRef/jabref/pull/11575)
- The browse button for a Custom theme now opens in the directory of the current used CSS file. [#11597](https://github.com/JabRef/jabref/pull/11597)
- The browse button for a Custom exporter now opens in the directory of the current used exporter file. [#11717](https://github.com/JabRef/jabref/pull/11717)
- JabRef now uses TLS 1.2 for all HTTPS connections. [#11852](https://github.com/JabRef/jabref/pull/11852)
- We improved the display of long messages in the integrity check dialog. [#11619](https://github.com/JabRef/jabref/pull/11619)
- We improved the undo/redo buttons in the main toolbar and main menu to be disabled when there is nothing to undo/redo. [#8807](https://github.com/JabRef/jabref/issues/8807)
- We improved the DOI detection in PDF imports. [#11782](https://github.com/JabRef/jabref/pull/11782)
- We improved the performance when pasting and importing entries in an existing library. [#11843](https://github.com/JabRef/jabref/pull/11843)
- When fulltext search is selected but indexing is deactivated, a dialog is now shown asking if the user wants to enable indexing now [#9491](https://github.com/JabRef/jabref/issues/9491)

### Fixed

Expand All @@ -73,6 +75,7 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv
- We fixed an issue where search result highlighting was incorrectly highlighting the boolean operators. [#11595](https://github.com/JabRef/jabref/issues/11595)
- We fixed an issue where search result highlighting was broken at complex searches. [#8067](https://github.com/JabRef/jabref/issues/8067)
- We fixed an exception when searching for unlinked files. [#11731](https://github.com/JabRef/jabref/issues/11731)
- We fixed an issue with the link to the full text at the BVB fetcher. [#11852](https://github.com/JabRef/jabref/pull/11852)
- We fixed an issue where two contradicting notifications were shown when cutting an entry in the main table. [#11724](https://github.com/JabRef/jabref/pull/11724)
- We fixed an issue where unescaped braces in the arXiv fetcher were not treated. [#11704](https://github.com/JabRef/jabref/issues/11704)
- We fixed an issue where HTML instead of the fulltext pdf was downloaded when importing arXiv entries. [#4913](https://github.com/JabRef/jabref/issues/4913)
Expand Down
10 changes: 5 additions & 5 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ dependencies {
implementation 'org.jsoup:jsoup:1.18.1'
implementation 'com.konghq:unirest-java-core:4.4.4'
implementation 'com.konghq:unirest-modules-gson:4.4.4'
implementation 'org.apache.httpcomponents.client5:httpclient5:5.3.1'
implementation 'org.apache.httpcomponents.client5:httpclient5:5.4'
// endregion

implementation 'org.slf4j:slf4j-api:2.0.16'
Expand Down Expand Up @@ -336,7 +336,7 @@ dependencies {
exclude group: 'com.squareup.retrofit2', module: 'retrofit'
exclude group: 'org.jetbrains.kotlin'
}
implementation('dev.langchain4j:langchain4j-mistral-ai:0.34.0') {
implementation('dev.langchain4j:langchain4j-mistral-ai:0.35.0') {
exclude group: 'com.squareup.okhttp3'
exclude group: 'com.squareup.retrofit2', module: 'retrofit'
exclude group: 'org.jetbrains.kotlin'
Expand All @@ -345,7 +345,7 @@ dependencies {
exclude group: 'com.squareup.okhttp3'
exclude group: 'com.squareup.retrofit2', module: 'retrofit'
}
implementation('dev.langchain4j:langchain4j-hugging-face:0.34.0') {
implementation('dev.langchain4j:langchain4j-hugging-face:0.35.0') {
exclude group: 'com.squareup.okhttp3'
exclude group: 'com.squareup.retrofit2', module: 'retrofit'
exclude group: 'org.jetbrains.kotlin'
Expand Down Expand Up @@ -373,11 +373,11 @@ dependencies {
implementation 'io.zonky.test:embedded-postgres:2.0.7'
implementation enforcedPlatform('io.zonky.test.postgres:embedded-postgres-binaries-bom:17.0.0')

testImplementation 'io.github.classgraph:classgraph:4.8.175'
testImplementation 'io.github.classgraph:classgraph:4.8.176'
testImplementation 'org.junit.jupiter:junit-jupiter:5.11.0'
testImplementation 'org.junit.platform:junit-platform-launcher:1.10.3'

testImplementation 'org.mockito:mockito-core:5.13.0'
testImplementation 'org.mockito:mockito-core:5.14.1'
testImplementation 'org.xmlunit:xmlunit-core:2.10.0'
testImplementation 'org.xmlunit:xmlunit-matchers:2.10.0'
testRuntimeOnly 'com.tngtech.archunit:archunit-junit5-engine:1.3.0'
Expand Down
2 changes: 2 additions & 0 deletions rewrite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ recipeList:
- org.openrewrite.java.migrate.io.ReplaceFileInOrOutputStreamFinalizeWithClose
- org.openrewrite.java.migrate.net.JavaNetAPIs
- org.openrewrite.java.migrate.net.URLConstructorsToURIRecipes
- org.openrewrite.java.migrate.util.OptionalNotEmptyToIsPresent
- org.openrewrite.java.migrate.util.OptionalNotPresentToIsEmpty
- org.openrewrite.java.migrate.util.SequencedCollection
- org.openrewrite.java.migrate.lang.StringFormatted

Expand Down
27 changes: 15 additions & 12 deletions src/main/java/org/jabref/Launcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -172,26 +172,29 @@ private static void initLogging(String[] args) {
/**
* @return true if JabRef should continue starting up, false if it should quit.
*/
private static boolean handleMultipleAppInstances(String[] args, RemotePreferences remotePreferences) {
private static boolean handleMultipleAppInstances(String[] args, RemotePreferences remotePreferences) throws InterruptedException {
LOGGER.trace("Checking for remote handling...");
if (remotePreferences.useRemoteServer()) {
// Try to contact already running JabRef
RemoteClient remoteClient = new RemoteClient(remotePreferences.getPort());
if (remoteClient.ping()) {
LOGGER.debug("Pinging other instance succeeded.");
// We are not alone, there is already a server out there, send command line
// arguments to other instance
LOGGER.debug("Passing arguments passed on to running JabRef...");
if (remoteClient.sendCommandLineArguments(args)) {
// So we assume it's all taken care of, and quit.
// Output to both to the log and the screen. Therefore, we do not have an additional System.out.println.
LOGGER.info("Arguments passed on to running JabRef instance. Shutting down.");
return false;
if (args.length == 0) {
// There is already a server out there, avoid showing log "Passing arguments" while no arguments are provided.
LOGGER.warn("This JabRef instance is already running. Please switch to that instance.");
} else {
LOGGER.warn("Could not communicate with other running JabRef instance.");
// We do not launch a new instance in presence of an error
return false;
// We are not alone, there is already a server out there, send command line arguments to other instance
LOGGER.debug("Passing arguments passed on to running JabRef...");
if (remoteClient.sendCommandLineArguments(args)) {
// So we assume it's all taken care of, and quit.
// Output to both to the log and the screen. Therefore, we do not have an additional System.out.println.
LOGGER.info("Arguments passed on to running JabRef instance. Shutting down.");
} else {
LOGGER.warn("Could not communicate with other running JabRef instance.");
}
}
// We do not launch a new instance in presence if there is another instance running
return false;
} else {
LOGGER.debug("Could not ping JabRef instance.");
}
Expand Down
4 changes: 3 additions & 1 deletion src/main/java/org/jabref/gui/JabRefGUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,9 @@ public void stopBackgroundTasks() {

public static void shutdownThreadPools() {
LOGGER.trace("Shutting down taskExecutor");
taskExecutor.shutdown();
if (taskExecutor != null) {
taskExecutor.shutdown();
}
LOGGER.trace("Shutting down fileUpdateMonitor");
fileUpdateMonitor.shutdown();
LOGGER.trace("Shutting down directoryMonitor");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ protected SequencedSet<Field> determineFieldsToShow(BibEntry entry) {
BibDatabaseMode mode = databaseContext.getMode();
Optional<BibEntryType> entryType = entryTypesManager.enrich(entry.getType(), mode);
if (entryType.isPresent()) {
return entryType.get().getDeprecatedFields(mode).stream().filter(field -> !entry.getField(field).isEmpty()).collect(Collectors.toCollection(LinkedHashSet::new));
return entryType.get().getDeprecatedFields(mode).stream().filter(field -> entry.getField(field).isPresent()).collect(Collectors.toCollection(LinkedHashSet::new));
} else {
// Entry type unknown -> treat all fields as required (thus no optional fields)
return new LinkedHashSet<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public String getAPIUrl(String entry_point, BibEntry entry) {

@Override
public List<BibEntry> searchCitedBy(BibEntry entry) throws FetcherException {
if (!entry.getDOI().isPresent()) {
if (entry.getDOI().isEmpty()) {
return List.of();
}

Expand All @@ -59,7 +59,7 @@ public List<BibEntry> searchCitedBy(BibEntry entry) throws FetcherException {

@Override
public List<BibEntry> searchCiting(BibEntry entry) throws FetcherException {
if (!entry.getDOI().isPresent()) {
if (entry.getDOI().isEmpty()) {
return List.of();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,7 @@
import java.util.List;
import java.util.Optional;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLSocketFactory;

import javafx.beans.property.DoubleProperty;
import javafx.beans.property.ReadOnlyDoubleProperty;
Expand Down Expand Up @@ -243,8 +240,6 @@ private boolean checkSSLHandshake(URLDownload urlDownload) {
}

private BackgroundTask<Path> prepareDownloadTask(Path targetDirectory, URLDownload urlDownload) {
SSLSocketFactory defaultSSLSocketFactory = HttpsURLConnection.getDefaultSSLSocketFactory();
HostnameVerifier defaultHostnameVerifier = HttpsURLConnection.getDefaultHostnameVerifier();
return BackgroundTask
.wrap(() -> {
String suggestedName;
Expand All @@ -263,7 +258,6 @@ private BackgroundTask<Path> prepareDownloadTask(Path targetDirectory, URLDownlo
.then(destination -> new FileDownloadTask(urlDownload.getSource(), destination))
.onFailure(ex -> LOGGER.error("Error in download", ex))
.onFinished(() -> {
URLDownload.setSSLVerification(defaultSSLSocketFactory, defaultHostnameVerifier);
downloadProgress.unbind();
downloadProgress.set(1);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@
import java.util.Optional;
import java.util.stream.Collectors;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSocketFactory;

import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ListProperty;
import javafx.beans.property.ObjectProperty;
Expand Down Expand Up @@ -217,15 +213,10 @@ public void checkCustomApiKey() {
if (!apiKey.isEmpty()) {
URLDownload urlDownload;
try {
SSLSocketFactory defaultSslSocketFactory = HttpsURLConnection.getDefaultSSLSocketFactory();
HostnameVerifier defaultHostnameVerifier = HttpsURLConnection.getDefaultHostnameVerifier();

urlDownload = new URLDownload(testUrlWithoutApiKey + apiKey);
// The HEAD request cannot be used because its response is not 200 (maybe 404 or 596...).
int statusCode = ((HttpURLConnection) urlDownload.getSource().openConnection()).getResponseCode();
keyValid = (statusCode >= 200) && (statusCode < 300);

URLDownload.setSSLVerification(defaultSslSocketFactory, defaultHostnameVerifier);
} catch (IOException | UnirestException e) {
keyValid = false;
}
Expand Down
52 changes: 43 additions & 9 deletions src/main/java/org/jabref/gui/search/GlobalSearchBar.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import org.jabref.architecture.AllowedToUseClassGetResource;
import org.jabref.gui.ClipBoardManager;
import org.jabref.gui.DialogService;
import org.jabref.gui.LibraryTab;
import org.jabref.gui.LibraryTabContainer;
import org.jabref.gui.StateManager;
import org.jabref.gui.autocompleter.AppendPersonNamesStrategy;
Expand All @@ -57,6 +58,7 @@
import org.jabref.gui.util.BindingsHelper;
import org.jabref.gui.util.TooltipTextUtil;
import org.jabref.gui.util.UiTaskExecutor;
import org.jabref.logic.FilePreferences;
import org.jabref.logic.l10n.Localization;
import org.jabref.logic.preferences.AutoCompleteFirstNameMode;
import org.jabref.logic.search.SearchPreferences;
Expand Down Expand Up @@ -96,6 +98,7 @@ public class GlobalSearchBar extends HBox {
private final DialogService dialogService;
private final BooleanProperty globalSearchActive = new SimpleBooleanProperty(false);
private final BooleanProperty illegalSearch = new SimpleBooleanProperty(false);
private final FilePreferences filePreferences;
private GlobalSearchResultDialog globalSearchResultDialog;
private final SearchType searchType;

Expand All @@ -109,6 +112,7 @@ public GlobalSearchBar(LibraryTabContainer tabContainer,
this.stateManager = stateManager;
this.preferences = preferences;
this.searchPreferences = preferences.getSearchPreferences();
this.filePreferences = preferences.getFilePreferences();
this.undoManager = undoManager;
this.dialogService = dialogService;
this.tabContainer = tabContainer;
Expand Down Expand Up @@ -151,7 +155,10 @@ public GlobalSearchBar(LibraryTabContainer tabContainer,
if (keyBindingRepository.matches(event, KeyBinding.CLEAR_SEARCH)) {
searchField.clear();
if (searchType == SearchType.NORMAL_SEARCH) {
tabContainer.getCurrentLibraryTab().getMainTable().requestFocus();
LibraryTab currentLibraryTab = tabContainer.getCurrentLibraryTab();
if (currentLibraryTab != null) {
currentLibraryTab.getMainTable().requestFocus();
}
}
event.consume();
}
Expand Down Expand Up @@ -231,32 +238,59 @@ public GlobalSearchBar(LibraryTabContainer tabContainer,
}

private void initSearchModifierButtons() {
fulltextButton.setSelected(searchPreferences.isFulltext());
fulltextButton.setTooltip(new Tooltip(Localization.lang("Fulltext search")));
initSearchModifierButton(fulltextButton);

EasyBind.subscribe(filePreferences.fulltextIndexLinkedFilesProperty(), enabled -> {
if (!enabled) {
fulltextButton.setSelected(false);
} else if (searchPreferences.isFulltext()) {
fulltextButton.setSelected(true);
}
});

fulltextButton.selectedProperty().addListener((obs, oldVal, newVal) -> {
searchPreferences.setSearchFlag(SearchFlags.FULLTEXT, newVal);
if (!filePreferences.shouldFulltextIndexLinkedFiles() && newVal) {
boolean enableFulltextSearch = dialogService.showConfirmationDialogAndWait(Localization.lang("Fulltext search"), Localization.lang("Fulltext search requires the setting 'Automatically index all linked files for fulltext search' to be enabled. Do you want to enable indexing now?"), Localization.lang("Enable indexing"), Localization.lang("Keep disabled"));

LibraryTab libraryTab = tabContainer.getCurrentLibraryTab();
if (libraryTab != null && enableFulltextSearch) {
filePreferences.setFulltextIndexLinkedFiles(true);
searchPreferences.setSearchFlag(SearchFlags.FULLTEXT, true);
}
if (!enableFulltextSearch) {
fulltextButton.setSelected(false);
searchPreferences.setSearchFlag(SearchFlags.FULLTEXT, false);
}
} else {
searchPreferences.setSearchFlag(SearchFlags.FULLTEXT, newVal);
}
searchField.requestFocus();
updateSearchQuery();
});

keepSearchString.setSelected(searchPreferences.shouldKeepSearchString());
keepSearchString.setTooltip(new Tooltip(Localization.lang("Keep search string across libraries")));
initSearchModifierButton(keepSearchString);
keepSearchString.selectedProperty().addListener((obs, oldVal, newVal) -> searchPreferences.setKeepSearchString(newVal));
keepSearchString.selectedProperty().addListener((obs, oldVal, newVal) -> {
searchPreferences.setKeepSearchString(newVal);
searchField.requestFocus();
});

filterModeButton.setSelected(searchPreferences.getSearchDisplayMode() == SearchDisplayMode.FILTER);
filterModeButton.setTooltip(new Tooltip(Localization.lang("Filter search results")));
initSearchModifierButton(filterModeButton);
filterModeButton.setOnAction(event -> searchPreferences.setSearchDisplayMode(filterModeButton.isSelected() ? SearchDisplayMode.FILTER : SearchDisplayMode.FLOAT));
filterModeButton.setOnAction(event -> {
searchPreferences.setSearchDisplayMode(filterModeButton.isSelected() ? SearchDisplayMode.FILTER : SearchDisplayMode.FLOAT);
searchField.requestFocus();
});

openGlobalSearchButton.disableProperty().bindBidirectional(globalSearchActive);
openGlobalSearchButton.setTooltip(new Tooltip(Localization.lang("Search across libraries in a new window")));
initSearchModifierButton(openGlobalSearchButton);
openGlobalSearchButton.setOnAction(evt -> openGlobalSearchDialog());

searchPreferences.getObservableSearchFlags().addListener((SetChangeListener.Change<? extends SearchFlags> change) -> {
fulltextButton.setSelected(searchPreferences.isFulltext());
});
searchPreferences.getObservableSearchFlags().addListener((SetChangeListener.Change<? extends SearchFlags> change) -> fulltextButton.setSelected(searchPreferences.isFulltext()));
}

public void openGlobalSearchDialog() {
Expand All @@ -268,7 +302,7 @@ public void openGlobalSearchDialog() {
globalSearchResultDialog = new GlobalSearchResultDialog(undoManager, tabContainer);
}
stateManager.activeSearchQuery(SearchType.NORMAL_SEARCH).get().ifPresent(query ->
stateManager.activeSearchQuery(SearchType.GLOBAL_SEARCH).set(Optional.of(query)));
stateManager.activeSearchQuery(SearchType.GLOBAL_SEARCH).set(Optional.of(query)));
updateSearchQuery();
dialogService.showCustomDialogAndWait(globalSearchResultDialog);
globalSearchActive.setValue(false);
Expand Down
Loading

0 comments on commit 3cbac93

Please sign in to comment.