Polishing
This commit is contained in:
parent
18a3b52d5e
commit
37b110a181
|
@ -181,6 +181,7 @@ public interface GeneratedFiles {
|
|||
*/
|
||||
void handleFile(Kind kind, String path, ThrowingConsumer<FileHandler> handler);
|
||||
|
||||
|
||||
private static String getClassNamePath(String className) {
|
||||
Assert.hasLength(className, "'className' must not be empty");
|
||||
validatePackage(ClassUtils.getPackageName(className), className);
|
||||
|
@ -232,13 +233,12 @@ public interface GeneratedFiles {
|
|||
* generated using CGLIB.
|
||||
*/
|
||||
CLASS
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Provide access to a particular file and offer convenient methods to retrieve,
|
||||
* save, or override its content.
|
||||
*
|
||||
* @since 6.2
|
||||
*/
|
||||
abstract class FileHandler {
|
||||
|
@ -292,7 +292,6 @@ public interface GeneratedFiles {
|
|||
}
|
||||
|
||||
protected abstract void copy(InputStreamSource content, boolean override);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -48,7 +48,8 @@ import org.springframework.aot.hint.MemberCategory;
|
|||
* packages can use this annotation as well.
|
||||
*
|
||||
* <p>To register reflection hints for the type itself, only member categories
|
||||
* should be specified:<pre><code class="java">
|
||||
* should be specified:
|
||||
* <pre><code class="java">
|
||||
* @Component
|
||||
* @RegisterReflection(memberCategories = INVOKE_PUBLIC_METHODS)
|
||||
* class MyComponent {
|
||||
|
@ -56,7 +57,8 @@ import org.springframework.aot.hint.MemberCategory;
|
|||
* }</code></pre>
|
||||
*
|
||||
* <p>Reflection hints can be registered from a method. In this case, at least
|
||||
* one target class should be specified:<pre><code class="java">
|
||||
* one target class should be specified:
|
||||
* <pre><code class="java">
|
||||
* class MyProcessor {
|
||||
*
|
||||
* @RegisterReflection(classes = CustomerEntry.class, memberCategories = PUBLIC_FIELDS)
|
||||
|
@ -81,11 +83,10 @@ public @interface RegisterReflection {
|
|||
|
||||
/**
|
||||
* Classes for which reflection hints should be registered. Consider using
|
||||
* {@link #classNames()} for classes that are not public in the current
|
||||
* scope. If both {@code classes} and {@code classNames} are specified, they
|
||||
* are merged in a single set.
|
||||
* <p>
|
||||
* By default, the annotated type is the target of the registration. When
|
||||
* {@link #classNames()} for classes that are not public in the current scope.
|
||||
* If both {@code classes} and {@code classNames} are specified, they are
|
||||
* merged into a single set.
|
||||
* <p>By default, the annotated type is the target of the registration. When
|
||||
* placed on a method, at least one class must be specified.
|
||||
* @see #classNames()
|
||||
*/
|
||||
|
|
|
@ -45,12 +45,11 @@ public class RegisterReflectionReflectiveProcessor implements ReflectiveProcesso
|
|||
|
||||
private static final Log logger = LogFactory.getLog(RegisterReflectionReflectiveProcessor.class);
|
||||
|
||||
|
||||
@Override
|
||||
public final void registerReflectionHints(ReflectionHints hints, AnnotatedElement element) {
|
||||
RegisterReflection annotation = AnnotatedElementUtils.getMergedAnnotation(
|
||||
element, RegisterReflection.class);
|
||||
Assert.notNull(annotation, "Element must be annotated with @" + RegisterReflection.class.getSimpleName()
|
||||
+ ": " + element);
|
||||
RegisterReflection annotation = AnnotatedElementUtils.getMergedAnnotation(element, RegisterReflection.class);
|
||||
Assert.notNull(annotation, () -> "Element must be annotated with @RegisterReflection: " + element);
|
||||
ReflectionRegistration registration = parse(element, annotation);
|
||||
registerReflectionHints(hints, registration);
|
||||
}
|
||||
|
@ -65,12 +64,10 @@ public class RegisterReflectionReflectiveProcessor implements ReflectiveProcesso
|
|||
allClassNames.add(clazz);
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException("At least one class must be specified, "
|
||||
+ "could not detect target from '" + element + "'");
|
||||
throw new IllegalStateException("At least one class must be specified: " + element);
|
||||
}
|
||||
}
|
||||
return new ReflectionRegistration(allClassNames.toArray(new Class<?>[0]),
|
||||
annotation.memberCategories());
|
||||
return new ReflectionRegistration(allClassNames.toArray(new Class<?>[0]), annotation.memberCategories());
|
||||
}
|
||||
|
||||
protected void registerReflectionHints(ReflectionHints hints, ReflectionRegistration registration) {
|
||||
|
@ -89,11 +86,15 @@ public class RegisterReflectionReflectiveProcessor implements ReflectiveProcesso
|
|||
return ClassUtils.forName(className, getClass().getClassLoader());
|
||||
}
|
||||
catch (Exception ex) {
|
||||
logger.warn("Ignoring '" + className + "': " + ex.getMessage());
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("Ignoring '" + className + "': " + ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected record ReflectionRegistration(Class<?>[] classes, MemberCategory[] memberCategories) {}
|
||||
|
||||
protected record ReflectionRegistration(Class<?>[] classes, MemberCategory[] memberCategories) {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.springframework.lang.Nullable;
|
|||
* used when converting property values from one type to another.
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @author Stephane Nicoll
|
||||
* @since 3.1
|
||||
*/
|
||||
public interface ConfigurablePropertyResolver extends PropertyResolver {
|
||||
|
@ -75,9 +76,8 @@ public interface ConfigurablePropertyResolver extends PropertyResolver {
|
|||
void setValueSeparator(@Nullable String valueSeparator);
|
||||
|
||||
/**
|
||||
* Specify the escape character to use to ignore placeholder prefix
|
||||
* or value separator, or {@code null} if no escaping should take
|
||||
* place.
|
||||
* Specify the escape character to use to ignore placeholder prefix or
|
||||
* value separator, or {@code null} if no escaping should take place.
|
||||
* @since 6.2
|
||||
*/
|
||||
void setEscapeCharacter(@Nullable Character escapeCharacter);
|
||||
|
|
|
@ -67,6 +67,7 @@ public final class JettyDataBuffer implements PooledDataBuffer {
|
|||
this.chunk = null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isAllocated() {
|
||||
return this.refCount.get() > 0;
|
||||
|
@ -74,14 +75,7 @@ public final class JettyDataBuffer implements PooledDataBuffer {
|
|||
|
||||
@Override
|
||||
public PooledDataBuffer retain() {
|
||||
int result = this.refCount.updateAndGet(c -> {
|
||||
if (c != 0) {
|
||||
return c + 1;
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
int result = this.refCount.updateAndGet(c -> (c != 0 ? c + 1 : 0));
|
||||
if (result != 0 && this.chunk != null) {
|
||||
this.chunk.retain();
|
||||
}
|
||||
|
@ -107,7 +101,7 @@ public final class JettyDataBuffer implements PooledDataBuffer {
|
|||
return this.chunk.release();
|
||||
}
|
||||
else {
|
||||
return result == 0;
|
||||
return (result == 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -116,6 +110,7 @@ public final class JettyDataBuffer implements PooledDataBuffer {
|
|||
return this.bufferFactory;
|
||||
}
|
||||
|
||||
|
||||
// delegation
|
||||
|
||||
@Override
|
||||
|
@ -305,15 +300,16 @@ public final class JettyDataBuffer implements PooledDataBuffer {
|
|||
return this.delegate.toString(index, length, charset);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.delegate.hashCode();
|
||||
public boolean equals(Object other) {
|
||||
return (this == other || (other instanceof JettyDataBuffer otherBuffer &&
|
||||
this.delegate.equals(otherBuffer.delegate)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return this == o || (o instanceof JettyDataBuffer other &&
|
||||
this.delegate.equals(other.delegate));
|
||||
public int hashCode() {
|
||||
return this.delegate.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -322,13 +318,13 @@ public final class JettyDataBuffer implements PooledDataBuffer {
|
|||
readPosition(), writePosition(), capacity());
|
||||
}
|
||||
|
||||
|
||||
private static final class JettyByteBufferIterator implements ByteBufferIterator {
|
||||
|
||||
private final ByteBufferIterator delegate;
|
||||
|
||||
private final Content.Chunk chunk;
|
||||
|
||||
|
||||
public JettyByteBufferIterator(ByteBufferIterator delegate, Content.Chunk chunk) {
|
||||
Assert.notNull(delegate, "Delegate must not be null");
|
||||
Assert.notNull(chunk, "Chunk must not be null");
|
||||
|
@ -338,7 +334,6 @@ public final class JettyDataBuffer implements PooledDataBuffer {
|
|||
this.chunk.retain();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
this.delegate.close();
|
||||
|
|
|
@ -105,4 +105,5 @@ public class JettyDataBufferFactory implements DataBufferFactory {
|
|||
public boolean isDirect() {
|
||||
return this.delegate.isDirect();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,8 +23,8 @@ import java.lang.annotation.Target;
|
|||
/**
|
||||
* Specifies that the method return value must be used.
|
||||
*
|
||||
* <p>Inspired from {@code org.jetbrains.annotations.CheckReturnValue}, this variant
|
||||
* has been introduce in the {@code org.springframework.lang} package to avoid
|
||||
* <p>Inspired by {@code org.jetbrains.annotations.CheckReturnValue}, this variant
|
||||
* has been introduced in the {@code org.springframework.lang} package to avoid
|
||||
* requiring an extra dependency, while still following similar semantics.
|
||||
*
|
||||
* <p>This annotation should not be used if the return value of the method
|
||||
|
|
|
@ -28,9 +28,9 @@ import java.lang.annotation.Target;
|
|||
* just describes how the code works and doesn't add any functionality by means of
|
||||
* code generation.
|
||||
*
|
||||
* <p>Inspired from {@code org.jetbrains.annotations.Contract}, this variant has
|
||||
* been introduce in the {@code org.springframework.lang} package to avoid requiring
|
||||
* an extra dependency, while still following the same semantics.
|
||||
* <p>Inspired by {@code org.jetbrains.annotations.Contract}, this variant has
|
||||
* been introduced in the {@code org.springframework.lang} package to avoid
|
||||
* requiring an extra dependency, while still following the same semantics.
|
||||
*
|
||||
* <p>Method contract has the following syntax:
|
||||
* <pre>{@code
|
||||
|
@ -85,4 +85,5 @@ public @interface Contract {
|
|||
* Contains the contract clauses describing causal relations between call arguments and the returned value.
|
||||
*/
|
||||
String value() default "";
|
||||
|
||||
}
|
||||
|
|
|
@ -1502,8 +1502,7 @@ public abstract class ClassUtils {
|
|||
* (if there is one). For {@code toString()}, it may traverse as far as {@link Object}.
|
||||
* @param method the method to be invoked, potentially from an implementation class
|
||||
* @param targetClass the target class to invoke the method on, or {@code null} if unknown
|
||||
* @return the corresponding publicly accessible method, or the original method if none
|
||||
* found
|
||||
* @return the corresponding publicly accessible method, or the original method if none found
|
||||
* @since 6.2
|
||||
* @see #getInterfaceMethodIfPossible(Method, Class)
|
||||
* @see #getMostSpecificMethod(Method, Class)
|
||||
|
|
|
@ -515,7 +515,6 @@ public abstract class CollectionUtils {
|
|||
* Return a (partially unmodifiable) map that combines the provided two
|
||||
* maps. Invoking {@link Map#put(Object, Object)} or {@link Map#putAll(Map)}
|
||||
* on the returned map results in an {@link UnsupportedOperationException}.
|
||||
*
|
||||
* <p>In the case of a key collision, {@code first} takes precedence over
|
||||
* {@code second}. In other words, entries in {@code second} with a key
|
||||
* that is also mapped by {@code first} are effectively ignored.
|
||||
|
@ -535,7 +534,6 @@ public abstract class CollectionUtils {
|
|||
* {@link UnsupportedOperationException} {@code putFunction} is
|
||||
* {@code null}. The same applies to {@link Map#putAll(Map)} and
|
||||
* {@code putAllFunction}.
|
||||
*
|
||||
* <p>In the case of a key collision, {@code first} takes precedence over
|
||||
* {@code second}. In other words, entries in {@code second} with a key
|
||||
* that is also mapped by {@code first} are effectively ignored.
|
||||
|
|
|
@ -43,6 +43,7 @@ class CompositeCollection<E> implements Collection<E> {
|
|||
this.second = second;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return this.first.size() + this.second.size();
|
||||
|
@ -160,4 +161,5 @@ class CompositeCollection<E> implements Collection<E> {
|
|||
this.first.clear();
|
||||
this.second.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -186,4 +186,5 @@ final class CompositeMap<K, V> implements Map<K, V> {
|
|||
sb.append(',').append(' ');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,6 +18,8 @@ package org.springframework.util;
|
|||
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Composite set that combines two other sets. This type is only exposed through
|
||||
* {@link CompositeMap#keySet()} and {@link CompositeMap#entrySet()}.
|
||||
|
@ -34,24 +36,19 @@ final class CompositeSet<E> extends CompositeCollection<E> implements Set<E> {
|
|||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this) {
|
||||
public boolean equals(@Nullable Object other) {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
else if (obj instanceof Set<?> set) {
|
||||
if (set.size() != size()) {
|
||||
return false;
|
||||
}
|
||||
if (other instanceof Set<?> otherSet && size() == otherSet.size()) {
|
||||
try {
|
||||
return containsAll(set);
|
||||
return containsAll(otherSet);
|
||||
}
|
||||
catch (ClassCastException | NullPointerException ignored) {
|
||||
return false;
|
||||
// fall through
|
||||
}
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -64,4 +61,5 @@ final class CompositeSet<E> extends CompositeCollection<E> implements Set<E> {
|
|||
}
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.util.function.Predicate;
|
|||
/**
|
||||
* Collection that filters out values that do not match a predicate.
|
||||
* This type is used by {@link CompositeMap}.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 6.2
|
||||
* @param <E> the type of elements maintained by this collection
|
||||
|
@ -38,11 +39,11 @@ class FilteredCollection<E> extends AbstractCollection<E> {
|
|||
public FilteredCollection(Collection<E> delegate, Predicate<E> filter) {
|
||||
Assert.notNull(delegate, "Delegate must not be null");
|
||||
Assert.notNull(filter, "Filter must not be null");
|
||||
|
||||
this.delegate = delegate;
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
int size = 0;
|
||||
|
@ -87,4 +88,5 @@ class FilteredCollection<E> extends AbstractCollection<E> {
|
|||
public void clear() {
|
||||
this.delegate.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import org.springframework.lang.Nullable;
|
|||
/**
|
||||
* Iterator that filters out values that do not match a predicate.
|
||||
* This type is used by {@link CompositeMap}.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 6.2
|
||||
* @param <E> the type of elements returned by this iterator
|
||||
|
@ -44,7 +45,6 @@ final class FilteredIterator<E> implements Iterator<E> {
|
|||
public FilteredIterator(Iterator<E> delegate, Predicate<E> filter) {
|
||||
Assert.notNull(delegate, "Delegate must not be null");
|
||||
Assert.notNull(filter, "Filter must not be null");
|
||||
|
||||
this.delegate = delegate;
|
||||
this.filter = filter;
|
||||
}
|
||||
|
@ -83,4 +83,5 @@ final class FilteredIterator<E> implements Iterator<E> {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.springframework.lang.Nullable;
|
|||
/**
|
||||
* Map that filters out values that do not match a predicate.
|
||||
* This type is used by {@link CompositeMap}.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 6.2
|
||||
* @param <K> the type of keys maintained by this map
|
||||
|
@ -41,11 +42,11 @@ final class FilteredMap<K, V> extends AbstractMap<K, V> {
|
|||
public FilteredMap(Map<K, V> delegate, Predicate<K> filter) {
|
||||
Assert.notNull(delegate, "Delegate must not be null");
|
||||
Assert.notNull(filter, "Filter must not be null");
|
||||
|
||||
this.delegate = delegate;
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Set<Entry<K, V>> entrySet() {
|
||||
return new FilteredSet<>(this.delegate.entrySet(), entry -> this.filter.test(entry.getKey()));
|
||||
|
|
|
@ -19,9 +19,12 @@ package org.springframework.util;
|
|||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Set that filters out values that do not match a predicate.
|
||||
* This type is used by {@link CompositeMap}.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 6.2
|
||||
* @param <E> the type of elements maintained by this set
|
||||
|
@ -32,25 +35,21 @@ final class FilteredSet<E> extends FilteredCollection<E> implements Set<E> {
|
|||
super(delegate, filter);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this) {
|
||||
public boolean equals(@Nullable Object other) {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
else if (obj instanceof Set<?> set) {
|
||||
if (set.size() != size()) {
|
||||
return false;
|
||||
}
|
||||
if (other instanceof Set<?> otherSet && size() == otherSet.size()) {
|
||||
try {
|
||||
return containsAll(set);
|
||||
return containsAll(otherSet);
|
||||
}
|
||||
catch (ClassCastException | NullPointerException ignored) {
|
||||
return false;
|
||||
// fall through
|
||||
}
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -63,4 +62,5 @@ final class FilteredSet<E> extends FilteredCollection<E> implements Set<E> {
|
|||
}
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -62,6 +62,7 @@ final class MultiToSingleValueMapAdapter<K, V> implements Map<K, V>, Serializabl
|
|||
this.targetMap = targetMap;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return this.targetMap.size();
|
||||
|
@ -166,8 +167,6 @@ final class MultiToSingleValueMapAdapter<K, V> implements Map<K, V>, Serializabl
|
|||
return values;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public Set<Entry<K, V>> entrySet() {
|
||||
Set<Entry<K, V>> entries = this.entries;
|
||||
|
@ -206,51 +205,6 @@ final class MultiToSingleValueMapAdapter<K, V> implements Map<K, V>, Serializabl
|
|||
this.targetMap.forEach((k, vs) -> action.accept(k, vs.get(0)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
else if (o instanceof Map<?,?> other) {
|
||||
if (this.size() != other.size()) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
for (Entry<K, V> e : entrySet()) {
|
||||
K key = e.getKey();
|
||||
V value = e.getValue();
|
||||
if (value == null) {
|
||||
if (other.get(key) != null || !other.containsKey(key)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!value.equals(other.get(key))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (ClassCastException | NullPointerException ignore) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.targetMap.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.targetMap.toString();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private V adaptValue(@Nullable List<V> values) {
|
||||
if (!CollectionUtils.isEmpty(values)) {
|
||||
|
@ -271,4 +225,45 @@ final class MultiToSingleValueMapAdapter<K, V> implements Map<K, V>, Serializabl
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object other) {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
if (other instanceof Map<?,?> otherMap && size() == otherMap.size()) {
|
||||
try {
|
||||
for (Entry<K, V> e : entrySet()) {
|
||||
K key = e.getKey();
|
||||
V value = e.getValue();
|
||||
if (value == null) {
|
||||
if (otherMap.get(key) != null || !otherMap.containsKey(key)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!value.equals(otherMap.get(key))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (ClassCastException | NullPointerException ignored) {
|
||||
// fall through
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.targetMap.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.targetMap.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -97,8 +97,9 @@ public interface MultiValueMap<K, V> extends Map<K, List<V>> {
|
|||
Map<K, V> toSingleValueMap();
|
||||
|
||||
/**
|
||||
* Return this map as a {@code Map} with the first values contained in this {@code MultiValueMap}.
|
||||
* The difference between this method and {@link #toSingleValueMap()} is
|
||||
* Return this map as a {@code Map} with the first values contained in this
|
||||
* {@code MultiValueMap}.
|
||||
* <p>The difference between this method and {@link #toSingleValueMap()} is
|
||||
* that this method returns a view of the entries of this map, whereas
|
||||
* the latter returns a copy.
|
||||
* @return a single value representation of this map
|
||||
|
@ -112,9 +113,9 @@ public interface MultiValueMap<K, V> extends Map<K, List<V>> {
|
|||
/**
|
||||
* Return a {@code MultiValueMap<K, V>} that adapts the given single-value
|
||||
* {@code Map<K, V>}.
|
||||
* The returned map cannot map multiple values to the same key, and doing so
|
||||
* results in an {@link UnsupportedOperationException}. Use
|
||||
* {@link #fromMultiValue(Map)} to support multiple values.
|
||||
* <p>The returned map cannot map multiple values to the same key,
|
||||
* and doing so results in an {@link UnsupportedOperationException}.
|
||||
* Use {@link #fromMultiValue(Map)} to support multiple values.
|
||||
* @param map the map to be adapted
|
||||
* @param <K> the key type
|
||||
* @param <V> the value element type
|
||||
|
|
|
@ -293,6 +293,7 @@ final class PlaceholderParser {
|
|||
return (this.escape != null && index > 0 && value.charAt(index - 1) == this.escape);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Provide the necessary context to handle and resolve underlying placeholders.
|
||||
*/
|
||||
|
@ -397,9 +398,9 @@ final class PlaceholderParser {
|
|||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A representation of the parsing of an input string.
|
||||
* @param text the raw input string
|
||||
|
@ -415,9 +416,9 @@ final class PlaceholderParser {
|
|||
throw ex.withValue(this.text);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A {@link Part} implementation that does not contain a valid placeholder.
|
||||
* @param text the raw (and resolved) text
|
||||
|
@ -428,9 +429,9 @@ final class PlaceholderParser {
|
|||
public String resolve(PartResolutionContext resolutionContext) {
|
||||
return this.text;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A {@link Part} implementation that represents a single placeholder with
|
||||
* a hard-coded fallback.
|
||||
|
@ -479,9 +480,9 @@ final class PlaceholderParser {
|
|||
parts.forEach(part -> sb.append(part.text()));
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A {@link Part} implementation that represents a single placeholder
|
||||
* containing nested placeholders.
|
||||
|
@ -503,7 +504,6 @@ final class PlaceholderParser {
|
|||
}
|
||||
return resolutionContext.handleUnresolvablePlaceholder(resolvedKey, this.text);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ public class PlaceholderResolutionException extends IllegalArgumentException {
|
|||
|
||||
private final List<String> values;
|
||||
|
||||
|
||||
/**
|
||||
* Create an exception using the specified reason for its message.
|
||||
* @param reason the reason for the exception, should contain the placeholder
|
||||
|
@ -67,6 +68,7 @@ public class PlaceholderResolutionException extends IllegalArgumentException {
|
|||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a {@link PlaceholderResolutionException} that provides
|
||||
* an additional parent value.
|
||||
|
|
|
@ -271,39 +271,35 @@ final class SingleToMultiValueMapAdapter<K, V> implements MultiValueMap<K, V>, S
|
|||
this.targetMap.forEach((k, v) -> action.accept(k, Collections.singletonList(v)));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (o == this) {
|
||||
public boolean equals(@Nullable Object other) {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
else if (o instanceof Map<?,?> other) {
|
||||
if (this.size() != other.size()) {
|
||||
return false;
|
||||
}
|
||||
if (other instanceof Map<?,?> otherMap && size() == otherMap.size()) {
|
||||
try {
|
||||
for (Entry<K, List<V>> e : entrySet()) {
|
||||
K key = e.getKey();
|
||||
List<V> values = e.getValue();
|
||||
if (values == null) {
|
||||
if (other.get(key) != null || !other.containsKey(key)) {
|
||||
if (otherMap.get(key) != null || !otherMap.containsKey(key)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!values .equals(other.get(key))) {
|
||||
if (!values.equals(otherMap.get(key))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (ClassCastException | NullPointerException ignore) {
|
||||
return false;
|
||||
catch (ClassCastException | NullPointerException ignored) {
|
||||
// fall through
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2024 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.
|
||||
|
@ -247,14 +247,14 @@ public final class DataSize implements Comparable<DataSize>, Serializable {
|
|||
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object obj) {
|
||||
if (this == obj) {
|
||||
public boolean equals(@Nullable Object other) {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null || getClass() != obj.getClass()) {
|
||||
if (other == null || getClass() != other.getClass()) {
|
||||
return false;
|
||||
}
|
||||
DataSize that = (DataSize) obj;
|
||||
DataSize that = (DataSize) other;
|
||||
return (this.bytes == that.bytes);
|
||||
}
|
||||
|
||||
|
@ -279,7 +279,6 @@ public final class DataSize implements Comparable<DataSize>, Serializable {
|
|||
DataUnit defaultUnitToUse = (defaultUnit != null ? defaultUnit : DataUnit.BYTES);
|
||||
return (StringUtils.hasLength(suffix) ? DataUnit.fromSuffix(suffix) : defaultUnitToUse);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
|||
* Tests for {@link RegisterReflectionReflectiveProcessor}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @since 6.2
|
||||
*/
|
||||
class RegisterReflectionReflectiveProcessorTests {
|
||||
|
||||
|
@ -47,6 +48,7 @@ class RegisterReflectionReflectiveProcessorTests {
|
|||
|
||||
private final RuntimeHints hints = new RuntimeHints();
|
||||
|
||||
|
||||
@Nested
|
||||
class AnnotatedTypeTests {
|
||||
|
||||
|
@ -73,6 +75,7 @@ class RegisterReflectionReflectiveProcessorTests {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Nested
|
||||
class AnnotatedMethodTests {
|
||||
|
||||
|
@ -88,11 +91,12 @@ class RegisterReflectionReflectiveProcessorTests {
|
|||
Method method = RegistrationMethodWithoutTarget.class.getDeclaredMethod("doReflection");
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> registerReflectionHints(method))
|
||||
.withMessageContaining("At least one class must be specified, could not detect target from '")
|
||||
.withMessageContaining("At least one class must be specified")
|
||||
.withMessageContaining(method.toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void assertBasicTypeHint(Class<?> type, List<String> methodNames, List<MemberCategory> memberCategories) {
|
||||
TypeHint typeHint = getTypeHint(type);
|
||||
assertThat(typeHint.methods()).map(ExecutableHint::getName).hasSameElementsAs(methodNames);
|
||||
|
@ -120,31 +124,32 @@ class RegisterReflectionReflectiveProcessorTests {
|
|||
this.processor.registerReflectionHints(this.hints.reflection(), annotatedElement);
|
||||
}
|
||||
|
||||
|
||||
@RegisterReflection(classes = SimplePojo.class, memberCategories = MemberCategory.INVOKE_PUBLIC_METHODS)
|
||||
static class RegistrationSimple {}
|
||||
static class RegistrationSimple {
|
||||
}
|
||||
|
||||
|
||||
@RegisterReflection(classes = { Number.class, Double.class },
|
||||
classNames = { "java.lang.Integer", "java.lang.Float" }, memberCategories = MemberCategory.INVOKE_PUBLIC_METHODS)
|
||||
static class RegistrationMultipleTargets {
|
||||
|
||||
}
|
||||
|
||||
|
||||
static class RegistrationMethod {
|
||||
|
||||
@RegisterReflection(classes = SimplePojo.class, memberCategories = MemberCategory.INVOKE_DECLARED_METHODS)
|
||||
private void doReflection() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static class RegistrationMethodWithoutTarget {
|
||||
|
||||
@RegisterReflection(memberCategories = MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)
|
||||
private void doReflection() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -171,6 +176,7 @@ class RegisterReflectionReflectiveProcessorTests {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@RegisterReflection(memberCategories = MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)
|
||||
static class AnnotatedSimplePojo {
|
||||
|
||||
|
@ -179,8 +185,6 @@ class RegisterReflectionReflectiveProcessorTests {
|
|||
AnnotatedSimplePojo(String test) {
|
||||
this.test = test;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue