Comparators entry point with generically typed factory methods
Issue: SPR-14779
This commit is contained in:
parent
07dd61eabd
commit
5f531a7a7d
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
|
@ -52,7 +52,6 @@ import org.springframework.core.convert.converter.Converter;
|
|||
import org.springframework.core.convert.converter.ConvertingComparator;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.util.comparator.CompoundComparator;
|
||||
import org.springframework.util.comparator.InstanceComparator;
|
||||
|
||||
/**
|
||||
|
@ -73,8 +72,7 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
|
|||
private static final Comparator<Method> METHOD_COMPARATOR;
|
||||
|
||||
static {
|
||||
CompoundComparator<Method> comparator = new CompoundComparator<>();
|
||||
comparator.addComparator(new ConvertingComparator<>(
|
||||
Comparator<Method> adviceKindComparator = new ConvertingComparator<>(
|
||||
new InstanceComparator<>(
|
||||
Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class),
|
||||
new Converter<Method, Annotation>() {
|
||||
|
@ -84,15 +82,15 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
|
|||
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(method);
|
||||
return (annotation != null ? annotation.getAnnotation() : null);
|
||||
}
|
||||
}));
|
||||
comparator.addComparator(new ConvertingComparator<>(
|
||||
});
|
||||
Comparator<Method> methodNameComparator = new ConvertingComparator<>(
|
||||
new Converter<Method, String>() {
|
||||
@Override
|
||||
public String convert(Method method) {
|
||||
return method.getName();
|
||||
}
|
||||
}));
|
||||
METHOD_COMPARATOR = comparator;
|
||||
});
|
||||
METHOD_COMPARATOR = adviceKindComparator.thenComparing(methodNameComparator);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -21,12 +21,12 @@ import java.util.Map;
|
|||
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.comparator.ComparableComparator;
|
||||
import org.springframework.util.comparator.Comparators;
|
||||
|
||||
/**
|
||||
* A {@link Comparator} that converts values before they are compared. The specified
|
||||
* {@link Converter} will be used to convert each value before it passed to the underlying
|
||||
* {@code Comparator}.
|
||||
* A {@link Comparator} that converts values before they are compared.
|
||||
* The specified {@link Converter} will be used to convert each value
|
||||
* before it passed to the underlying {@code Comparator}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @since 3.2
|
||||
|
@ -44,9 +44,8 @@ public class ConvertingComparator<S, T> implements Comparator<S> {
|
|||
* Create a new {@link ConvertingComparator} instance.
|
||||
* @param converter the converter
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public ConvertingComparator(Converter<S, T> converter) {
|
||||
this(ComparableComparator.INSTANCE, converter);
|
||||
this(Comparators.comparable(), converter);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -62,7 +61,7 @@ public class ConvertingComparator<S, T> implements Comparator<S> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link ComparableComparator} instance.
|
||||
* Create a new {@code ConvertingComparator} instance.
|
||||
* @param comparator the underlying comparator
|
||||
* @param conversionService the conversion service
|
||||
* @param targetType the target type
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
|
@ -20,23 +20,24 @@ import java.io.Serializable;
|
|||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
* A Comparator for Boolean objects that can sort either true or false first.
|
||||
* A {@link Comparator} for {@link Boolean} objects that can sort either
|
||||
* {@code true} or {@code false} first.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 1.2.2
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public final class BooleanComparator implements Comparator<Boolean>, Serializable {
|
||||
public class BooleanComparator implements Comparator<Boolean>, Serializable {
|
||||
|
||||
/**
|
||||
* A shared default instance of this comparator, treating true lower
|
||||
* than false.
|
||||
* A shared default instance of this comparator,
|
||||
* treating {@code true} lower than {@code false}.
|
||||
*/
|
||||
public static final BooleanComparator TRUE_LOW = new BooleanComparator(true);
|
||||
|
||||
/**
|
||||
* A shared default instance of this comparator, treating true higher
|
||||
* than false.
|
||||
* A shared default instance of this comparator,
|
||||
* treating {@code true} higher than {@code false}.
|
||||
*/
|
||||
public static final BooleanComparator TRUE_HIGH = new BooleanComparator(false);
|
||||
|
||||
|
@ -64,20 +65,16 @@ public final class BooleanComparator implements Comparator<Boolean>, Serializabl
|
|||
return (v1 ^ v2) ? ((v1 ^ this.trueLow) ? 1 : -1) : 0;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof BooleanComparator)) {
|
||||
return false;
|
||||
}
|
||||
return (this.trueLow == ((BooleanComparator) obj).trueLow);
|
||||
return (this == obj ||
|
||||
(obj instanceof BooleanComparator && (this.trueLow == ((BooleanComparator) obj).trueLow)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (this.trueLow ? -1 : 1) * getClass().hashCode();
|
||||
return getClass().hashCode() * (this.trueLow ? -1 : 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
|
@ -29,9 +29,14 @@ import java.util.Comparator;
|
|||
*/
|
||||
public class ComparableComparator<T extends Comparable<T>> implements Comparator<T> {
|
||||
|
||||
/**
|
||||
* A shared instance of this default comparator
|
||||
* @see Comparators#comparable()
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public static final ComparableComparator INSTANCE = new ComparableComparator();
|
||||
|
||||
|
||||
@Override
|
||||
public int compare(T o1, T o2) {
|
||||
return o1.compareTo(o2);
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright 2002-2017 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
|
||||
*
|
||||
* http://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.util.comparator;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
* Convenient entry point with generically typed factory methods
|
||||
* for common Spring {@link Comparator} variants.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 5.0
|
||||
*/
|
||||
public abstract class Comparators {
|
||||
|
||||
/**
|
||||
* Return a {@link Comparable} adapter.
|
||||
* @see ComparableComparator#INSTANCE
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> Comparator<T> comparable() {
|
||||
return ComparableComparator.INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a {@link Comparable} adapter which accepts
|
||||
* null values and sorts them lower than non-null values.
|
||||
* @see NullSafeComparator#NULLS_LOW
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> Comparator<T> nullsLow() {
|
||||
return NullSafeComparator.NULLS_LOW;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a decorator for the given comparator which accepts
|
||||
* null values and sorts them lower than non-null values.
|
||||
* @see NullSafeComparator#NullSafeComparator(boolean)
|
||||
*/
|
||||
public static <T> Comparator<T> nullsLow(Comparator<T> comparator) {
|
||||
return new NullSafeComparator<T>(comparator, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a {@link Comparable} adapter which accepts
|
||||
* null values and sorts them higher than non-null values.
|
||||
* @see NullSafeComparator#NULLS_HIGH
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> Comparator<T> nullsHigh() {
|
||||
return NullSafeComparator.NULLS_HIGH;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a decorator for the given comparator which accepts
|
||||
* null values and sorts them higher than non-null values.
|
||||
* @see NullSafeComparator#NullSafeComparator(boolean)
|
||||
*/
|
||||
public static <T> Comparator<T> nullsHigh(Comparator<T> comparator) {
|
||||
return new NullSafeComparator<T>(comparator, false);
|
||||
}
|
||||
|
||||
}
|
|
@ -36,7 +36,10 @@ import org.springframework.util.Assert;
|
|||
* @author Keith Donald
|
||||
* @author Juergen Hoeller
|
||||
* @since 1.2.2
|
||||
* @deprecated as of Spring Framework 5.0, in favor of the standard JDK 8
|
||||
* {@link Comparator#thenComparing(Comparator)}
|
||||
*/
|
||||
@Deprecated
|
||||
@SuppressWarnings({"serial", "rawtypes"})
|
||||
public class CompoundComparator<T> implements Comparator<T>, Serializable {
|
||||
|
||||
|
@ -165,10 +168,11 @@ public class CompoundComparator<T> implements Comparator<T>, Serializable {
|
|||
return this.comparators.size();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public int compare(T o1, T o2) {
|
||||
Assert.state(this.comparators.size() > 0,
|
||||
Assert.state(!this.comparators.isEmpty(),
|
||||
"No sort definitions have been added to this CompoundComparator to compare");
|
||||
for (InvertibleComparator comparator : this.comparators) {
|
||||
int result = comparator.compare(o1, o2);
|
||||
|
@ -179,6 +183,7 @@ public class CompoundComparator<T> implements Comparator<T>, Serializable {
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public boolean equals(Object obj) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
|
@ -27,12 +27,12 @@ import org.springframework.util.Assert;
|
|||
*
|
||||
* <p>Only the specified {@code instanceOrder} classes are considered during comparison.
|
||||
* If two objects are both instances of the ordered type this comparator will return a
|
||||
* {@code 0}. Consider combining with a {@link CompoundComparator} if additional sorting
|
||||
* is required.
|
||||
* {@code 0}. Consider combining with {@link Comparator#thenComparing(Comparator)}
|
||||
* if additional sorting is required.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @since 3.2
|
||||
* @see CompoundComparator
|
||||
* @see Comparator#thenComparing(Comparator)
|
||||
* @param <T> the type of objects being compared
|
||||
*/
|
||||
public class InstanceComparator<T> implements Comparator<T> {
|
||||
|
@ -46,7 +46,7 @@ public class InstanceComparator<T> implements Comparator<T> {
|
|||
* objects. Classes earlier in the list will be given a higher priority.
|
||||
*/
|
||||
public InstanceComparator(Class<?>... instanceOrder) {
|
||||
Assert.notNull(instanceOrder, "'instanceOrder' must not be null");
|
||||
Assert.notNull(instanceOrder, "'instanceOrder' array must not be null");
|
||||
this.instanceOrder = instanceOrder;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
|
@ -29,7 +29,10 @@ import org.springframework.util.Assert;
|
|||
* @author Keith Donald
|
||||
* @author Juergen Hoeller
|
||||
* @since 1.2.2
|
||||
* @deprecated as of Spring Framework 5.0, in favor of the standard JDK 8
|
||||
* {@link Comparator#reversed()}
|
||||
*/
|
||||
@Deprecated
|
||||
@SuppressWarnings("serial")
|
||||
public class InvertibleComparator<T> implements Comparator<T>, Serializable {
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
|
@ -34,6 +34,7 @@ public class NullSafeComparator<T> implements Comparator<T> {
|
|||
/**
|
||||
* A shared default instance of this comparator, treating nulls lower
|
||||
* than non-null objects.
|
||||
* @see Comparators#nullsLow()
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public static final NullSafeComparator NULLS_LOW = new NullSafeComparator<>(true);
|
||||
|
@ -41,10 +42,12 @@ public class NullSafeComparator<T> implements Comparator<T> {
|
|||
/**
|
||||
* A shared default instance of this comparator, treating nulls higher
|
||||
* than non-null objects.
|
||||
* @see Comparators#nullsHigh()
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public static final NullSafeComparator NULLS_HIGH = new NullSafeComparator<>(false);
|
||||
|
||||
|
||||
private final Comparator<T> nonNullComparator;
|
||||
|
||||
private final boolean nullsLow;
|
||||
|
@ -64,9 +67,9 @@ public class NullSafeComparator<T> implements Comparator<T> {
|
|||
* @see #NULLS_LOW
|
||||
* @see #NULLS_HIGH
|
||||
*/
|
||||
@SuppressWarnings({ "unchecked", "rawtypes"})
|
||||
@SuppressWarnings("unchecked")
|
||||
private NullSafeComparator(boolean nullsLow) {
|
||||
this.nonNullComparator = new ComparableComparator();
|
||||
this.nonNullComparator = ComparableComparator.INSTANCE;
|
||||
this.nullsLow = nullsLow;
|
||||
}
|
||||
|
||||
|
@ -80,7 +83,7 @@ public class NullSafeComparator<T> implements Comparator<T> {
|
|||
* @param nullsLow whether to treat nulls lower or higher than non-null objects
|
||||
*/
|
||||
public NullSafeComparator(Comparator<T> comparator, boolean nullsLow) {
|
||||
Assert.notNull(comparator, "The non-null comparator is required");
|
||||
Assert.notNull(comparator, "Non-null Comparator is required");
|
||||
this.nonNullComparator = comparator;
|
||||
this.nullsLow = nullsLow;
|
||||
}
|
||||
|
@ -100,6 +103,7 @@ public class NullSafeComparator<T> implements Comparator<T> {
|
|||
return this.nonNullComparator.compare(o1, o2);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public boolean equals(Object obj) {
|
||||
|
@ -115,7 +119,7 @@ public class NullSafeComparator<T> implements Comparator<T> {
|
|||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (this.nullsLow ? -1 : 1) * this.nonNullComparator.hashCode();
|
||||
return this.nonNullComparator.hashCode() * (this.nullsLow ? -1 : 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -33,7 +33,6 @@ import org.springframework.util.InvalidMimeTypeException;
|
|||
import org.springframework.util.MimeType;
|
||||
import org.springframework.util.MimeTypeUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.util.comparator.CompoundComparator;
|
||||
|
||||
/**
|
||||
* A sub-class of {@link MimeType} that adds support for quality parameters as defined
|
||||
|
@ -644,8 +643,8 @@ public class MediaType extends MimeType implements Serializable {
|
|||
public static void sortBySpecificityAndQuality(List<MediaType> mediaTypes) {
|
||||
Assert.notNull(mediaTypes, "'mediaTypes' must not be null");
|
||||
if (mediaTypes.size() > 1) {
|
||||
Collections.sort(mediaTypes, new CompoundComparator<>(
|
||||
MediaType.SPECIFICITY_COMPARATOR, MediaType.QUALITY_VALUE_COMPARATOR));
|
||||
Collections.sort(mediaTypes,
|
||||
MediaType.SPECIFICITY_COMPARATOR.thenComparing(MediaType.QUALITY_VALUE_COMPARATOR));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue