DATAREST-431 - Switched to Formatters for Point and Distance of Spring Data Commons.

Dropped our Converter implementations for Point and Distance and rather use the ones provided through Spring Data Commons, the addFormatters(…) method of SpringDataWebConfiguration in particular.

Related ticket: DATACMNS-626.
This commit is contained in:
Oliver Gierke
2015-01-05 13:12:52 +01:00
parent 1c2201faa1
commit ca8399316f
6 changed files with 23 additions and 287 deletions

View File

@@ -46,6 +46,8 @@ import org.springframework.data.domain.PageRequest;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.GeoModule;
import org.springframework.data.geo.Point;
import org.springframework.data.geo.format.DistanceFormatter;
import org.springframework.data.geo.format.PointFormatter;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.mapping.context.PersistentEntities;
import org.springframework.data.repository.support.DefaultRepositoryInvokerFactory;
@@ -77,8 +79,6 @@ import org.springframework.data.rest.webmvc.ServerHttpRequestMethodArgumentResol
import org.springframework.data.rest.webmvc.alps.AlpsJsonHttpMessageConverter;
import org.springframework.data.rest.webmvc.alps.AlpsResourceProcessor;
import org.springframework.data.rest.webmvc.alps.RootResourceInformationToAlpsDescriptorConverter;
import org.springframework.data.rest.webmvc.convert.StringToDistanceConverter;
import org.springframework.data.rest.webmvc.convert.StringToPointConverter;
import org.springframework.data.rest.webmvc.convert.UriListHttpMessageConverter;
import org.springframework.data.rest.webmvc.json.DomainObjectReader;
import org.springframework.data.rest.webmvc.json.Jackson2DatatypeHelper;
@@ -182,16 +182,12 @@ public class RepositoryRestMvcConfiguration extends HateoasAwareSpringDataWebCon
public DefaultFormattingConversionService defaultConversionService() {
DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService();
// Add Spring Data Commons formatters
addFormatters(conversionService);
configureConversionService(conversionService);
if (!conversionService.canConvert(String.class, Point.class)) {
conversionService.addConverter(StringToPointConverter.INSTANCE);
}
if (!conversionService.canConvert(String.class, Distance.class)) {
conversionService.addConverter(StringToDistanceConverter.INSTANCE);
}
return conversionService;
}

View File

@@ -1,87 +0,0 @@
/*
* Copyright 2014 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.data.rest.webmvc.convert;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.Metric;
import org.springframework.data.geo.Metrics;
import org.springframework.util.StringUtils;
/**
* Converter to create {@link Distance} instances from {@link String} representations. The supported format is a decimal
* followed by whitespace and a metric abbreviation. We currently support the following abbreviations:
* {@value #SUPPORTED_METRICS}.
*
* @author Oliver Gierke
*/
public enum StringToDistanceConverter implements Converter<String, Distance> {
INSTANCE;
private static final Map<String, Metric> SUPPORTED_METRICS;
private static final String INVALID_DISTANCE = "Expected double amount optionally followed by a metrics abbreviation (%s) but got '%s'!";
static {
Map<String, Metric> metrics = new LinkedHashMap<String, Metric>();
metrics.put("km", Metrics.KILOMETERS);
metrics.put("miles", Metrics.MILES);
metrics.put("mile", Metrics.MILES);
SUPPORTED_METRICS = Collections.unmodifiableMap(metrics);
}
/*
* (non-Javadoc)
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
*/
@Override
public Distance convert(String source) {
source = source.trim();
for (Entry<String, Metric> metric : SUPPORTED_METRICS.entrySet()) {
if (source.endsWith(metric.getKey())) {
return fromString(source, metric);
}
}
try {
return new Distance(Double.parseDouble(source));
} catch (NumberFormatException o_O) {
throw new IllegalArgumentException(String.format(INVALID_DISTANCE,
StringUtils.collectionToCommaDelimitedString(SUPPORTED_METRICS.keySet()), source));
}
}
private Distance fromString(String source, Entry<String, Metric> metric) {
String amountString = source.substring(0, source.indexOf(metric.getKey()));
try {
return new Distance(Double.parseDouble(amountString), metric.getValue());
} catch (NumberFormatException o_O) {
throw new IllegalArgumentException(String.format(INVALID_DISTANCE,
StringUtils.collectionToCommaDelimitedString(SUPPORTED_METRICS.keySet()), source));
}
}
}

View File

@@ -1,59 +0,0 @@
/*
* Copyright 2014 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.data.rest.webmvc.convert;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.converter.GenericConverter.ConvertiblePair;
import org.springframework.data.geo.Point;
/**
* Converter to parse two comma-separated doubles into a {@link Point}.
*
* @author Oliver Gierke
*/
public enum StringToPointConverter implements Converter<String, Point> {
INSTANCE;
public static final ConvertiblePair CONVERTIBLE = new ConvertiblePair(String.class, Point.class);
private static final String INVALID_FORMAT = "Expected two doubles separated by a semicolon but got '%s'!";
/*
* (non-Javadoc)
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
*/
@Override
public Point convert(String source) {
String[] parts = source.split(",");
if (parts.length != 2) {
throw new IllegalArgumentException(String.format(INVALID_FORMAT, source));
}
try {
double latitude = Double.parseDouble(parts[0]);
double longitude = Double.parseDouble(parts[1]);
return new Point(longitude, latitude);
} catch (NumberFormatException o_O) {
throw new IllegalArgumentException(String.format(INVALID_FORMAT, source), o_O);
}
}
}

View File

@@ -32,8 +32,11 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.core.convert.ConversionService;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.Point;
import org.springframework.data.rest.core.config.RepositoryRestConfiguration;
import org.springframework.data.rest.webmvc.RepositoryLinksResource;
import org.springframework.data.rest.webmvc.RestMediaTypes;
@@ -187,6 +190,20 @@ public class RepositoryRestMvConfigurationIntegrationTests {
assertThat(converters.get(1).getSupportedMediaTypes(), hasItem(MediaTypes.HAL_JSON));
}
/**
* @see DATAREST-431, DATACMNS-626
*/
@Test
public void hasConvertersForPointAndDistance() {
ConversionService service = context.getBean("defaultConversionService", ConversionService.class);
assertThat(service.canConvert(String.class, Point.class), is(true));
assertThat(service.canConvert(Point.class, String.class), is(true));
assertThat(service.canConvert(String.class, Distance.class), is(true));
assertThat(service.canConvert(Distance.class, String.class), is(true));
}
@Configuration
static class ExtendingConfiguration extends RepositoryRestMvcConfiguration {

View File

@@ -1,62 +0,0 @@
/*
* Copyright 2014 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.data.rest.webmvc.convert;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import static org.springframework.data.rest.webmvc.convert.StringToDistanceConverter.*;
import org.junit.Test;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.Metrics;
/**
* Unit tests for {@link StringToDistanceConverter}.
*
* @author Oliver Gierke
*/
public class StringToDistanceConverterUnitTests {
/**
* @see DATAREST-279
*/
@Test
public void parsesDistanceFromString() {
Distance reference = new Distance(10.8, Metrics.KILOMETERS);
assertThat(INSTANCE.convert("10.8km"), is(reference));
assertThat(INSTANCE.convert(" 10.8km"), is(reference));
assertThat(INSTANCE.convert(" 10.8 km"), is(reference));
assertThat(INSTANCE.convert(" 10.8 km "), is(reference));
}
/**
* @see DATAREST-279
*/
@Test(expected = IllegalArgumentException.class)
public void rejectsArbitraryNonsense() {
INSTANCE.convert("foo");
}
/**
* @see DATAREST-279
*/
@Test(expected = IllegalArgumentException.class)
public void rejectsUnsupportedMetric() {
INSTANCE.convert("10.8cm");
}
}

View File

@@ -1,69 +0,0 @@
/*
* Copyright 2014 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.data.rest.webmvc.convert;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import static org.springframework.data.rest.webmvc.convert.StringToPointConverter.*;
import org.junit.Test;
import org.springframework.data.geo.Point;
/**
* Unit tests for {@link StringToPointConverter}.
*
* @author Oliver Gierke
*/
public class StringToPointConverterUnitTests {
/**
* @see DATAREST-279
*/
@Test
public void parsesPointFromString() {
Point reference = new Point(20.9, 10.8);
assertThat(INSTANCE.convert("10.8,20.9"), is(reference));
assertThat(INSTANCE.convert(" 10.8,20.9 "), is(reference));
assertThat(INSTANCE.convert(" 10.8 ,20.9"), is(reference));
assertThat(INSTANCE.convert(" 10.8 , 20.9 "), is(reference));
}
/**
* @see DATAREST-279
*/
@Test(expected = IllegalArgumentException.class)
public void rejectsArbitraryNonsense() {
INSTANCE.convert("foo");
}
/**
* @see DATAREST-279
*/
@Test(expected = IllegalArgumentException.class)
public void rejectsMoreThanTwoCoordinates() {
INSTANCE.convert("10.8,20.9,30.10");
}
/**
* @see DATAREST-279
*/
@Test(expected = IllegalArgumentException.class)
public void rejectsInvalidCoordinate() {
INSTANCE.convert("10.8,foo");
}
}