org.springframework.core.convert.converter.ConvertingComparator Maven / Gradle / Ivy
/*
* 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.core.convert.converter;
import java.util.Comparator;
import java.util.Map;
import org.springframework.core.convert.ConversionService;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
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}.
*
* @author Phillip Webb
* @since 3.2
* @param the source type
* @param the target type
*/
public class ConvertingComparator implements Comparator {
private final Comparator comparator;
private final Converter converter;
/**
* Create a new {@link ConvertingComparator} instance.
* @param converter the converter
*/
public ConvertingComparator(Converter converter) {
this(Comparators.comparable(), converter);
}
/**
* Create a new {@link ConvertingComparator} instance.
* @param comparator the underlying comparator used to compare the converted values
* @param converter the converter
*/
public ConvertingComparator(Comparator comparator, Converter converter) {
Assert.notNull(comparator, "Comparator must not be null");
Assert.notNull(converter, "Converter must not be null");
this.comparator = comparator;
this.converter = converter;
}
/**
* Create a new {@code ConvertingComparator} instance.
* @param comparator the underlying comparator
* @param conversionService the conversion service
* @param targetType the target type
*/
public ConvertingComparator(
Comparator comparator, ConversionService conversionService, Class targetType) {
this(comparator, new ConversionServiceConverter<>(conversionService, targetType));
}
@Override
public int compare(S o1, S o2) {
T c1 = this.converter.convert(o1);
T c2 = this.converter.convert(o2);
return this.comparator.compare(c1, c2);
}
/**
* Create a new {@link ConvertingComparator} that compares {@link java.util.Map.Entry
* map * entries} based on their {@link java.util.Map.Entry#getKey() keys}.
* @param comparator the underlying comparator used to compare keys
* @return a new {@link ConvertingComparator} instance
*/
public static ConvertingComparator, K> mapEntryKeys(Comparator comparator) {
return new ConvertingComparator<>(comparator, Map.Entry::getKey);
}
/**
* Create a new {@link ConvertingComparator} that compares {@link java.util.Map.Entry
* map entries} based on their {@link java.util.Map.Entry#getValue() values}.
* @param comparator the underlying comparator used to compare values
* @return a new {@link ConvertingComparator} instance
*/
public static ConvertingComparator, V> mapEntryValues(Comparator comparator) {
return new ConvertingComparator<>(comparator, Map.Entry::getValue);
}
/**
* Adapts a {@link ConversionService} and targetType to a {@link Converter}.
*/
private static class ConversionServiceConverter implements Converter {
private final ConversionService conversionService;
private final Class targetType;
public ConversionServiceConverter(ConversionService conversionService,
Class targetType) {
Assert.notNull(conversionService, "ConversionService must not be null");
Assert.notNull(targetType, "TargetType must not be null");
this.conversionService = conversionService;
this.targetType = targetType;
}
@Override
@Nullable
public T convert(S source) {
return this.conversionService.convert(source, this.targetType);
}
}
}