Hide builder implementations in RuntimeHints API

This commit is contained in:
Stephane Nicoll
2022-04-14 10:05:38 +02:00
parent c28fd91a10
commit 780d07217b
9 changed files with 79 additions and 48 deletions

View File

@@ -20,7 +20,6 @@ import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* A hint that describes the need for a proxy against a concrete class.
@@ -55,6 +54,9 @@ public final class ClassProxyHint {
* @return a builder for the hint
*/
public static Builder of(Class<?> targetClass) {
if (targetClass.isInterface()) {
throw new IllegalArgumentException("Should not be an interface: " + targetClass);
}
return of(TypeReference.of(targetClass));
}
@@ -103,7 +105,7 @@ public final class ClassProxyHint {
private final LinkedList<TypeReference> proxiedInterfaces = new LinkedList<>();
public Builder(TypeReference targetClass) {
Builder(TypeReference targetClass) {
this.targetClass = targetClass;
}
@@ -124,7 +126,7 @@ public final class ClassProxyHint {
*/
public Builder proxiedInterfaces(Class<?>... proxiedInterfaces) {
this.proxiedInterfaces.addAll(Arrays.stream(proxiedInterfaces)
.map(TypeReference::of).collect(Collectors.toList()));
.map(TypeReference::of).toList());
return this;
}
@@ -132,7 +134,7 @@ public final class ClassProxyHint {
* Create a {@link ClassProxyHint} based on the state of this builder.
* @return a class proxy hint
*/
public ClassProxyHint build() {
ClassProxyHint build() {
return new ClassProxyHint(this);
}

View File

@@ -86,7 +86,7 @@ public final class ExecutableHint extends MemberHint {
/**
* Builder for {@link ExecutableHint}.
*/
public static final class Builder {
public static class Builder {
private final String name;
@@ -95,7 +95,7 @@ public final class ExecutableHint extends MemberHint {
private final Set<ExecutableMode> modes = new LinkedHashSet<>();
private Builder(String name, List<TypeReference> parameterTypes) {
Builder(String name, List<TypeReference> parameterTypes) {
this.name = name;
this.parameterTypes = parameterTypes;
}
@@ -127,7 +127,7 @@ public final class ExecutableHint extends MemberHint {
* Create an {@link ExecutableHint} based on the state of this builder.
* @return an executable hint
*/
public ExecutableHint build() {
ExecutableHint build() {
return new ExecutableHint(this);
}

View File

@@ -66,7 +66,7 @@ public final class FieldHint extends MemberHint {
private boolean allowUnsafeAccess;
public Builder(String name) {
Builder(String name) {
this.name = name;
}
@@ -94,7 +94,7 @@ public final class FieldHint extends MemberHint {
* Create a {@link FieldHint} based on the state of this builder.
* @return a field hint
*/
public FieldHint build() {
FieldHint build() {
return new FieldHint(this);
}

View File

@@ -21,7 +21,6 @@ import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* A hint that describes the need of a JDK {@link Proxy}, that is an
@@ -39,6 +38,24 @@ public final class JdkProxyHint {
this.proxiedInterfaces = List.copyOf(builder.proxiedInterfaces);
}
/**
* Initialize a builder with the proxied interfaces to use.
* @param proxiedInterfaces the interfaces the proxy should implement
* @return a builder for the hint
*/
public static Builder of(TypeReference... proxiedInterfaces) {
return new Builder().proxiedInterfaces(proxiedInterfaces);
}
/**
* Initialize a builder with the proxied interfaces to use.
* @param proxiedInterfaces the interfaces the proxy should implement
* @return a builder for the hint
*/
public static Builder of(Class<?>... proxiedInterfaces) {
return new Builder().proxiedInterfaces(proxiedInterfaces);
}
/**
* Return the interfaces to be proxied.
* @return the interfaces that the proxy should implement
@@ -70,8 +87,11 @@ public final class JdkProxyHint {
*/
public static class Builder {
private final LinkedList<TypeReference> proxiedInterfaces = new LinkedList<>();
private final LinkedList<TypeReference> proxiedInterfaces;
Builder() {
this.proxiedInterfaces = new LinkedList<>();
}
/**
* Add the specified interfaces that the proxy should implement.
@@ -89,8 +109,7 @@ public final class JdkProxyHint {
* @return {@code this}, to facilitate method chaining
*/
public Builder proxiedInterfaces(Class<?>... proxiedInterfaces) {
this.proxiedInterfaces.addAll(Arrays.stream(proxiedInterfaces)
.map(TypeReference::of).collect(Collectors.toList()));
this.proxiedInterfaces.addAll(toTypeReferences(proxiedInterfaces));
return this;
}
@@ -98,10 +117,19 @@ public final class JdkProxyHint {
* Create a {@link JdkProxyHint} based on the state of this builder.
* @return a jdk proxy hint
*/
public JdkProxyHint build() {
JdkProxyHint build() {
return new JdkProxyHint(this);
}
private static List<TypeReference> toTypeReferences(Class<?>... proxiedInterfaces) {
List<String> concreteTypes = Arrays.stream(proxiedInterfaces)
.filter(candidate -> !candidate.isInterface()).map(Class::getName).toList();
if (!concreteTypes.isEmpty()) {
throw new IllegalArgumentException("Not an interface: " + concreteTypes);
}
return Arrays.stream(proxiedInterfaces).map(TypeReference::of).toList();
}
}
}

View File

@@ -16,13 +16,9 @@
package org.springframework.aot.hint;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.springframework.aot.hint.ClassProxyHint.Builder;
@@ -58,11 +54,13 @@ public class ProxyHints {
/**
* Register a {@link JdkProxyHint}.
* @param hint the supplier to the hint
* @param jdkProxyHint the supplier to the hint
* @return {@code this}, to facilitate method chaining
*/
public ProxyHints registerJdkProxy(Supplier<JdkProxyHint> hint) {
this.jdkProxies.add(hint.get());
public ProxyHints registerJdkProxy(Consumer<JdkProxyHint.Builder> jdkProxyHint) {
JdkProxyHint.Builder builder = new JdkProxyHint.Builder();
jdkProxyHint.accept(builder);
this.jdkProxies.add(builder.build());
return this;
}
@@ -73,8 +71,8 @@ public class ProxyHints {
* @return {@code this}, to facilitate method chaining
*/
public ProxyHints registerJdkProxy(TypeReference... proxiedInterfaces) {
return registerJdkProxy(() -> new JdkProxyHint.Builder()
.proxiedInterfaces(proxiedInterfaces).build());
return registerJdkProxy(jdkProxyHint ->
jdkProxyHint.proxiedInterfaces(proxiedInterfaces));
}
/**
@@ -84,13 +82,8 @@ public class ProxyHints {
* @return {@code this}, to facilitate method chaining
*/
public ProxyHints registerJdkProxy(Class<?>... proxiedInterfaces) {
List<String> concreteTypes = Arrays.stream(proxiedInterfaces)
.filter(candidate -> !candidate.isInterface()).map(Class::getName).collect(Collectors.toList());
if (!concreteTypes.isEmpty()) {
throw new IllegalArgumentException("Not an interface: " + concreteTypes);
}
return registerJdkProxy(() -> new JdkProxyHint.Builder()
.proxiedInterfaces(proxiedInterfaces).build());
return registerJdkProxy(jdkProxyHint ->
jdkProxyHint.proxiedInterfaces(proxiedInterfaces));
}
/**
@@ -101,10 +94,7 @@ public class ProxyHints {
* @return {@code this}, to facilitate method chaining
*/
public ProxyHints registerClassProxy(TypeReference targetClass, Consumer<Builder> classProxyHint) {
Builder builder = ClassProxyHint.of(targetClass);
classProxyHint.accept(builder);
this.classProxies.add(builder.build());
return this;
return addClassProxyHint(ClassProxyHint.of(targetClass), classProxyHint);
}
/**
@@ -114,10 +104,13 @@ public class ProxyHints {
* @return {@code this}, to facilitate method chaining
*/
public ProxyHints registerClassProxy(Class<?> targetClass, Consumer<Builder> classProxyHint) {
if (targetClass.isInterface()) {
throw new IllegalArgumentException("Should not be an interface: " + targetClass);
}
return registerClassProxy(TypeReference.of(targetClass), classProxyHint);
return addClassProxyHint(ClassProxyHint.of(targetClass), classProxyHint);
}
private ProxyHints addClassProxyHint(ClassProxyHint.Builder builder, Consumer<ClassProxyHint.Builder> classProxyHint) {
classProxyHint.accept(builder);
this.classProxies.add(builder.build());
return this;
}
}

View File

@@ -25,6 +25,7 @@ import java.util.function.Consumer;
import java.util.stream.Stream;
import org.springframework.aot.hint.ResourcePatternHint.Builder;
import org.springframework.lang.Nullable;
/**
* Gather the need for resources available at runtime.
@@ -72,7 +73,7 @@ public class ResourceHints {
* @param resourceHint a builder to further customize the resource pattern
* @return {@code this}, to facilitate method chaining
*/
public ResourceHints registerPattern(String include, Consumer<Builder> resourceHint) {
public ResourceHints registerPattern(String include, @Nullable Consumer<Builder> resourceHint) {
Builder builder = new Builder().includes(include);
if (resourceHint != null) {
resourceHint.accept(builder);
@@ -136,7 +137,7 @@ public class ResourceHints {
return candidate.replace(".", "/") + ".class";
}
private void buildName(TypeReference type, StringBuilder sb) {
private void buildName(@Nullable TypeReference type, StringBuilder sb) {
if (type == null) {
return;
}

View File

@@ -96,7 +96,7 @@ public final class ResourcePatternHint {
* builder.
* @return a resource pattern hint
*/
public ResourcePatternHint build() {
ResourcePatternHint build() {
return new ResourcePatternHint(this);
}

View File

@@ -223,7 +223,7 @@ public final class TypeHint {
* Create a {@link TypeHint} based on the state of this builder.
* @return a type hint
*/
public TypeHint build() {
TypeHint build() {
return new TypeHint(this);
}