Add nullability annotations to module/spring-boot-ldap

See gh-46587
This commit is contained in:
Moritz Halbritter
2025-08-04 11:27:41 +02:00
parent 30e7d1eb80
commit 97ad5cb204
12 changed files with 78 additions and 43 deletions
@@ -16,6 +16,8 @@
package org.springframework.boot.ldap.autoconfigure;
import org.jspecify.annotations.Nullable;
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails;
/**
@@ -36,7 +38,7 @@ public interface LdapConnectionDetails extends ConnectionDetails {
* Base suffix from which all operations should originate.
* @return base suffix
*/
default String getBase() {
default @Nullable String getBase() {
return null;
}
@@ -44,7 +46,7 @@ public interface LdapConnectionDetails extends ConnectionDetails {
* Login username of the server.
* @return login username
*/
default String getUsername() {
default @Nullable String getUsername() {
return null;
}
@@ -52,7 +54,7 @@ public interface LdapConnectionDetails extends ConnectionDetails {
* Login password of the server.
* @return login password
*/
default String getPassword() {
default @Nullable String getPassword() {
return null;
}
@@ -19,6 +19,8 @@ package org.springframework.boot.ldap.autoconfigure;
import java.util.HashMap;
import java.util.Map;
import org.jspecify.annotations.Nullable;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.core.env.Environment;
import org.springframework.ldap.ReferralException;
@@ -40,34 +42,34 @@ public class LdapProperties {
/**
* LDAP URLs of the server.
*/
private String[] urls;
private String @Nullable [] urls;
/**
* Base suffix from which all operations should originate.
*/
private String base;
private @Nullable String base;
/**
* Login username of the server.
*/
private String username;
private @Nullable String username;
/**
* Login password of the server.
*/
private String password;
private @Nullable String password;
/**
* Whether read-only operations should use an anonymous environment. Disabled by
* default unless a username is set.
*/
private Boolean anonymousReadOnly;
private @Nullable Boolean anonymousReadOnly;
/**
* Specify how referrals encountered by the service provider are to be processed. If
* not specified, the default is determined by the provider.
*/
private Referral referral;
private @Nullable Referral referral;
/**
* LDAP specification settings.
@@ -76,51 +78,51 @@ public class LdapProperties {
private final Template template = new Template();
public String[] getUrls() {
public String @Nullable [] getUrls() {
return this.urls;
}
public void setUrls(String[] urls) {
public void setUrls(String @Nullable [] urls) {
this.urls = urls;
}
public String getBase() {
public @Nullable String getBase() {
return this.base;
}
public void setBase(String base) {
public void setBase(@Nullable String base) {
this.base = base;
}
public String getUsername() {
public @Nullable String getUsername() {
return this.username;
}
public void setUsername(String username) {
public void setUsername(@Nullable String username) {
this.username = username;
}
public String getPassword() {
public @Nullable String getPassword() {
return this.password;
}
public void setPassword(String password) {
public void setPassword(@Nullable String password) {
this.password = password;
}
public Boolean getAnonymousReadOnly() {
public @Nullable Boolean getAnonymousReadOnly() {
return this.anonymousReadOnly;
}
public void setAnonymousReadOnly(Boolean anonymousReadOnly) {
public void setAnonymousReadOnly(@Nullable Boolean anonymousReadOnly) {
this.anonymousReadOnly = anonymousReadOnly;
}
public Referral getReferral() {
public @Nullable Referral getReferral() {
return this.referral;
}
public void setReferral(Referral referral) {
public void setReferral(@Nullable Referral referral) {
this.referral = referral;
}
@@ -16,6 +16,8 @@
package org.springframework.boot.ldap.autoconfigure;
import org.jspecify.annotations.Nullable;
import org.springframework.core.env.Environment;
/**
@@ -40,17 +42,17 @@ class PropertiesLdapConnectionDetails implements LdapConnectionDetails {
}
@Override
public String getBase() {
public @Nullable String getBase() {
return this.properties.getBase();
}
@Override
public String getUsername() {
public @Nullable String getUsername() {
return this.properties.getUsername();
}
@Override
public String getPassword() {
public @Nullable String getPassword() {
return this.properties.getPassword();
}
@@ -28,6 +28,7 @@ import com.unboundid.ldap.listener.InMemoryListenerConfig;
import com.unboundid.ldap.sdk.LDAPException;
import com.unboundid.ldap.sdk.schema.Schema;
import com.unboundid.ldif.LDIFReader;
import org.jspecify.annotations.Nullable;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
@@ -83,7 +84,7 @@ public final class EmbeddedLdapAutoConfiguration implements DisposableBean {
private final EmbeddedLdapProperties embeddedProperties;
private InMemoryDirectoryServer server;
private @Nullable InMemoryDirectoryServer server;
EmbeddedLdapAutoConfiguration(EmbeddedLdapProperties embeddedProperties) {
this.embeddedProperties = embeddedProperties;
@@ -93,16 +94,17 @@ public final class EmbeddedLdapAutoConfiguration implements DisposableBean {
InMemoryDirectoryServer directoryServer(ApplicationContext applicationContext) throws LDAPException {
String[] baseDn = StringUtils.toStringArray(this.embeddedProperties.getBaseDn());
InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig(baseDn);
if (this.embeddedProperties.getCredential().isAvailable()) {
config.addAdditionalBindCredentials(this.embeddedProperties.getCredential().getUsername(),
this.embeddedProperties.getCredential().getPassword());
String username = this.embeddedProperties.getCredential().getUsername();
String password = this.embeddedProperties.getCredential().getPassword();
if (StringUtils.hasText(username) && StringUtils.hasText(password)) {
config.addAdditionalBindCredentials(username, password);
}
setSchema(config);
InMemoryListenerConfig listenerConfig = InMemoryListenerConfig.createLDAPConfig("LDAP",
this.embeddedProperties.getPort());
config.setListenerConfigs(listenerConfig);
this.server = new InMemoryDirectoryServer(config);
importLdif(applicationContext);
importLdif(this.server, applicationContext);
this.server.startListening();
setPortProperty(applicationContext, this.server.getListenPort());
return this.server;
@@ -123,21 +125,26 @@ public final class EmbeddedLdapAutoConfiguration implements DisposableBean {
try {
Schema defaultSchema = Schema.getDefaultStandardSchema();
Schema schema = Schema.getSchema(resource.getInputStream());
config.setSchema(Schema.mergeSchemas(defaultSchema, schema));
if (schema == null) {
config.setSchema(defaultSchema);
}
else {
config.setSchema(Schema.mergeSchemas(defaultSchema, schema));
}
}
catch (Exception ex) {
throw new IllegalStateException("Unable to load schema " + resource.getDescription(), ex);
}
}
private void importLdif(ApplicationContext applicationContext) {
private void importLdif(InMemoryDirectoryServer server, ApplicationContext applicationContext) {
String location = this.embeddedProperties.getLdif();
if (StringUtils.hasText(location)) {
try {
Resource resource = applicationContext.getResource(location);
if (resource.exists()) {
try (InputStream inputStream = resource.getInputStream()) {
this.server.importFromLDIF(true, new LDIFReader(inputStream));
server.importFromLDIF(true, new LDIFReader(inputStream));
}
}
}
@@ -221,7 +228,7 @@ public final class EmbeddedLdapAutoConfiguration implements DisposableBean {
static class EmbeddedLdapAutoConfigurationRuntimeHints implements RuntimeHintsRegistrar {
@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) {
hints.resources()
.registerPatternIfPresent(classLoader, "schema.ldif", (hint) -> hint.includes("schema.ldif"));
}
@@ -19,6 +19,8 @@ package org.springframework.boot.ldap.autoconfigure.embedded;
import java.util.ArrayList;
import java.util.List;
import org.jspecify.annotations.Nullable;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.convert.Delimiter;
import org.springframework.core.io.Resource;
@@ -101,26 +103,26 @@ public class EmbeddedLdapProperties {
/**
* Embedded LDAP username.
*/
private String username;
private @Nullable String username;
/**
* Embedded LDAP password.
*/
private String password;
private @Nullable String password;
public String getUsername() {
public @Nullable String getUsername() {
return this.username;
}
public void setUsername(String username) {
public void setUsername(@Nullable String username) {
this.username = username;
}
public String getPassword() {
public @Nullable String getPassword() {
return this.password;
}
public void setPassword(String password) {
public void setPassword(@Nullable String password) {
this.password = password;
}
@@ -140,7 +142,7 @@ public class EmbeddedLdapProperties {
/**
* Path to the custom schema.
*/
private Resource schema;
private @Nullable Resource schema;
public boolean isEnabled() {
return this.enabled;
@@ -150,11 +152,11 @@ public class EmbeddedLdapProperties {
this.enabled = enabled;
}
public Resource getSchema() {
public @Nullable Resource getSchema() {
return this.schema;
}
public void setSchema(Resource schema) {
public void setSchema(@Nullable Resource schema) {
this.schema = schema;
}
@@ -17,4 +17,7 @@
/**
* Auto-configuration for embedded LDAP.
*/
@NullMarked
package org.springframework.boot.ldap.autoconfigure.embedded;
import org.jspecify.annotations.NullMarked;
@@ -17,4 +17,7 @@
/**
* Auto-configuration for LDAP health.
*/
@NullMarked
package org.springframework.boot.ldap.autoconfigure.health;
import org.jspecify.annotations.NullMarked;
@@ -17,4 +17,7 @@
/**
* Auto-configuration for LDAP.
*/
@NullMarked
package org.springframework.boot.ldap.autoconfigure;
import org.jspecify.annotations.NullMarked;
@@ -17,4 +17,7 @@
/**
* Support for Docker Compose LDAP service connections.
*/
@NullMarked
package org.springframework.boot.ldap.docker.compose;
import org.jspecify.annotations.NullMarked;
@@ -19,6 +19,8 @@ package org.springframework.boot.ldap.health;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import org.jspecify.annotations.Nullable;
import org.springframework.boot.health.contributor.AbstractHealthIndicator;
import org.springframework.boot.health.contributor.Health;
import org.springframework.boot.health.contributor.HealthIndicator;
@@ -54,7 +56,7 @@ public class LdapHealthIndicator extends AbstractHealthIndicator {
private static final class VersionContextExecutor implements ContextExecutor<String> {
@Override
public String executeWithContext(DirContext ctx) throws NamingException {
public @Nullable String executeWithContext(DirContext ctx) throws NamingException {
Object version = ctx.getEnvironment().get("java.naming.ldap.version");
if (version != null) {
return (String) version;
@@ -17,4 +17,7 @@
/**
* Health integration for LDAP.
*/
@NullMarked
package org.springframework.boot.ldap.health;
import org.jspecify.annotations.NullMarked;
@@ -17,4 +17,7 @@
/**
* Support for testcontainers Ldap service connections.
*/
@NullMarked
package org.springframework.boot.ldap.testcontainers;
import org.jspecify.annotations.NullMarked;