Skip to content

Commit a7c37b4

Browse files
committed
Add JSpecify annotations to commons module.
Signed-off-by: Eric Bottard <[email protected]>
1 parent d281da4 commit a7c37b4

File tree

40 files changed

+337
-253
lines changed

40 files changed

+337
-253
lines changed

models/spring-ai-openai/src/test/java/org/springframework/ai/openai/vectorstore/SimplePersistentVectorStoreIT.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ void persist() {
7272

7373
}
7474

75-
public class ProductMetadataGenerator implements JsonMetadataGenerator {
75+
public static class ProductMetadataGenerator implements JsonMetadataGenerator {
7676

7777
@Override
7878
public Map<String, Object> generate(Map<String, Object> jsonMap) {

spring-ai-client-chat/src/main/java/org/springframework/ai/chat/evaluation/FactCheckingEvaluator.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,12 @@
1818

1919
import java.util.Collections;
2020

21+
import org.jspecify.annotations.Nullable;
22+
2123
import org.springframework.ai.chat.client.ChatClient;
2224
import org.springframework.ai.evaluation.EvaluationRequest;
2325
import org.springframework.ai.evaluation.EvaluationResponse;
2426
import org.springframework.ai.evaluation.Evaluator;
25-
import org.springframework.lang.Nullable;
2627
import org.springframework.util.Assert;
2728

2829
/**
@@ -148,9 +149,9 @@ public static FactCheckingEvaluator.Builder builder(ChatClient.Builder chatClien
148149

149150
public static final class Builder {
150151

151-
private ChatClient.Builder chatClientBuilder;
152+
private ChatClient.@Nullable Builder chatClientBuilder;
152153

153-
private String evaluationPrompt;
154+
private @Nullable String evaluationPrompt = DEFAULT_EVALUATION_PROMPT_TEXT;
154155

155156
private Builder() {
156157
}
@@ -166,6 +167,8 @@ public FactCheckingEvaluator.Builder evaluationPrompt(String evaluationPrompt) {
166167
}
167168

168169
public FactCheckingEvaluator build() {
170+
Assert.state(this.chatClientBuilder != null, "ChatClientBuilder cannot be null");
171+
Assert.state(this.evaluationPrompt != null, "EvaluationPrompt cannot be null");
169172
return new FactCheckingEvaluator(this.chatClientBuilder, this.evaluationPrompt);
170173
}
171174

spring-ai-client-chat/src/main/java/org/springframework/ai/chat/evaluation/RelevancyEvaluator.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,13 @@
1919
import java.util.Collections;
2020
import java.util.Map;
2121

22+
import org.jspecify.annotations.Nullable;
23+
2224
import org.springframework.ai.chat.client.ChatClient;
2325
import org.springframework.ai.chat.prompt.PromptTemplate;
2426
import org.springframework.ai.evaluation.EvaluationRequest;
2527
import org.springframework.ai.evaluation.EvaluationResponse;
2628
import org.springframework.ai.evaluation.Evaluator;
27-
import org.springframework.lang.Nullable;
2829
import org.springframework.util.Assert;
2930

3031
/**
@@ -93,9 +94,9 @@ public static Builder builder() {
9394

9495
public static final class Builder {
9596

96-
private ChatClient.Builder chatClientBuilder;
97+
private ChatClient.@Nullable Builder chatClientBuilder;
9798

98-
private PromptTemplate promptTemplate;
99+
private @Nullable PromptTemplate promptTemplate;
99100

100101
private Builder() {
101102
}
@@ -111,6 +112,7 @@ public Builder promptTemplate(PromptTemplate promptTemplate) {
111112
}
112113

113114
public RelevancyEvaluator build() {
115+
Assert.state(this.chatClientBuilder != null, "chatClientBuilder cannot be null");
114116
return new RelevancyEvaluator(this.chatClientBuilder, this.promptTemplate);
115117
}
116118

spring-ai-client-chat/src/main/java/org/springframework/ai/chat/package-info.java renamed to spring-ai-client-chat/src/main/java/org/springframework/ai/chat/evaluation/package-info.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2023-2024 the original author or authors.
2+
* Copyright 2023-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -28,4 +28,7 @@
2828
* functionalities, maintaining a clear boundary from other contexts within the AI domain.
2929
*/
3030

31-
package org.springframework.ai.chat;
31+
@NullMarked
32+
package org.springframework.ai.chat.evaluation;
33+
34+
import org.jspecify.annotations.NullMarked;

spring-ai-client-chat/src/test/java/org/springframework/ai/chat/evaluation/FactCheckingEvaluatorTests.java

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,21 +36,15 @@ class FactCheckingEvaluatorTests {
3636
@SuppressWarnings("deprecation")
3737
@Test
3838
void whenChatClientBuilderIsNullThenThrow() {
39-
assertThatThrownBy(() -> new FactCheckingEvaluator(null, null)).isInstanceOf(IllegalArgumentException.class)
40-
.hasMessageContaining("chatClientBuilder cannot be null");
41-
42-
assertThatThrownBy(() -> FactCheckingEvaluator.builder(null).build())
43-
.isInstanceOf(IllegalArgumentException.class)
44-
.hasMessageContaining("chatClientBuilder cannot be null");
39+
assertThatThrownBy(() -> FactCheckingEvaluator.builder(null).build()).isInstanceOf(IllegalStateException.class)
40+
.hasMessageContaining("ChatClientBuilder cannot be null");
4541
}
4642

4743
@SuppressWarnings("deprecation")
4844
@Test
4945
void whenEvaluationPromptIsNullThenUseDefaultEvaluationPromptText() {
50-
FactCheckingEvaluator evaluator = new FactCheckingEvaluator(ChatClient.builder(mock(ChatModel.class)), null);
51-
assertThat(evaluator).isNotNull();
52-
53-
evaluator = FactCheckingEvaluator.builder(ChatClient.builder(mock(ChatModel.class))).build();
46+
FactCheckingEvaluator evaluator = FactCheckingEvaluator.builder(ChatClient.builder(mock(ChatModel.class)))
47+
.build();
5448
assertThat(evaluator).isNotNull();
5549
}
5650

spring-ai-client-chat/src/test/java/org/springframework/ai/chat/evaluation/RelevancyEvaluatorTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ void whenChatClientBuilderIsNullThenThrow() {
3838
.hasMessageContaining("chatClientBuilder cannot be null");
3939

4040
assertThatThrownBy(() -> RelevancyEvaluator.builder().chatClientBuilder(null).build())
41-
.isInstanceOf(IllegalArgumentException.class)
41+
.isInstanceOf(IllegalStateException.class)
4242
.hasMessageContaining("chatClientBuilder cannot be null");
4343
}
4444

spring-ai-commons/src/main/java/org/springframework/ai/content/Content.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
import java.util.Map;
2020

21+
import org.jspecify.annotations.Nullable;
22+
2123
/**
2224
* Data structure that contains content and metadata. Common parent for the
2325
* {@link org.springframework.ai.document.Document} and the
@@ -33,7 +35,7 @@ public interface Content {
3335
* Get the content of the message.
3436
* @return the content of the message
3537
*/
36-
String getText();
38+
@Nullable String getText();
3739

3840
/**
3941
* Get the metadata associated with the content.

spring-ai-commons/src/main/java/org/springframework/ai/content/Media.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@
1919
import java.io.IOException;
2020
import java.net.URI;
2121

22+
import org.jspecify.annotations.Nullable;
23+
2224
import org.springframework.core.io.Resource;
23-
import org.springframework.lang.Nullable;
2425
import org.springframework.util.Assert;
2526
import org.springframework.util.MimeType;
2627

@@ -75,8 +76,7 @@ public class Media {
7576
* An Id of the media object, usually defined when the model returns a reference to
7677
* media it has been passed.
7778
*/
78-
@Nullable
79-
private final String id;
79+
private final @Nullable String id;
8080

8181
private final MimeType mimeType;
8282

@@ -195,8 +195,7 @@ public byte[] getDataAsByteArray() {
195195
* Get the media id
196196
* @return the media id
197197
*/
198-
@Nullable
199-
public String getId() {
198+
public @Nullable String getId() {
200199
return this.id;
201200
}
202201

@@ -209,13 +208,13 @@ public String getName() {
209208
*/
210209
public static final class Builder {
211210

212-
private String id;
211+
private @Nullable String id;
213212

214-
private MimeType mimeType;
213+
private @Nullable MimeType mimeType;
215214

216-
private Object data;
215+
private @Nullable Object data;
217216

218-
private String name;
217+
private @Nullable String name;
219218

220219
private Builder() {
221220
}
@@ -315,6 +314,8 @@ public Builder name(String name) {
315314
* @throws IllegalArgumentException if mimeType or data are null
316315
*/
317316
public Media build() {
317+
Assert.state(this.mimeType != null, "MimeType must not be null");
318+
Assert.state(this.data != null, "Data must not be null");
318319
return new Media(this.mimeType, this.data, this.id, this.name);
319320
}
320321

spring-ai-commons/src/main/java/org/springframework/ai/content/package-info.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,7 @@
1717
/**
1818
* Core observation abstractions.
1919
*/
20+
@NullMarked
2021
package org.springframework.ai.content;
22+
23+
import org.jspecify.annotations.NullMarked;

spring-ai-commons/src/main/java/org/springframework/ai/document/DefaultContentFormatter.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,9 @@ public String format(Document document, MetadataMode metadataMode) {
111111
.replace(TEMPLATE_VALUE_PLACEHOLDER, metadataEntry.getValue().toString()))
112112
.collect(Collectors.joining(this.metadataSeparator));
113113

114+
var text = document.getText() != null ? document.getText() : "";
114115
return this.textTemplate.replace(TEMPLATE_METADATA_STRING_PLACEHOLDER, metadataText)
115-
.replace(TEMPLATE_CONTENT_PLACEHOLDER, document.getText());
116+
.replace(TEMPLATE_CONTENT_PLACEHOLDER, text);
116117
}
117118

118119
/**

0 commit comments

Comments
 (0)