Browse Source

Comparators entry point with generically typed factory methods

Issue: SPR-14779
pull/1329/head
Juergen Hoeller 8 years ago
parent
commit
5f531a7a7d
  1. 14
      spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/ReflectiveAspectJAdvisorFactory.java
  2. 13
      spring-core/src/main/java/org/springframework/core/convert/converter/ConvertingComparator.java
  3. 27
      spring-core/src/main/java/org/springframework/util/comparator/BooleanComparator.java
  4. 7
      spring-core/src/main/java/org/springframework/util/comparator/ComparableComparator.java
  5. 77
      spring-core/src/main/java/org/springframework/util/comparator/Comparators.java
  6. 7
      spring-core/src/main/java/org/springframework/util/comparator/CompoundComparator.java
  7. 10
      spring-core/src/main/java/org/springframework/util/comparator/InstanceComparator.java
  8. 5
      spring-core/src/main/java/org/springframework/util/comparator/InvertibleComparator.java
  9. 14
      spring-core/src/main/java/org/springframework/util/comparator/NullSafeComparator.java
  10. 5
      spring-web/src/main/java/org/springframework/http/MediaType.java

14
spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/ReflectiveAspectJAdvisorFactory.java

@ -1,5 +1,5 @@ @@ -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; @@ -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 @@ -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 @@ -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);
}

13
spring-core/src/main/java/org/springframework/core/convert/converter/ConvertingComparator.java

@ -21,12 +21,12 @@ import java.util.Map; @@ -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> { @@ -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> { @@ -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

27
spring-core/src/main/java/org/springframework/util/comparator/BooleanComparator.java

@ -1,5 +1,5 @@ @@ -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; @@ -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 @@ -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

7
spring-core/src/main/java/org/springframework/util/comparator/ComparableComparator.java

@ -1,5 +1,5 @@ @@ -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; @@ -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);

77
spring-core/src/main/java/org/springframework/util/comparator/Comparators.java

@ -0,0 +1,77 @@ @@ -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);
}
}

7
spring-core/src/main/java/org/springframework/util/comparator/CompoundComparator.java

@ -36,7 +36,10 @@ import org.springframework.util.Assert; @@ -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 { @@ -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 { @@ -179,6 +183,7 @@ public class CompoundComparator<T> implements Comparator<T>, Serializable {
return 0;
}
@Override
@SuppressWarnings("unchecked")
public boolean equals(Object obj) {

10
spring-core/src/main/java/org/springframework/util/comparator/InstanceComparator.java

@ -1,5 +1,5 @@ @@ -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; @@ -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> { @@ -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;
}

5
spring-core/src/main/java/org/springframework/util/comparator/InvertibleComparator.java

@ -1,5 +1,5 @@ @@ -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; @@ -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 {

14
spring-core/src/main/java/org/springframework/util/comparator/NullSafeComparator.java

@ -1,5 +1,5 @@ @@ -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> { @@ -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> { @@ -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> { @@ -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> { @@ -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> { @@ -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> { @@ -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

5
spring-web/src/main/java/org/springframework/http/MediaType.java

@ -33,7 +33,6 @@ import org.springframework.util.InvalidMimeTypeException; @@ -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 { @@ -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…
Cancel
Save