Polishing

This commit is contained in:
Juergen Hoeller 2018-03-07 15:49:58 +01:00
parent 6f4d25a6e6
commit f57fcdee3c
4 changed files with 55 additions and 74 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2018 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.
@ -91,7 +91,7 @@ public abstract class PropertyMatches {
private final String propertyName;
private String[] possibleMatches;
private final String[] possibleMatches;
/**
@ -155,8 +155,8 @@ public abstract class PropertyMatches {
if (s2.isEmpty()) {
return s1.length();
}
int[][] d = new int[s1.length() + 1][s2.length() + 1];
int[][] d = new int[s1.length() + 1][s2.length() + 1];
for (int i = 0; i <= s1.length(); i++) {
d[i][0] = i;
}
@ -165,18 +165,17 @@ public abstract class PropertyMatches {
}
for (int i = 1; i <= s1.length(); i++) {
char s_i = s1.charAt(i - 1);
char c1 = s1.charAt(i - 1);
for (int j = 1; j <= s2.length(); j++) {
int cost;
char t_j = s2.charAt(j - 1);
if (s_i == t_j) {
char c2 = s2.charAt(j - 1);
if (c1 == c2) {
cost = 0;
}
else {
cost = 1;
}
d[i][j] = Math.min(Math.min(d[i - 1][j] + 1, d[i][j - 1] + 1),
d[i - 1][j - 1] + cost);
d[i][j] = Math.min(Math.min(d[i - 1][j] + 1, d[i][j - 1] + 1), d[i - 1][j - 1] + cost);
}
}
@ -189,24 +188,23 @@ public abstract class PropertyMatches {
private static class BeanPropertyMatches extends PropertyMatches {
public BeanPropertyMatches(String propertyName, Class<?> beanClass, int maxDistance) {
super(propertyName, calculateMatches(propertyName,
BeanUtils.getPropertyDescriptors(beanClass), maxDistance));
super(propertyName,
calculateMatches(propertyName, BeanUtils.getPropertyDescriptors(beanClass), maxDistance));
}
/**
* Generate possible property alternatives for the given property and
* class. Internally uses the {@code getStringDistance} method, which
* in turn uses the Levenshtein algorithm to determine the distance between
* two Strings.
* @param propertyDescriptors the JavaBeans property descriptors to search
* Generate possible property alternatives for the given property and class.
* Internally uses the {@code getStringDistance} method, which in turn uses
* the Levenshtein algorithm to determine the distance between two Strings.
* @param descriptors the JavaBeans property descriptors to search
* @param maxDistance the maximum distance to accept
*/
private static String[] calculateMatches(String propertyName, PropertyDescriptor[] propertyDescriptors, int maxDistance) {
private static String[] calculateMatches(String name, PropertyDescriptor[] descriptors, int maxDistance) {
List<String> candidates = new ArrayList<>();
for (PropertyDescriptor pd : propertyDescriptors) {
for (PropertyDescriptor pd : descriptors) {
if (pd.getWriteMethod() != null) {
String possibleAlternative = pd.getName();
if (calculateStringDistance(propertyName, possibleAlternative) <= maxDistance) {
if (calculateStringDistance(name, possibleAlternative) <= maxDistance) {
candidates.add(possibleAlternative);
}
}
@ -215,21 +213,16 @@ public abstract class PropertyMatches {
return StringUtils.toStringArray(candidates);
}
@Override
public String buildErrorMessage() {
String propertyName = getPropertyName();
String[] possibleMatches = getPossibleMatches();
StringBuilder msg = new StringBuilder();
msg.append("Bean property '");
msg.append(propertyName);
msg.append("' is not writable or has an invalid setter method. ");
if (ObjectUtils.isEmpty(possibleMatches)) {
msg.append("Does the parameter type of the setter match the return type of the getter?");
StringBuilder msg = new StringBuilder(160);
msg.append("Bean property '").append(getPropertyName()).append(
"' is not writable or has an invalid setter method. ");
if (!ObjectUtils.isEmpty(getPossibleMatches())) {
appendHintMessage(msg);
}
else {
appendHintMessage(msg);
msg.append("Does the parameter type of the setter match the return type of the getter?");
}
return msg.toString();
}
@ -242,11 +235,11 @@ public abstract class PropertyMatches {
super(propertyName, calculateMatches(propertyName, beanClass, maxDistance));
}
private static String[] calculateMatches(final String propertyName, Class<?> beanClass, final int maxDistance) {
private static String[] calculateMatches(final String name, Class<?> clazz, final int maxDistance) {
final List<String> candidates = new ArrayList<>();
ReflectionUtils.doWithFields(beanClass, field -> {
ReflectionUtils.doWithFields(clazz, field -> {
String possibleAlternative = field.getName();
if (calculateStringDistance(propertyName, possibleAlternative) <= maxDistance) {
if (calculateStringDistance(name, possibleAlternative) <= maxDistance) {
candidates.add(possibleAlternative);
}
});
@ -256,14 +249,10 @@ public abstract class PropertyMatches {
@Override
public String buildErrorMessage() {
String propertyName = getPropertyName();
String[] possibleMatches = getPossibleMatches();
StringBuilder msg = new StringBuilder();
msg.append("Bean property '");
msg.append(propertyName);
msg.append("' has no matching field. ");
if (!ObjectUtils.isEmpty(possibleMatches)) {
StringBuilder msg = new StringBuilder(80);
msg.append("Bean property '").append(getPropertyName()).append("' has no matching field.");
if (!ObjectUtils.isEmpty(getPossibleMatches())) {
msg.append(' ');
appendHintMessage(msg);
}
return msg.toString();

View File

@ -22,17 +22,16 @@
<xsd:complexType>
<xsd:annotation>
<xsd:documentation source="java:org.springframework.cache.annotation.AnnotationCacheOperationDefinitionSource"><![CDATA[
Indicates that cache configuration is defined by Java 5
annotations on bean classes, and that proxies are automatically
to be created for the relevant annotated beans.
Indicates that cache configuration is defined by annotations on bean classes,
and that proxies are automatically to be created for the relevant annotated beans.
The default annotations supported are Spring's @Cacheable, @CachePut and @CacheEvict. If
spring-context-support and the JSR-107 API are on the classpath, additional proxies are
automatically created for JSR-107 annotated beans, that is @CacheResult, @CachePut,
The default annotations supported are Spring's @Cacheable, @CachePut and @CacheEvict.
If spring-context-support and the JSR-107 API are on the classpath, additional proxies
are automatically created for JSR-107 annotated beans, that is @CacheResult, @CachePut,
@CacheRemove and @CacheRemoveAll.
See org.springframework.cache.annotation.EnableCaching Javadoc
for information on code-based alternatives to this XML element.
See org.springframework.cache.annotation.EnableCaching javadoc for information on
code-based alternatives to this XML element.
]]></xsd:documentation>
</xsd:annotation>
<xsd:attribute name="cache-manager" type="xsd:string" default="cacheManager">
@ -148,8 +147,7 @@
<xsd:complexType>
<xsd:annotation>
<xsd:documentation source="java:org.springframework.cache.interceptor.CacheInterceptor"><![CDATA[
Defines the cache semantics of the AOP advice that is to be
executed.
Defines the cache semantics of the AOP advice that is to be executed.
That is, this advice element is where the cacheable semantics of
any number of methods are defined (where cacheable semantics
@ -243,7 +241,6 @@
example, 'get*', 'handle*', '*Order', 'on*Event', etc.]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<xsd:complexType name="definitionsType">
@ -303,7 +300,6 @@
invoked (default) or before.]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>

View File

@ -20,12 +20,12 @@
<xsd:element name="annotation-driven">
<xsd:annotation>
<xsd:documentation><![CDATA[
Enables the detection of @JmsListener annotation on any Spring-managed object. If
present, a message listener container will be created to receive the relevant
Enables the detection of @JmsListener annotation on any Spring-managed object.
If present, a message listener container will be created to receive the relevant
messages and invoke the annotated method accordingly.
See Javadoc for the org.springframework.jms.annotation.EnableJms annotation for
information on code-based alternatives to this XML element.
See org.springframework.jms.annotation.EnableJms javadoc for information on
code-based alternatives to this XML element.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
@ -68,7 +68,7 @@
processor. By default, DefaultMessageHandlerMethodFactory is used and it can be configured
further to support additional method arguments or to customize conversion and validation
support. See org.springframework.messaging.handler.annotation.support.DefaultMessageHandlerMethodFactory
Javadoc for more details.
javadoc for more details.
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref">
@ -77,8 +77,6 @@
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
@ -378,14 +376,13 @@
<xsd:element name="jca-listener-container">
<xsd:annotation>
<xsd:documentation><![CDATA[
Each listener child element will be hosted by a container whose configuration
is determined by this parent element. This variant builds standard JCA-based
listener containers, operating against a specified JCA ResourceAdapter
(which needs to be provided by the JMS message broker, e.g. ActiveMQ). When
a factory-id attribute is present, the configuration defined by this element is
exposed as a org.springframework.jms.config.JmsListenerContainerFactory. It is
therefore possible to only define this element without any child to just expose
a container factory.
Each listener child element will be hosted by a container whose configuration is
determined by this parent element. This variant builds standard JCA-based listener
containers, operating against a specified JCA ResourceAdapter (which needs to be
provided by the JMS message broker, e.g. ActiveMQ). When a factory-id attribute is
present, the configuration defined by this element is exposed as a bean of type
org.springframework.jms.config.JmsListenerContainerFactory. It is therefore possible
to only define this element without any child to just expose a container factory.
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation>
@ -400,7 +397,8 @@
<xsd:attribute name="factory-id" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
Expose the settings defined by this element as a org.springframework.jms.config.JmsListenerContainerFactory
Expose the settings defined by this element as a bean of type
org.springframework.jms.config.JmsListenerContainerFactory
so that they can be reused with other endpoints.
]]></xsd:documentation>
</xsd:annotation>
@ -478,8 +476,8 @@
<xsd:attribute name="response-destination-type" default="queue">
<xsd:annotation>
<xsd:documentation><![CDATA[
The JMS destination type for responses: "queue", "topic". Default
is the value of the "destination-type" attribute.
The JMS destination type for responses: "queue", "topic".
Default is the value of the "destination-type" attribute.
]]></xsd:documentation>
</xsd:annotation>
<xsd:simpleType>

View File

@ -24,7 +24,6 @@ import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
@ -182,11 +181,10 @@ public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMe
* but not by consumable/producible media types
*/
@Override
protected HandlerMethod handleNoMatch(Set<RequestMappingInfo> infos, String lookupPath,
HttpServletRequest request) throws ServletException {
protected HandlerMethod handleNoMatch(
Set<RequestMappingInfo> infos, String lookupPath, HttpServletRequest request) throws ServletException {
PartialMatchHelper helper = new PartialMatchHelper(infos, request);
if (helper.isEmpty()) {
return null;
}