Skip to content

Commit

Permalink
Specify generic type nullness in spring-context
Browse files Browse the repository at this point in the history
Also in spring-context-support.

See spring-projectsgh-34140
  • Loading branch information
sdeleuze committed Jan 14, 2025
1 parent 928a3c7 commit 435cb0c
Show file tree
Hide file tree
Showing 30 changed files with 112 additions and 103 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -16,6 +16,7 @@

package org.springframework.cache.jcache;

import java.util.Objects;
import java.util.concurrent.Callable;
import java.util.function.Function;

Expand Down Expand Up @@ -134,7 +135,8 @@ private static class PutIfAbsentEntryProcessor implements EntryProcessor<Object,
private static final PutIfAbsentEntryProcessor INSTANCE = new PutIfAbsentEntryProcessor();

@Override
public @Nullable Object process(MutableEntry<Object, Object> entry, Object... arguments) throws EntryProcessorException {
@SuppressWarnings("NullAway") // Overridden method does not define nullness
public @Nullable Object process(MutableEntry<Object, @Nullable Object> entry, @Nullable Object... arguments) throws EntryProcessorException {
Object existingValue = entry.getValue();
if (existingValue == null) {
entry.setValue(arguments[0]);
Expand All @@ -146,28 +148,28 @@ private static class PutIfAbsentEntryProcessor implements EntryProcessor<Object,

private static final class ValueLoaderEntryProcessor implements EntryProcessor<Object, Object, Object> {

private final Function<Object, Object> fromStoreValue;
private final Function<Object, @Nullable Object> fromStoreValue;

private final Function<Object, Object> toStoreValue;

private ValueLoaderEntryProcessor(Function<Object, Object> fromStoreValue,
private ValueLoaderEntryProcessor(Function<Object, @Nullable Object> fromStoreValue,
Function<Object, Object> toStoreValue) {

this.fromStoreValue = fromStoreValue;
this.toStoreValue = toStoreValue;
}

@Override
@SuppressWarnings("unchecked")
public @Nullable Object process(MutableEntry<Object, Object> entry, Object... arguments) throws EntryProcessorException {
@SuppressWarnings({"unchecked","NullAway"}) // Overridden method does not define nullness
public @Nullable Object process(MutableEntry<Object, @Nullable Object> entry, @Nullable Object... arguments) throws EntryProcessorException {
Callable<Object> valueLoader = (Callable<Object>) arguments[0];
if (entry.exists()) {
return this.fromStoreValue.apply(entry.getValue());
return this.fromStoreValue.apply(Objects.requireNonNull(entry.getValue()));
}
else {
Object value;
try {
value = valueLoader.call();
value = Objects.requireNonNull(valueLoader).call();
}
catch (Exception ex) {
throw new EntryProcessorException("Value loader '" + valueLoader + "' failed " +
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -41,10 +41,11 @@
@Configuration(proxyBeanMethods = false)
public abstract class AbstractJCacheConfiguration extends AbstractCachingConfiguration {

protected @Nullable Supplier<CacheResolver> exceptionCacheResolver;
protected @Nullable Supplier<? extends @Nullable CacheResolver> exceptionCacheResolver;


@Override
@SuppressWarnings("NullAway") // https://github.com/uber/NullAway/issues/1126
protected void useCachingConfigurer(CachingConfigurerSupplier cachingConfigurerSupplier) {
super.useCachingConfigurer(cachingConfigurerSupplier);
this.exceptionCacheResolver = cachingConfigurerSupplier.adapt(config -> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -79,8 +79,8 @@ public DefaultJCacheOperationSource() {
* @since 5.1
*/
public DefaultJCacheOperationSource(
@Nullable Supplier<CacheManager> cacheManager, @Nullable Supplier<CacheResolver> cacheResolver,
@Nullable Supplier<CacheResolver> exceptionCacheResolver, @Nullable Supplier<KeyGenerator> keyGenerator) {
@Nullable Supplier<? extends @Nullable CacheManager> cacheManager, @Nullable Supplier<? extends @Nullable CacheResolver> cacheResolver,
@Nullable Supplier<? extends @Nullable CacheResolver> exceptionCacheResolver, @Nullable Supplier<? extends @Nullable KeyGenerator> keyGenerator) {

this.cacheManager = SingletonSupplier.ofNullable(cacheManager);
this.cacheResolver = SingletonSupplier.ofNullable(cacheResolver);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -96,7 +96,7 @@ public void afterPropertiesSet() {
}


protected @Nullable Object execute(CacheOperationInvoker invoker, Object target, Method method, Object[] args) {
protected @Nullable Object execute(CacheOperationInvoker invoker, Object target, Method method, @Nullable Object[] args) {
// Check whether aspect is enabled to cope with cases where the AJ is pulled in automatically
if (this.initialized) {
Class<?> targetClass = AopProxyUtils.ultimateTargetClass(target);
Expand All @@ -113,7 +113,7 @@ public void afterPropertiesSet() {

@SuppressWarnings("unchecked")
private CacheOperationInvocationContext<?> createCacheOperationInvocationContext(
Object target, Object[] args, JCacheOperation<?> operation) {
Object target, @Nullable Object[] args, JCacheOperation<?> operation) {

return new DefaultCacheInvocationContext<>(
(JCacheOperation<Annotation>) operation, target, args);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -60,7 +60,7 @@ public JCacheInterceptor() {
* applying the default error handler if the supplier is not resolvable
* @since 5.1
*/
public JCacheInterceptor(@Nullable Supplier<CacheErrorHandler> errorHandler) {
public JCacheInterceptor(@Nullable Supplier<? extends @Nullable CacheErrorHandler> errorHandler) {
this.errorHandler = new SingletonSupplier<>(errorHandler, SimpleCacheErrorHandler::new);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -50,13 +50,13 @@ public abstract class AbstractCachingConfiguration implements ImportAware {

protected @Nullable AnnotationAttributes enableCaching;

protected @Nullable Supplier<CacheManager> cacheManager;
protected @Nullable Supplier<? extends @Nullable CacheManager> cacheManager;

protected @Nullable Supplier<CacheResolver> cacheResolver;
protected @Nullable Supplier<? extends @Nullable CacheResolver> cacheResolver;

protected @Nullable Supplier<KeyGenerator> keyGenerator;
protected @Nullable Supplier<? extends @Nullable KeyGenerator> keyGenerator;

protected @Nullable Supplier<CacheErrorHandler> errorHandler;
protected @Nullable Supplier<? extends @Nullable CacheErrorHandler> errorHandler;


@Override
Expand All @@ -70,8 +70,9 @@ public void setImportMetadata(AnnotationMetadata importMetadata) {
}

@Autowired
@SuppressWarnings("NullAway") // https://github.com/uber/NullAway/issues/1126
void setConfigurers(ObjectProvider<CachingConfigurer> configurers) {
Supplier<CachingConfigurer> configurer = () -> {
Supplier<? extends @Nullable CachingConfigurer> configurer = () -> {
List<CachingConfigurer> candidates = configurers.stream().toList();
if (CollectionUtils.isEmpty(candidates)) {
return null;
Expand All @@ -90,6 +91,7 @@ void setConfigurers(ObjectProvider<CachingConfigurer> configurers) {
/**
* Extract the configuration from the nominated {@link CachingConfigurer}.
*/
@SuppressWarnings("NullAway") // https://github.com/uber/NullAway/issues/1126
protected void useCachingConfigurer(CachingConfigurerSupplier cachingConfigurerSupplier) {
this.cacheManager = cachingConfigurerSupplier.adapt(CachingConfigurer::cacheManager);
this.cacheResolver = cachingConfigurerSupplier.adapt(CachingConfigurer::cacheResolver);
Expand All @@ -100,10 +102,10 @@ protected void useCachingConfigurer(CachingConfigurerSupplier cachingConfigurerS

protected static class CachingConfigurerSupplier {

private final Supplier<CachingConfigurer> supplier;
private final SingletonSupplier<CachingConfigurer> supplier;

public CachingConfigurerSupplier(Supplier<CachingConfigurer> supplier) {
this.supplier = SingletonSupplier.of(supplier);
public CachingConfigurerSupplier(Supplier<? extends @Nullable CachingConfigurer> supplier) {
this.supplier = SingletonSupplier.ofNullable(supplier);
}

/**
Expand All @@ -115,7 +117,7 @@ public CachingConfigurerSupplier(Supplier<CachingConfigurer> supplier) {
* @param <T> the type of the supplier
* @return another supplier mapped by the specified function
*/
public <T> @Nullable Supplier<T> adapt(Function<CachingConfigurer, T> provider) {
public <T> Supplier<@Nullable T> adapt(Function<CachingConfigurer, ? extends @Nullable T> provider) {
return () -> {
CachingConfigurer cachingConfigurer = this.supplier.get();
return (cachingConfigurer != null ? provider.apply(cachingConfigurer) : null);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -154,8 +154,8 @@ protected CacheAspectSupport() {
* @since 5.1
*/
public void configure(
@Nullable Supplier<CacheErrorHandler> errorHandler, @Nullable Supplier<KeyGenerator> keyGenerator,
@Nullable Supplier<CacheResolver> cacheResolver, @Nullable Supplier<CacheManager> cacheManager) {
@Nullable Supplier<? extends @Nullable CacheErrorHandler> errorHandler, @Nullable Supplier<? extends @Nullable KeyGenerator> keyGenerator,
@Nullable Supplier<? extends @Nullable CacheResolver> cacheResolver, @Nullable Supplier<? extends @Nullable CacheManager> cacheManager) {

this.errorHandler = new SingletonSupplier<>(errorHandler, SimpleCacheErrorHandler::new);
this.keyGenerator = new SingletonSupplier<>(keyGenerator, SimpleKeyGenerator::new);
Expand Down Expand Up @@ -317,7 +317,7 @@ protected Collection<? extends Cache> getCaches(
}

protected CacheOperationContext getOperationContext(
CacheOperation operation, Method method, Object[] args, Object target, Class<?> targetClass) {
CacheOperation operation, Method method, @Nullable Object[] args, Object target, Class<?> targetClass) {

CacheOperationMetadata metadata = getCacheOperationMetadata(operation, method, targetClass);
return new CacheOperationContext(metadata, args, target);
Expand Down Expand Up @@ -391,7 +391,7 @@ protected void clearMetadataCache() {
this.evaluator.clear();
}

protected @Nullable Object execute(CacheOperationInvoker invoker, Object target, Method method, Object[] args) {
protected @Nullable Object execute(CacheOperationInvoker invoker, Object target, Method method, @Nullable Object[] args) {
// Check whether aspect is enabled (to cope with cases where the AJ is pulled in automatically)
if (this.initialized) {
Class<?> targetClass = AopProxyUtils.ultimateTargetClass(target);
Expand Down Expand Up @@ -726,7 +726,7 @@ private class CacheOperationContexts {
boolean processed;

public CacheOperationContexts(Collection<? extends CacheOperation> operations, Method method,
Object[] args, Object target, Class<?> targetClass) {
@Nullable Object[] args, Object target, Class<?> targetClass) {

this.contexts = new LinkedMultiValueMap<>(operations.size());
for (CacheOperation op : operations) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -22,6 +22,7 @@

import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.lang.Contract;

/**
* A simple {@link CacheResolver} that resolves the {@link Cache} instance(s)
Expand Down Expand Up @@ -63,6 +64,7 @@ protected Collection<String> getCacheNames(CacheOperationInvocationContext<?> co
* @return the SimpleCacheResolver ({@code null} if the CacheManager was {@code null})
* @since 5.1
*/
@Contract("null -> null; !null -> !null")
static @Nullable SimpleCacheResolver of(@Nullable CacheManager cacheManager) {
return (cacheManager != null ? new SimpleCacheResolver(cacheManager) : null);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -211,7 +211,7 @@ private Set<String> getMetaAnnotationTypes(MergedAnnotation<Annotation> mergedAn
* @return whether the annotation qualifies as a stereotype with component name
*/
protected boolean isStereotypeWithNameValue(String annotationType,
Set<String> metaAnnotationTypes, Map<String, Object> attributes) {
Set<String> metaAnnotationTypes, Map<String, @Nullable Object> attributes) {

boolean isStereotype = metaAnnotationTypes.contains(COMPONENT_ANNOTATION_CLASSNAME) ||
annotationType.equals("jakarta.inject.Named");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -129,7 +129,7 @@ List<Condition> collectConditions(@Nullable AnnotatedTypeMetadata metadata) {

@SuppressWarnings("unchecked")
private List<String[]> getConditionClasses(AnnotatedTypeMetadata metadata) {
MultiValueMap<String, Object> attributes = metadata.getAllAnnotationAttributes(Conditional.class.getName(), true);
MultiValueMap<String, @Nullable Object> attributes = metadata.getAllAnnotationAttributes(Conditional.class.getName(), true);
Object values = (attributes != null ? attributes.get("value") : null);
return (List<String[]>) (values != null ? values : Collections.emptyList());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -1077,7 +1077,7 @@ public Set<SourceClass> getAnnotations() {
}

public Collection<SourceClass> getAnnotationAttributes(String annType, String attribute) throws IOException {
Map<String, Object> annotationAttributes = this.metadata.getAnnotationAttributes(annType, true);
Map<String, @Nullable Object> annotationAttributes = this.metadata.getAnnotationAttributes(annType, true);
if (annotationAttributes == null || !annotationAttributes.containsKey(attribute)) {
return Collections.emptySet();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -658,9 +658,9 @@ private static class PropertySourcesAotContribution implements BeanFactoryInitia

private final List<PropertySourceDescriptor> descriptors;

private final Function<String, Resource> resourceResolver;
private final Function<String, @Nullable Resource> resourceResolver;

PropertySourcesAotContribution(List<PropertySourceDescriptor> descriptors, Function<String, Resource> resourceResolver) {
PropertySourcesAotContribution(List<PropertySourceDescriptor> descriptors, Function<String, @Nullable Resource> resourceResolver) {
this.descriptors = descriptors;
this.resourceResolver = resourceResolver;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -143,7 +143,7 @@ else if (beanDef instanceof AbstractBeanDefinition abstractBd && abstractBd.hasB
}
}

Map<String, Object> config = metadata.getAnnotationAttributes(Configuration.class.getName());
Map<String, @Nullable Object> config = metadata.getAnnotationAttributes(Configuration.class.getName());
if (config != null && !Boolean.FALSE.equals(config.get("proxyBeanMethods"))) {
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
}
Expand Down Expand Up @@ -208,7 +208,7 @@ static boolean hasBeanMethods(AnnotationMetadata metadata) {
* @since 5.0
*/
public static @Nullable Integer getOrder(AnnotationMetadata metadata) {
Map<String, Object> orderAttributes = metadata.getAnnotationAttributes(Order.class.getName());
Map<String, @Nullable Object> orderAttributes = metadata.getAnnotationAttributes(Order.class.getName());
return (orderAttributes != null ? ((Integer) orderAttributes.get(AnnotationUtils.VALUE)) : null);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -60,7 +60,7 @@ public class MBeanExportConfiguration implements ImportAware, EnvironmentAware,

@Override
public void setImportMetadata(AnnotationMetadata importMetadata) {
Map<String, Object> map = importMetadata.getAnnotationAttributes(EnableMBeanExport.class.getName());
Map<String, @Nullable Object> map = importMetadata.getAnnotationAttributes(EnableMBeanExport.class.getName());
this.enableMBeanExport = AnnotationAttributes.fromMap(map);
if (this.enableMBeanExport == null) {
throw new IllegalArgumentException(
Expand Down
Loading

0 comments on commit 435cb0c

Please sign in to comment.