Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions jablib/src/main/java/org/jabref/logic/ai/AiPreferences.java
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@ public AiPreferences(boolean enableAi,
this.ragMaxResultsCount = new SimpleIntegerProperty(ragMaxResultsCount);
this.ragMinScore = new SimpleDoubleProperty(ragMinScore);

this.apiKeyChangeListener = () -> {
};

this.templates = Map.of(
AiTemplate.CHATTING_SYSTEM_MESSAGE, new SimpleStringProperty(templates.get(AiTemplate.CHATTING_SYSTEM_MESSAGE)),
AiTemplate.CHATTING_USER_MESSAGE, new SimpleStringProperty(templates.get(AiTemplate.CHATTING_USER_MESSAGE)),
Expand Down Expand Up @@ -550,14 +553,14 @@ public void apiKeyUpdated() {
}

public void setTemplate(AiTemplate aiTemplate, String template) {
templates.get(aiTemplate).set(template);
templateProperty(aiTemplate).set(template);
}

public String getTemplate(AiTemplate aiTemplate) {
return templates.get(aiTemplate).get();
return templateProperty(aiTemplate).get();
}

public StringProperty templateProperty(AiTemplate aiTemplate) {
return templates.get(aiTemplate);
return templates.getOrDefault(aiTemplate, new SimpleStringProperty(""));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ public EmbeddingSearchResult<TextSegment> search(EmbeddingSearchRequest request)
PriorityQueue<EmbeddingMatch<TextSegment>> matches = new PriorityQueue<>(comparator);

applyFilter(request.filter()).forEach(id -> {
EmbeddingRecord eRecord = embeddingsMap.get(id);
EmbeddingRecord eRecord = embeddingsMap.getOrDefault(id, new EmbeddingRecord(null, "", new float[0]));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could think about a NULL_OBJECT constant


double cosineSimilarity = CosineSimilarity.between(Embedding.from(eRecord.embeddingVector), request.queryEmbedding());
double score = RelevanceScore.fromCosineSimilarity(cosineSimilarity);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,15 @@ public void startRebuildingTask() {
predictorProperty.set(Optional.empty());

new UpdateEmbeddingModelTask(aiPreferences, predictorProperty)
.onSuccess(v -> {
.onSuccess(_ -> {
LOGGER.info("Embedding model was successfully updated");
errorWhileBuildingModel = "";
eventBus.post(new EmbeddingModelBuiltEvent());
})
.onFailure(e -> {
LOGGER.error("An error occurred while building the embedding model", e);
notificationService.notify(Localization.lang("An error occurred while building the embedding model"));
errorWhileBuildingModel = e.getMessage();
errorWhileBuildingModel = e.getMessage() == null ? "" : e.getMessage();
eventBus.post(new EmbeddingModelBuildingErrorEvent());
})
.executeWith(taskExecutor);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import org.h2.mvstore.MVStore;
import org.h2.mvstore.MVStoreException;
import org.jspecify.annotations.Nullable;
import org.jspecify.annotations.NonNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -17,7 +17,7 @@ public abstract class MVStoreBase implements AutoCloseable {

protected MVStore mvStore;

public MVStoreBase(@Nullable Path path, NotificationService dialogService) {
public MVStoreBase(@NonNull Path path, NotificationService dialogService) {
Path mvStorePath = path;

try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import org.jabref.logic.util.strings.StringUtil;
import org.jabref.model.http.SimpleHttpResponse;

import org.jspecify.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -18,10 +19,13 @@ public class FetcherException extends JabRefException {
private static final Pattern API_KEY_PATTERN = Pattern.compile("(?i)(?<" + API_KEY_PARAM_NAME + ">api|key|api[-_]?key)=[^&]*");
private static final String REDACTED_STRING = "[REDACTED]";

@Nullable
private final String url;

@Nullable
private final SimpleHttpResponse httpResponse;

public FetcherException(String url, SimpleHttpResponse httpResponse) {
public FetcherException(@Nullable String url, @Nullable SimpleHttpResponse httpResponse) {
// Empty string handled at org.jabref.logic.importer.FetcherException.getPrefix.
super("");
this.url = url;
Expand Down Expand Up @@ -87,7 +91,7 @@ public String getLocalizedMessage() {
}

String getRedactedUrl() {
return getRedactedUrl(url);
return getRedactedUrl(url == null ? "" : url);
}

public static String getRedactedUrl(String source) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public Parser getParser() {
} catch (ParserConfigurationException | IOException | SAXException e) {
Unchecked.throwChecked(new FetcherException("Issue with parsing link", e));
}
return null;
return List.of();
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ public List<BibEntry> performSearch(BaseQueryNode queryNode) throws FetcherExcep
html = getPage(url);
// ResearchGate's server blocks when too many request are made
if (!html.getElementsByClass("nova-legacy-v-publication-item__title").hasText()) {
throw new FetcherException(url, "Required HTML element not found", null);
throw new FetcherException(url, "Required HTML element not found", new IllegalStateException("Missing element"));
}
} catch (IOException e) {
throw new FetcherException(url, e);
Expand All @@ -230,11 +230,13 @@ public List<BibEntry> performSearch(BaseQueryNode queryNode) throws FetcherExcep
Elements sol = html.getElementsByClass("nova-legacy-v-publication-item__title");
List<String> urls = sol.select("a").eachAttr("href").stream()
.filter(stream -> stream.contains("publication/"))
.map(resultStream -> resultStream.substring(resultStream.indexOf("publication/") + 12, resultStream.indexOf("_")))
.map(resultStream -> resultStream.substring(
resultStream.indexOf("publication/") + 12,
resultStream.indexOf("_")))
.map(idStream -> SEARCH_FOR_BIB_ENTRY + idStream)
.map(this::getInputStream)
.filter(Objects::nonNull)
.map(stream -> stream.lines().collect(Collectors.joining(OS.NEWLINE)))
.flatMap(Optional::stream)
.map(reader -> reader.lines().collect(Collectors.joining(OS.NEWLINE)))
.toList();

List<BibEntry> list = new ArrayList<>();
Expand All @@ -251,14 +253,14 @@ public List<BibEntry> performSearch(BaseQueryNode queryNode) throws FetcherExcep
return list;
}

private BufferedReader getInputStream(String urlString) {
private Optional<BufferedReader> getInputStream(String urlString) {
try {
URL url = URLUtil.create(urlString);
return new BufferedReader(new InputStreamReader(url.openStream()));
return Optional.of(new BufferedReader(new InputStreamReader(url.openStream())));
} catch (IOException e) {
LOGGER.debug("Wrong URL", e);
return Optional.empty();
}
return null;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.jabref.model.study.Study;

import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -62,9 +63,12 @@ public class BibDatabaseContext {
/**
* The path where this database was last saved to.
*/
@Nullable
private Path path;

@Nullable
private DatabaseSynchronizer dbmsSynchronizer;
@Nullable
private CoarseChangeFilter dbmsListener;
private DatabaseLocation location;

Expand Down Expand Up @@ -223,10 +227,15 @@ private Path getFileDirectoryPath(String directory) {

// If this path is relative, we try to interpret it as relative to the file path of this BIB file:
return getDatabasePath()
.map(databaseFile -> databaseFile.getParent().resolve(path).normalize().toAbsolutePath())
.map(databaseFile -> Optional.ofNullable(databaseFile.getParent())
.orElse(Path.of(""))
.resolve(path)
.normalize()
.toAbsolutePath())
.orElse(path);
}

@Nullable
public DatabaseSynchronizer getDBMSSynchronizer() {
return this.dbmsSynchronizer;
}
Expand All @@ -250,7 +259,9 @@ public void convertToSharedDatabase(DatabaseSynchronizer dmbsSynchronizer) {

public void convertToLocalDatabase() {
if (dbmsListener != null && (location == DatabaseLocation.SHARED)) {
dbmsListener.unregisterListener(dbmsSynchronizer);
if (dbmsSynchronizer != null) {
dbmsListener.unregisterListener(dbmsSynchronizer);
}
dbmsListener.shutdown();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public enum StandardField implements Field {
DATE("date", FieldProperty.DATE),
DAY("day"),
DAYFILED("dayfiled"),
DOI("doi", "DOI", FieldProperty.VERBATIM, FieldProperty.IDENTIFIER),
DOI("doi", FieldProperty.VERBATIM, FieldProperty.IDENTIFIER),
EDITION("edition", FieldProperty.NUMERIC),
EDITOR("editor", FieldProperty.PERSON_NAMES),
EDITORA("editora", FieldProperty.PERSON_NAMES),
Expand Down Expand Up @@ -64,9 +64,9 @@ public enum StandardField implements Field {
IDS("ids", FieldProperty.MULTIPLE_ENTRY_LINK),
INSTITUTION("institution"),
INTRODUCTION("introduction", FieldProperty.PERSON_NAMES),
ISBN("isbn", "ISBN", FieldProperty.VERBATIM),
ISRN("isrn", "ISRN", FieldProperty.VERBATIM),
ISSN("issn", "ISSN", FieldProperty.VERBATIM),
ISBN("isbn", FieldProperty.VERBATIM),
ISRN("isrn", FieldProperty.VERBATIM),
ISSN("issn", FieldProperty.VERBATIM),
ISSUE("issue"),
ISSUETITLE("issuetitle"),
ISSUESUBTITLE("issuesubtitle"),
Expand Down Expand Up @@ -96,9 +96,9 @@ public enum StandardField implements Field {
PAGETOTAL("pagetotal", FieldProperty.NUMERIC),
PAGINATION("pagination", FieldProperty.PAGINATION),
PART("part"),
PDF("pdf", "PDF"),
PMID("pmid", "PMID", FieldProperty.NUMERIC, FieldProperty.IDENTIFIER),
PS("ps", "PS"),
PDF("pdf"),
PMID("pmid", FieldProperty.NUMERIC, FieldProperty.IDENTIFIER),
PS("ps"),
PUBLISHER("publisher"),
PUBSTATE("pubstate"),
PRIMARYCLASS("primaryclass"),
Expand All @@ -118,8 +118,8 @@ public enum StandardField implements Field {
TITLEADDON("titleaddon"),
TRANSLATOR("translator", FieldProperty.PERSON_NAMES),
TYPE("type"),
URI("uri", "URI", FieldProperty.EXTERNAL, FieldProperty.VERBATIM),
URL("url", "URL", FieldProperty.EXTERNAL, FieldProperty.VERBATIM),
URI("uri", FieldProperty.EXTERNAL, FieldProperty.VERBATIM),
URL("url", FieldProperty.EXTERNAL, FieldProperty.VERBATIM),
URLDATE("urldate", FieldProperty.DATE),
VENUE("venue"),
VERSION("version"),
Expand Down Expand Up @@ -152,7 +152,6 @@ public enum StandardField implements Field {
private static final Map<String, StandardField> NAME_TO_STANDARD_FIELD = new HashMap<>();

private final String name;
private final String displayName;
private final EnumSet<FieldProperty> properties;

static {
Expand All @@ -163,25 +162,11 @@ public enum StandardField implements Field {

StandardField(String name) {
this.name = name;
this.displayName = null;
this.properties = EnumSet.noneOf(FieldProperty.class);
}

StandardField(String name, String displayName) {
this.name = name;
this.displayName = displayName;
this.properties = EnumSet.noneOf(FieldProperty.class);
}

StandardField(String name, String displayName, FieldProperty first, FieldProperty... rest) {
this.name = name;
this.displayName = displayName;
this.properties = EnumSet.of(first, rest);
}

StandardField(String name, FieldProperty first, FieldProperty... rest) {
this.name = name;
this.displayName = null;
this.properties = EnumSet.of(first, rest);
}

Expand Down
Loading