Expand hints conditions support in RuntimeHints
Prior to this commit, the hints conditions were only supported for the `TypeHint` case. GraalVM generally expanded this concept to all hints and we should do the same. Right now, only the `typeReachable` condition is available but we should design for possible future additions. This commit introduces a new `ConditionalHint` contract implemented by all hints compatible with this approach. The condition information is also used in all configuration writers as a result. Closes gh-28126
This commit is contained in:
@@ -16,11 +16,11 @@
|
||||
|
||||
package org.springframework.aot.generate;
|
||||
|
||||
import org.springframework.aot.hint.JavaSerializationHints;
|
||||
import org.springframework.aot.hint.ProxyHints;
|
||||
import org.springframework.aot.hint.ReflectionHints;
|
||||
import org.springframework.aot.hint.ResourceHints;
|
||||
import org.springframework.aot.hint.RuntimeHints;
|
||||
import org.springframework.aot.hint.SerializationHints;
|
||||
|
||||
/**
|
||||
* Central interface used for code generation.
|
||||
@@ -67,7 +67,7 @@ public interface GenerationContext {
|
||||
/**
|
||||
* Return the {@link RuntimeHints} being used by the context. Used to record
|
||||
* {@link ReflectionHints reflection}, {@link ResourceHints resource},
|
||||
* {@link JavaSerializationHints serialization} and {@link ProxyHints proxy}
|
||||
* {@link SerializationHints serialization} and {@link ProxyHints proxy}
|
||||
* hints so that the application can run as a native image.
|
||||
* @return the runtime hints
|
||||
*/
|
||||
|
||||
@@ -21,22 +21,29 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* A hint that describes the need for a proxy against a concrete class.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Brian Clozel
|
||||
* @since 6.0
|
||||
*/
|
||||
public final class ClassProxyHint {
|
||||
public final class ClassProxyHint implements ConditionalHint {
|
||||
|
||||
private final TypeReference targetClass;
|
||||
|
||||
private final List<TypeReference> proxiedInterfaces;
|
||||
|
||||
@Nullable
|
||||
private final TypeReference reachableType;
|
||||
|
||||
|
||||
private ClassProxyHint(Builder builder) {
|
||||
this.targetClass = builder.targetClass;
|
||||
this.proxiedInterfaces = builder.proxiedInterfaces.stream().distinct().toList();
|
||||
this.reachableType = builder.reachableType;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -76,6 +83,12 @@ public final class ClassProxyHint {
|
||||
return this.proxiedInterfaces;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public TypeReference getReachableType() {
|
||||
return this.reachableType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
@@ -86,7 +99,8 @@ public final class ClassProxyHint {
|
||||
}
|
||||
ClassProxyHint that = (ClassProxyHint) o;
|
||||
return this.targetClass.equals(that.targetClass)
|
||||
&& this.proxiedInterfaces.equals(that.proxiedInterfaces);
|
||||
&& this.proxiedInterfaces.equals(that.proxiedInterfaces)
|
||||
&& Objects.equals(this.reachableType, that.reachableType);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -104,6 +118,9 @@ public final class ClassProxyHint {
|
||||
|
||||
private final LinkedList<TypeReference> proxiedInterfaces = new LinkedList<>();
|
||||
|
||||
@Nullable
|
||||
private TypeReference reachableType;
|
||||
|
||||
|
||||
Builder(TypeReference targetClass) {
|
||||
this.targetClass = targetClass;
|
||||
@@ -130,6 +147,18 @@ public final class ClassProxyHint {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make this hint conditional on the fact that the specified type
|
||||
* can be resolved.
|
||||
* @param reachableType the type that should be reachable for this
|
||||
* hint to apply
|
||||
* @return {@code this}, to facilitate method chaining
|
||||
*/
|
||||
public Builder onReachableType(TypeReference reachableType) {
|
||||
this.reachableType = reachableType;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link ClassProxyHint} based on the state of this builder.
|
||||
* @return a class proxy hint
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2002-2022 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.aot.hint;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* Contract for {@link RuntimeHints runtime hints} that only apply
|
||||
* if the described condition is met.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @since 6.0
|
||||
*/
|
||||
public interface ConditionalHint {
|
||||
|
||||
/**
|
||||
* Return the type that should be reachable for this hint to apply, or
|
||||
* {@code null} if this hint should always been applied.
|
||||
* @return the reachable type, if any
|
||||
*/
|
||||
@Nullable
|
||||
TypeReference getReachableType();
|
||||
|
||||
/**
|
||||
* Whether the condition described for this hint is met. If it is not,
|
||||
* the hint does not apply.
|
||||
* <p>Instead of checking for actual reachability of a type in the
|
||||
* application, the classpath is checked for the presence of this
|
||||
* type as a simple heuristic.
|
||||
* @param classLoader the current classloader
|
||||
* @return whether the condition is met and the hint applies
|
||||
*/
|
||||
default boolean conditionMatches(ClassLoader classLoader) {
|
||||
TypeReference reachableType = getReachableType();
|
||||
if (reachableType != null) {
|
||||
return ClassUtils.isPresent(reachableType.getCanonicalName(), classLoader);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright 2002-2022 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.aot.hint;
|
||||
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* A hint that describes the need for Java serialization at runtime.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @since 6.0
|
||||
*/
|
||||
public class JavaSerializationHint implements ConditionalHint {
|
||||
|
||||
private final TypeReference type;
|
||||
|
||||
@Nullable
|
||||
private final TypeReference reachableType;
|
||||
|
||||
JavaSerializationHint(Builder builder) {
|
||||
this.type = builder.type;
|
||||
this.reachableType = builder.reachableType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the {@link TypeReference type} that needs to be serialized using
|
||||
* Java serialization at runtime.
|
||||
* @return a {@link Serializable} type
|
||||
*/
|
||||
public TypeReference getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public TypeReference getReachableType() {
|
||||
return this.reachableType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
JavaSerializationHint that = (JavaSerializationHint) o;
|
||||
return this.type.equals(that.type)
|
||||
&& Objects.equals(this.reachableType, that.reachableType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.type, this.reachableType);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Builder for {@link JavaSerializationHint}.
|
||||
*/
|
||||
public static class Builder {
|
||||
|
||||
private final TypeReference type;
|
||||
|
||||
@Nullable
|
||||
private TypeReference reachableType;
|
||||
|
||||
|
||||
Builder(TypeReference type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make this hint conditional on the fact that the specified type
|
||||
* can be resolved.
|
||||
* @param reachableType the type that should be reachable for this
|
||||
* hint to apply
|
||||
* @return {@code this}, to facilitate method chaining
|
||||
*/
|
||||
public Builder onReachableType(TypeReference reachableType) {
|
||||
this.reachableType = reachableType;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link JavaSerializationHint} based on the state of this builder.
|
||||
* @return a java serialization hint
|
||||
*/
|
||||
JavaSerializationHint build() {
|
||||
return new JavaSerializationHint(this);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2022 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.aot.hint;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* Gather the need for Java serialization at runtime.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @since 6.0
|
||||
* @see Serializable
|
||||
*/
|
||||
public class JavaSerializationHints {
|
||||
|
||||
private final Set<TypeReference> types;
|
||||
|
||||
|
||||
public JavaSerializationHints() {
|
||||
this.types = new LinkedHashSet<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the {@link TypeReference types} that need to be serialized using
|
||||
* Java serialization at runtime.
|
||||
* @return a stream of {@link Serializable} types
|
||||
*/
|
||||
public Stream<TypeReference> types() {
|
||||
return this.types.stream();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register that the type defined by the specified {@link TypeReference}
|
||||
* need to be serialized using java serialization.
|
||||
* @param type the type to register
|
||||
* @return {@code this}, to facilitate method chaining
|
||||
*/
|
||||
public JavaSerializationHints registerType(TypeReference type) {
|
||||
this.types.add(type);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register that the specified type need to be serialized using java
|
||||
* serialization.
|
||||
* @param type the type to register
|
||||
* @return {@code this}, to facilitate method chaining
|
||||
*/
|
||||
public JavaSerializationHints registerType(Class<? extends Serializable> type) {
|
||||
return registerType(TypeReference.of(type));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,20 +22,27 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* A hint that describes the need of a JDK {@link Proxy}, that is an
|
||||
* interfaces-based proxy.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Brian Clozel
|
||||
* @since 6.0
|
||||
*/
|
||||
public final class JdkProxyHint {
|
||||
public final class JdkProxyHint implements ConditionalHint {
|
||||
|
||||
private final List<TypeReference> proxiedInterfaces;
|
||||
|
||||
@Nullable
|
||||
private final TypeReference reachableType;
|
||||
|
||||
|
||||
private JdkProxyHint(Builder builder) {
|
||||
this.proxiedInterfaces = List.copyOf(builder.proxiedInterfaces);
|
||||
this.reachableType = builder.reachableType;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -64,6 +71,12 @@ public final class JdkProxyHint {
|
||||
return this.proxiedInterfaces;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public TypeReference getReachableType() {
|
||||
return this.reachableType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
@@ -73,7 +86,8 @@ public final class JdkProxyHint {
|
||||
return false;
|
||||
}
|
||||
JdkProxyHint that = (JdkProxyHint) o;
|
||||
return this.proxiedInterfaces.equals(that.proxiedInterfaces);
|
||||
return this.proxiedInterfaces.equals(that.proxiedInterfaces)
|
||||
&& Objects.equals(this.reachableType, that.reachableType);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -89,6 +103,10 @@ public final class JdkProxyHint {
|
||||
|
||||
private final LinkedList<TypeReference> proxiedInterfaces;
|
||||
|
||||
@Nullable
|
||||
private TypeReference reachableType;
|
||||
|
||||
|
||||
Builder() {
|
||||
this.proxiedInterfaces = new LinkedList<>();
|
||||
}
|
||||
@@ -113,6 +131,18 @@ public final class JdkProxyHint {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make this hint conditional on the fact that the specified type
|
||||
* can be resolved.
|
||||
* @param reachableType the type that should be reachable for this
|
||||
* hint to apply
|
||||
* @return {@code this}, to facilitate method chaining
|
||||
*/
|
||||
public Builder onReachableType(TypeReference reachableType) {
|
||||
this.reachableType = reachableType;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link JdkProxyHint} based on the state of this builder.
|
||||
* @return a jdk proxy hint
|
||||
|
||||
@@ -16,21 +16,29 @@
|
||||
|
||||
package org.springframework.aot.hint;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* A hint that describes the need to access to a {@link ResourceBundle}.
|
||||
* A hint that describes the need to access a {@link ResourceBundle}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Brian Clozel
|
||||
* @since 6.0
|
||||
*/
|
||||
public class ResourceBundleHint {
|
||||
public final class ResourceBundleHint implements ConditionalHint {
|
||||
|
||||
private final String baseName;
|
||||
|
||||
@Nullable
|
||||
private TypeReference reachableType;
|
||||
|
||||
ResourceBundleHint(String baseName) {
|
||||
this.baseName = baseName;
|
||||
|
||||
ResourceBundleHint(Builder builder) {
|
||||
this.baseName = builder.baseName;
|
||||
this.reachableType = builder.reachableType;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -41,4 +49,70 @@ public class ResourceBundleHint {
|
||||
return this.baseName;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public TypeReference getReachableType() {
|
||||
return this.reachableType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
ResourceBundleHint that = (ResourceBundleHint) o;
|
||||
return this.baseName.equals(that.baseName)
|
||||
&& Objects.equals(this.reachableType, that.reachableType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.baseName, this.reachableType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for {@link ResourceBundleHint}.
|
||||
*/
|
||||
public static class Builder {
|
||||
|
||||
private String baseName;
|
||||
|
||||
@Nullable
|
||||
private TypeReference reachableType;
|
||||
|
||||
/**
|
||||
* Make this hint conditional on the fact that the specified type
|
||||
* can be resolved.
|
||||
* @param reachableType the type that should be reachable for this
|
||||
* hint to apply
|
||||
* @return {@code this}, to facilitate method chaining
|
||||
*/
|
||||
public Builder onReachableType(TypeReference reachableType) {
|
||||
this.reachableType = reachableType;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the the {@code baseName} of the resource bundle.
|
||||
* @return {@code this}, to facilitate method chaining
|
||||
*/
|
||||
public Builder baseName(String baseName) {
|
||||
this.baseName = baseName;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link ResourceBundleHint} based on the state of this
|
||||
* builder.
|
||||
* @return a resource bundle hint
|
||||
*/
|
||||
ResourceBundleHint build() {
|
||||
return new ResourceBundleHint(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.springframework.aot.hint.ResourcePatternHint.Builder;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
@@ -37,9 +36,9 @@ public class ResourceHints {
|
||||
|
||||
private final Set<TypeReference> types;
|
||||
|
||||
private final List<Builder> resourcePatternHints;
|
||||
private final List<ResourcePatternHints> resourcePatternHints;
|
||||
|
||||
private final Set<String> resourceBundleHints;
|
||||
private final Set<ResourceBundleHint> resourceBundleHints;
|
||||
|
||||
|
||||
public ResourceHints() {
|
||||
@@ -50,10 +49,10 @@ public class ResourceHints {
|
||||
|
||||
/**
|
||||
* Return the resources that should be made available at runtime.
|
||||
* @return a stream of {@link ResourcePatternHint}
|
||||
* @return a stream of {@link ResourcePatternHints}
|
||||
*/
|
||||
public Stream<ResourcePatternHint> resourcePatterns() {
|
||||
Stream<ResourcePatternHint> patterns = this.resourcePatternHints.stream().map(Builder::build);
|
||||
public Stream<ResourcePatternHints> resourcePatterns() {
|
||||
Stream<ResourcePatternHints> patterns = this.resourcePatternHints.stream();
|
||||
return (this.types.isEmpty() ? patterns
|
||||
: Stream.concat(Stream.of(typesPatternResourceHint()), patterns));
|
||||
}
|
||||
@@ -63,22 +62,21 @@ public class ResourceHints {
|
||||
* @return a stream of {@link ResourceBundleHint}
|
||||
*/
|
||||
public Stream<ResourceBundleHint> resourceBundles() {
|
||||
return this.resourceBundleHints.stream().map(ResourceBundleHint::new);
|
||||
return this.resourceBundleHints.stream();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register that the resources matching the specified pattern should be
|
||||
* made available at runtime.
|
||||
* @param include a pattern of the resources to include
|
||||
* @param resourceHint a builder to further customize the resource pattern
|
||||
* @return {@code this}, to facilitate method chaining
|
||||
*/
|
||||
public ResourceHints registerPattern(String include, @Nullable Consumer<Builder> resourceHint) {
|
||||
Builder builder = new Builder().includes(include);
|
||||
public ResourceHints registerPattern(@Nullable Consumer<ResourcePatternHints.Builder> resourceHint) {
|
||||
ResourcePatternHints.Builder builder = new ResourcePatternHints.Builder();
|
||||
if (resourceHint != null) {
|
||||
resourceHint.accept(builder);
|
||||
}
|
||||
this.resourcePatternHints.add(builder);
|
||||
this.resourcePatternHints.add(builder.build());
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -89,7 +87,7 @@ public class ResourceHints {
|
||||
* @return {@code this}, to facilitate method chaining
|
||||
*/
|
||||
public ResourceHints registerPattern(String include) {
|
||||
return registerPattern(include, null);
|
||||
return registerPattern(builder -> builder.includes(include));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -117,15 +115,30 @@ public class ResourceHints {
|
||||
* Register that the resource bundle with the specified base name should
|
||||
* be made available at runtime.
|
||||
* @param baseName the base name of the resource bundle
|
||||
* @param resourceHint a builder to further customize the resource bundle
|
||||
* @return {@code this}, to facilitate method chaining
|
||||
*/
|
||||
public ResourceHints registerResourceBundle(String baseName) {
|
||||
this.resourceBundleHints.add(baseName);
|
||||
public ResourceHints registerResourceBundle(String baseName, @Nullable Consumer<ResourceBundleHint.Builder> resourceHint) {
|
||||
ResourceBundleHint.Builder builder = new ResourceBundleHint.Builder().baseName(baseName);
|
||||
if (resourceHint != null) {
|
||||
resourceHint.accept(builder);
|
||||
}
|
||||
this.resourceBundleHints.add(builder.build());
|
||||
return this;
|
||||
}
|
||||
|
||||
private ResourcePatternHint typesPatternResourceHint() {
|
||||
Builder builder = new Builder();
|
||||
/**
|
||||
* Register that the resource bundle with the specified base name should
|
||||
* be made available at runtime.
|
||||
* @param baseName the base name of the resource bundle
|
||||
* @return {@code this}, to facilitate method chaining
|
||||
*/
|
||||
public ResourceHints registerResourceBundle(String baseName) {
|
||||
return registerResourceBundle(baseName, null);
|
||||
}
|
||||
|
||||
private ResourcePatternHints typesPatternResourceHint() {
|
||||
ResourcePatternHints.Builder builder = new ResourcePatternHints.Builder();
|
||||
this.types.forEach(type -> builder.includes(toIncludePattern(type)));
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@@ -16,89 +16,61 @@
|
||||
|
||||
package org.springframework.aot.hint;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* A hint that describes resources that should be made available at runtime.
|
||||
*
|
||||
* <p>The patterns may be a simple path which has a one-to-one mapping to a
|
||||
* resource on the classpath, or alternatively may contain the special
|
||||
* {@code *} character to indicate a wildcard search.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Brian Clozel
|
||||
* @since 6.0
|
||||
*/
|
||||
public final class ResourcePatternHint {
|
||||
public final class ResourcePatternHint implements ConditionalHint {
|
||||
|
||||
private final List<String> includes;
|
||||
private final String pattern;
|
||||
|
||||
private final List<String> excludes;
|
||||
@Nullable
|
||||
private final TypeReference reachableType;
|
||||
|
||||
|
||||
private ResourcePatternHint(Builder builder) {
|
||||
this.includes = new ArrayList<>(builder.includes);
|
||||
this.excludes = new ArrayList<>(builder.excludes);
|
||||
ResourcePatternHint(String pattern, @Nullable TypeReference reachableType) {
|
||||
this.pattern = pattern;
|
||||
this.reachableType = reachableType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the include patterns to use to identify the resources to match.
|
||||
* @return the include patterns
|
||||
* Return the pattern to use for identifying the resources to match.
|
||||
* @return the patterns
|
||||
*/
|
||||
public List<String> getIncludes() {
|
||||
return this.includes;
|
||||
public String getPattern() {
|
||||
return this.pattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the exclude patterns to use to identify the resources to match.
|
||||
* @return the exclude patterns
|
||||
*/
|
||||
public List<String> getExcludes() {
|
||||
return this.excludes;
|
||||
@Nullable
|
||||
@Override
|
||||
public TypeReference getReachableType() {
|
||||
return this.reachableType;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Builder for {@link ResourcePatternHint}.
|
||||
*/
|
||||
public static class Builder {
|
||||
|
||||
private final Set<String> includes = new LinkedHashSet<>();
|
||||
|
||||
private final Set<String> excludes = new LinkedHashSet<>();
|
||||
|
||||
|
||||
/**
|
||||
* Includes the resources matching the specified pattern.
|
||||
* @param includes the include patterns
|
||||
* @return {@code this}, to facilitate method chaining
|
||||
*/
|
||||
public Builder includes(String... includes) {
|
||||
this.includes.addAll(Arrays.asList(includes));
|
||||
return this;
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exclude resources matching the specified pattern.
|
||||
* @param excludes the excludes pattern
|
||||
* @return {@code this}, to facilitate method chaining
|
||||
*/
|
||||
public Builder excludes(String... excludes) {
|
||||
this.excludes.addAll(Arrays.asList(excludes));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link ResourcePatternHint} based on the state of this
|
||||
* builder.
|
||||
* @return a resource pattern hint
|
||||
*/
|
||||
ResourcePatternHint build() {
|
||||
return new ResourcePatternHint(this);
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
ResourcePatternHint that = (ResourcePatternHint) o;
|
||||
return this.pattern.equals(that.pattern)
|
||||
&& Objects.equals(this.reachableType, that.reachableType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.pattern, this.reachableType);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright 2002-2022 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.aot.hint;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A collection of {@link ResourcePatternHint} describing whether
|
||||
* resources should be made available at runtime through a matching
|
||||
* mechanism or inclusion/exclusion.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Brian Clozel
|
||||
* @since 6.0
|
||||
*/
|
||||
public final class ResourcePatternHints {
|
||||
|
||||
private final List<ResourcePatternHint> includes;
|
||||
|
||||
private final List<ResourcePatternHint> excludes;
|
||||
|
||||
|
||||
private ResourcePatternHints(Builder builder) {
|
||||
this.includes = new ArrayList<>(builder.includes);
|
||||
this.excludes = new ArrayList<>(builder.excludes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the include patterns to use to identify the resources to match.
|
||||
* @return the include patterns
|
||||
*/
|
||||
public List<ResourcePatternHint> getIncludes() {
|
||||
return this.includes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the exclude patterns to use to identify the resources to match.
|
||||
* @return the exclude patterns
|
||||
*/
|
||||
public List<ResourcePatternHint> getExcludes() {
|
||||
return this.excludes;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Builder for {@link ResourcePatternHints}.
|
||||
*/
|
||||
public static class Builder {
|
||||
|
||||
private final Set<ResourcePatternHint> includes = new LinkedHashSet<>();
|
||||
|
||||
private final Set<ResourcePatternHint> excludes = new LinkedHashSet<>();
|
||||
|
||||
/**
|
||||
* Includes the resources matching the specified pattern.
|
||||
* @param reachableType the type that should be reachable for this hint to apply
|
||||
* @param includes the include patterns
|
||||
* @return {@code this}, to facilitate method chaining
|
||||
*/
|
||||
public Builder includes(TypeReference reachableType, String... includes) {
|
||||
List<ResourcePatternHint> newIncludes = Arrays.stream(includes)
|
||||
.map(include -> new ResourcePatternHint(include, reachableType)).toList();
|
||||
this.includes.addAll(newIncludes);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Includes the resources matching the specified pattern.
|
||||
* @param includes the include patterns
|
||||
* @return {@code this}, to facilitate method chaining
|
||||
*/
|
||||
public Builder includes(String... includes) {
|
||||
return includes(null, includes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Exclude resources matching the specified pattern.
|
||||
* @param reachableType the type that should be reachable for this hint to apply
|
||||
* @param excludes the excludes pattern
|
||||
* @return {@code this}, to facilitate method chaining
|
||||
*/
|
||||
public Builder excludes(TypeReference reachableType, String... excludes) {
|
||||
List<ResourcePatternHint> newExcludes = Arrays.stream(excludes)
|
||||
.map(include -> new ResourcePatternHint(include, reachableType)).toList();
|
||||
this.excludes.addAll(newExcludes);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exclude resources matching the specified pattern.
|
||||
* @param excludes the excludes pattern
|
||||
* @return {@code this}, to facilitate method chaining
|
||||
*/
|
||||
public Builder excludes(String... excludes) {
|
||||
return excludes(null, excludes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link ResourcePatternHints} based on the state of this
|
||||
* builder.
|
||||
* @return a resource pattern hint
|
||||
*/
|
||||
ResourcePatternHints build() {
|
||||
return new ResourcePatternHints(this);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -36,7 +36,7 @@ public class RuntimeHints {
|
||||
|
||||
private final ResourceHints resources = new ResourceHints();
|
||||
|
||||
private final JavaSerializationHints javaSerialization = new JavaSerializationHints();
|
||||
private final SerializationHints serialization = new SerializationHints();
|
||||
|
||||
private final ProxyHints proxies = new ProxyHints();
|
||||
|
||||
@@ -59,10 +59,10 @@ public class RuntimeHints {
|
||||
|
||||
/**
|
||||
* Provide access to serialization-based hints.
|
||||
* @return java serialization hints
|
||||
* @return serialization hints
|
||||
*/
|
||||
public JavaSerializationHints javaSerialization() {
|
||||
return this.javaSerialization;
|
||||
public SerializationHints serialization() {
|
||||
return this.serialization;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright 2002-2022 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.aot.hint;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Gather the need for Java serialization at runtime.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @since 6.0
|
||||
* @see Serializable
|
||||
*/
|
||||
public class SerializationHints {
|
||||
|
||||
private final Set<JavaSerializationHint> javaSerializationHints;
|
||||
|
||||
|
||||
public SerializationHints() {
|
||||
this.javaSerializationHints = new LinkedHashSet<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the {@link JavaSerializationHint java serialization hints} for types
|
||||
* that need to be serialized using Java serialization at runtime.
|
||||
* @return a stream of {@link JavaSerializationHint java serialization hints}
|
||||
*/
|
||||
public Stream<JavaSerializationHint> javaSerialization() {
|
||||
return this.javaSerializationHints.stream();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register that the type defined by the specified {@link TypeReference}
|
||||
* need to be serialized using java serialization.
|
||||
* @param type the type to register
|
||||
* @param serializationHint a builder to further customize the serialization
|
||||
* @return {@code this}, to facilitate method chaining
|
||||
*/
|
||||
public SerializationHints registerType(TypeReference type, @Nullable Consumer<JavaSerializationHint.Builder> serializationHint) {
|
||||
JavaSerializationHint.Builder builder = new JavaSerializationHint.Builder(type);
|
||||
if (serializationHint != null) {
|
||||
serializationHint.accept(builder);
|
||||
}
|
||||
this.javaSerializationHints.add(builder.build());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register that the type defined by the specified {@link TypeReference}
|
||||
* need to be serialized using java serialization.
|
||||
* @param type the type to register
|
||||
* @return {@code this}, to facilitate method chaining
|
||||
*/
|
||||
public SerializationHints registerType(TypeReference type) {
|
||||
return registerType(type, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register that the specified type need to be serialized using java
|
||||
* serialization.
|
||||
* @param type the type to register
|
||||
* @param serializationHint a builder to further customize the serialization
|
||||
* @return {@code this}, to facilitate method chaining
|
||||
*/
|
||||
public SerializationHints registerType(Class<? extends Serializable> type, @Nullable Consumer<JavaSerializationHint.Builder> serializationHint) {
|
||||
return registerType(TypeReference.of(type), serializationHint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register that the specified type need to be serialized using java
|
||||
* serialization.
|
||||
* @param type the type to register
|
||||
* @return {@code this}, to facilitate method chaining
|
||||
*/
|
||||
public SerializationHints registerType(Class<? extends Serializable> type) {
|
||||
return registerType(type, null);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -37,7 +37,7 @@ import org.springframework.util.Assert;
|
||||
* @author Stephane Nicoll
|
||||
* @since 6.0
|
||||
*/
|
||||
public final class TypeHint {
|
||||
public final class TypeHint implements ConditionalHint {
|
||||
|
||||
private final TypeReference type;
|
||||
|
||||
@@ -81,12 +81,8 @@ public final class TypeHint {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the type that should be reachable for this hint to apply, or
|
||||
* {@code null} if this hint should always been applied.
|
||||
* @return the reachable type, if any
|
||||
*/
|
||||
@Nullable
|
||||
@Override
|
||||
public TypeReference getReachableType() {
|
||||
return this.reachableType;
|
||||
}
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2022 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.aot.nativex;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.aot.hint.JavaSerializationHints;
|
||||
import org.springframework.aot.hint.TypeReference;
|
||||
|
||||
/**
|
||||
* Write a {@link JavaSerializationHints} to the JSON output expected by the
|
||||
* GraalVM {@code native-image} compiler, typically named
|
||||
* {@code serialization-config.json}.
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
* @author Stephane Nicoll
|
||||
* @since 6.0
|
||||
* @see <a href="https://www.graalvm.org/22.0/reference-manual/native-image/BuildConfiguration/">Native Image Build Configuration</a>
|
||||
*/
|
||||
class JavaSerializationHintsWriter {
|
||||
|
||||
public static final JavaSerializationHintsWriter INSTANCE = new JavaSerializationHintsWriter();
|
||||
|
||||
public void write(BasicJsonWriter writer, JavaSerializationHints hints) {
|
||||
writer.writeArray(hints.types().map(this::toAttributes).toList());
|
||||
}
|
||||
|
||||
private Map<String, Object> toAttributes(TypeReference typeReference) {
|
||||
LinkedHashMap<String, Object> attributes = new LinkedHashMap<>();
|
||||
attributes.put("name", typeReference);
|
||||
return attributes;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,11 +18,11 @@ package org.springframework.aot.nativex;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.springframework.aot.hint.JavaSerializationHints;
|
||||
import org.springframework.aot.hint.ProxyHints;
|
||||
import org.springframework.aot.hint.ReflectionHints;
|
||||
import org.springframework.aot.hint.ResourceHints;
|
||||
import org.springframework.aot.hint.RuntimeHints;
|
||||
import org.springframework.aot.hint.SerializationHints;
|
||||
|
||||
/**
|
||||
* Write {@link RuntimeHints} as GraalVM native configuration.
|
||||
@@ -30,7 +30,7 @@ import org.springframework.aot.hint.RuntimeHints;
|
||||
* @author Sebastien Deleuze
|
||||
* @author Stephane Nicoll
|
||||
* @since 6.0
|
||||
* @see <a href="https://www.graalvm.org/22.0/reference-manual/native-image/BuildConfiguration/">Native Image Build Configuration</a>
|
||||
* @see <a href="https://www.graalvm.org/22.1/reference-manual/native-image/BuildConfiguration/">Native Image Build Configuration</a>
|
||||
*/
|
||||
public abstract class NativeConfigurationWriter {
|
||||
|
||||
@@ -39,8 +39,8 @@ public abstract class NativeConfigurationWriter {
|
||||
* @param hints the hints to handle
|
||||
*/
|
||||
public void write(RuntimeHints hints) {
|
||||
if (hints.javaSerialization().types().findAny().isPresent()) {
|
||||
writeJavaSerializationHints(hints.javaSerialization());
|
||||
if (hints.serialization().javaSerialization().findAny().isPresent()) {
|
||||
writeJavaSerializationHints(hints.serialization());
|
||||
}
|
||||
if (hints.proxies().jdkProxies().findAny().isPresent()) {
|
||||
writeProxyHints(hints.proxies());
|
||||
@@ -62,9 +62,9 @@ public abstract class NativeConfigurationWriter {
|
||||
*/
|
||||
protected abstract void writeTo(String fileName, Consumer<BasicJsonWriter> writer);
|
||||
|
||||
private void writeJavaSerializationHints(JavaSerializationHints hints) {
|
||||
private void writeJavaSerializationHints(SerializationHints hints) {
|
||||
writeTo("serialization-config.json", writer ->
|
||||
JavaSerializationHintsWriter.INSTANCE.write(writer, hints));
|
||||
SerializationHintsWriter.INSTANCE.write(writer, hints));
|
||||
}
|
||||
|
||||
private void writeProxyHints(ProxyHints hints) {
|
||||
|
||||
@@ -30,9 +30,10 @@ import org.springframework.aot.hint.TypeReference;
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
* @author Stephane Nicoll
|
||||
* @author Brian Clozel
|
||||
* @since 6.0
|
||||
* @see <a href="https://www.graalvm.org/22.0/reference-manual/native-image/DynamicProxy/">Dynamic Proxy in Native Image</a>
|
||||
* @see <a href="https://www.graalvm.org/22.0/reference-manual/native-image/BuildConfiguration/">Native Image Build Configuration</a>
|
||||
* @see <a href="https://www.graalvm.org/22.1/reference-manual/native-image/DynamicProxy/">Dynamic Proxy in Native Image</a>
|
||||
* @see <a href="https://www.graalvm.org/22.1/reference-manual/native-image/BuildConfiguration/">Native Image Build Configuration</a>
|
||||
*/
|
||||
class ProxyHintsWriter {
|
||||
|
||||
@@ -44,9 +45,18 @@ class ProxyHintsWriter {
|
||||
|
||||
private Map<String, Object> toAttributes(JdkProxyHint hint) {
|
||||
Map<String, Object> attributes = new LinkedHashMap<>();
|
||||
handleCondition(attributes, hint);
|
||||
attributes.put("interfaces", hint.getProxiedInterfaces().stream()
|
||||
.map(TypeReference::getCanonicalName).toList());
|
||||
return attributes;
|
||||
}
|
||||
|
||||
private void handleCondition(Map<String, Object> attributes, JdkProxyHint hint) {
|
||||
if (hint.getReachableType() != null) {
|
||||
Map<String, Object> conditionAttributes = new LinkedHashMap<>();
|
||||
conditionAttributes.put("typeReachable", hint.getReachableType());
|
||||
attributes.put("condition", conditionAttributes);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,9 +25,11 @@ import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.springframework.aot.hint.ConditionalHint;
|
||||
import org.springframework.aot.hint.ResourceBundleHint;
|
||||
import org.springframework.aot.hint.ResourceHints;
|
||||
import org.springframework.aot.hint.ResourcePatternHint;
|
||||
import org.springframework.aot.hint.ResourcePatternHints;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
@@ -36,9 +38,10 @@ import org.springframework.lang.Nullable;
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
* @author Stephane Nicoll
|
||||
* @author Brian Clozel
|
||||
* @since 6.0
|
||||
* @see <a href="https://www.graalvm.org/22.0/reference-manual/native-image/Resources/">Accessing Resources in Native Images</a>
|
||||
* @see <a href="https://www.graalvm.org/22.0/reference-manual/native-image/BuildConfiguration/">Native Image Build Configuration</a>
|
||||
* @see <a href="https://www.graalvm.org/22.1/reference-manual/native-image/Resources/">Accessing Resources in Native Images</a>
|
||||
* @see <a href="https://www.graalvm.org/22.1/reference-manual/native-image/BuildConfiguration/">Native Image Build Configuration</a>
|
||||
*/
|
||||
class ResourceHintsWriter {
|
||||
|
||||
@@ -53,9 +56,9 @@ class ResourceHintsWriter {
|
||||
|
||||
private Map<String, Object> toAttributes(ResourceHints hint) {
|
||||
Map<String, Object> attributes = new LinkedHashMap<>();
|
||||
addIfNotEmpty(attributes, "includes", hint.resourcePatterns().map(ResourcePatternHint::getIncludes)
|
||||
addIfNotEmpty(attributes, "includes", hint.resourcePatterns().map(ResourcePatternHints::getIncludes)
|
||||
.flatMap(List::stream).distinct().map(this::toAttributes).toList());
|
||||
addIfNotEmpty(attributes, "excludes", hint.resourcePatterns().map(ResourcePatternHint::getExcludes)
|
||||
addIfNotEmpty(attributes, "excludes", hint.resourcePatterns().map(ResourcePatternHints::getExcludes)
|
||||
.flatMap(List::stream).distinct().map(this::toAttributes).toList());
|
||||
return attributes;
|
||||
}
|
||||
@@ -66,13 +69,15 @@ class ResourceHintsWriter {
|
||||
|
||||
private Map<String, Object> toAttributes(ResourceBundleHint hint) {
|
||||
Map<String, Object> attributes = new LinkedHashMap<>();
|
||||
handleCondition(attributes, hint);
|
||||
attributes.put("name", hint.getBaseName());
|
||||
return attributes;
|
||||
}
|
||||
|
||||
private Map<String, Object> toAttributes(String pattern) {
|
||||
private Map<String, Object> toAttributes(ResourcePatternHint hint) {
|
||||
Map<String, Object> attributes = new LinkedHashMap<>();
|
||||
attributes.put("pattern", patternToRegexp(pattern));
|
||||
handleCondition(attributes, hint);
|
||||
attributes.put("pattern", patternToRegexp(hint.getPattern()));
|
||||
return attributes;
|
||||
}
|
||||
|
||||
@@ -96,4 +101,12 @@ class ResourceHintsWriter {
|
||||
}
|
||||
}
|
||||
|
||||
private void handleCondition(Map<String, Object> attributes, ConditionalHint hint) {
|
||||
if (hint.getReachableType() != null) {
|
||||
Map<String, Object> conditionAttributes = new LinkedHashMap<>();
|
||||
conditionAttributes.put("typeReachable", hint.getReachableType());
|
||||
attributes.put("condition", conditionAttributes);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2002-2022 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.aot.nativex;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.aot.hint.ConditionalHint;
|
||||
import org.springframework.aot.hint.JavaSerializationHint;
|
||||
import org.springframework.aot.hint.SerializationHints;
|
||||
|
||||
/**
|
||||
* Write a {@link SerializationHints} to the JSON output expected by the
|
||||
* GraalVM {@code native-image} compiler, typically named
|
||||
* {@code serialization-config.json}.
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
* @author Stephane Nicoll
|
||||
* @author Brian Clozel
|
||||
* @since 6.0
|
||||
* @see <a href="https://www.graalvm.org/22.1/reference-manual/native-image/BuildConfiguration/">Native Image Build Configuration</a>
|
||||
*/
|
||||
class SerializationHintsWriter {
|
||||
|
||||
public static final SerializationHintsWriter INSTANCE = new SerializationHintsWriter();
|
||||
|
||||
public void write(BasicJsonWriter writer, SerializationHints hints) {
|
||||
writer.writeArray(hints.javaSerialization().map(this::toAttributes).toList());
|
||||
}
|
||||
|
||||
private Map<String, Object> toAttributes(JavaSerializationHint serializationHint) {
|
||||
LinkedHashMap<String, Object> attributes = new LinkedHashMap<>();
|
||||
handleCondition(attributes, serializationHint);
|
||||
attributes.put("name", serializationHint.getType());
|
||||
return attributes;
|
||||
}
|
||||
|
||||
private void handleCondition(Map<String, Object> attributes, ConditionalHint hint) {
|
||||
if (hint.getReachableType() != null) {
|
||||
Map<String, Object> conditionAttributes = new LinkedHashMap<>();
|
||||
conditionAttributes.put("typeReachable", hint.getReachableType());
|
||||
attributes.put("condition", conditionAttributes);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user