Polishing
This commit is contained in:
parent
6f4d25a6e6
commit
f57fcdee3c
|
|
@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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 final String propertyName;
|
||||||
|
|
||||||
private String[] possibleMatches;
|
private final String[] possibleMatches;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -155,8 +155,8 @@ public abstract class PropertyMatches {
|
||||||
if (s2.isEmpty()) {
|
if (s2.isEmpty()) {
|
||||||
return s1.length();
|
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++) {
|
for (int i = 0; i <= s1.length(); i++) {
|
||||||
d[i][0] = i;
|
d[i][0] = i;
|
||||||
}
|
}
|
||||||
|
|
@ -165,18 +165,17 @@ public abstract class PropertyMatches {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 1; i <= s1.length(); i++) {
|
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++) {
|
for (int j = 1; j <= s2.length(); j++) {
|
||||||
int cost;
|
int cost;
|
||||||
char t_j = s2.charAt(j - 1);
|
char c2 = s2.charAt(j - 1);
|
||||||
if (s_i == t_j) {
|
if (c1 == c2) {
|
||||||
cost = 0;
|
cost = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
cost = 1;
|
cost = 1;
|
||||||
}
|
}
|
||||||
d[i][j] = Math.min(Math.min(d[i - 1][j] + 1, d[i][j - 1] + 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 - 1][j - 1] + cost);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -189,24 +188,23 @@ public abstract class PropertyMatches {
|
||||||
private static class BeanPropertyMatches extends PropertyMatches {
|
private static class BeanPropertyMatches extends PropertyMatches {
|
||||||
|
|
||||||
public BeanPropertyMatches(String propertyName, Class<?> beanClass, int maxDistance) {
|
public BeanPropertyMatches(String propertyName, Class<?> beanClass, int maxDistance) {
|
||||||
super(propertyName, calculateMatches(propertyName,
|
super(propertyName,
|
||||||
BeanUtils.getPropertyDescriptors(beanClass), maxDistance));
|
calculateMatches(propertyName, BeanUtils.getPropertyDescriptors(beanClass), maxDistance));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate possible property alternatives for the given property and
|
* Generate possible property alternatives for the given property and class.
|
||||||
* class. Internally uses the {@code getStringDistance} method, which
|
* Internally uses the {@code getStringDistance} method, which in turn uses
|
||||||
* in turn uses the Levenshtein algorithm to determine the distance between
|
* the Levenshtein algorithm to determine the distance between two Strings.
|
||||||
* two Strings.
|
* @param descriptors the JavaBeans property descriptors to search
|
||||||
* @param propertyDescriptors the JavaBeans property descriptors to search
|
|
||||||
* @param maxDistance the maximum distance to accept
|
* @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<>();
|
List<String> candidates = new ArrayList<>();
|
||||||
for (PropertyDescriptor pd : propertyDescriptors) {
|
for (PropertyDescriptor pd : descriptors) {
|
||||||
if (pd.getWriteMethod() != null) {
|
if (pd.getWriteMethod() != null) {
|
||||||
String possibleAlternative = pd.getName();
|
String possibleAlternative = pd.getName();
|
||||||
if (calculateStringDistance(propertyName, possibleAlternative) <= maxDistance) {
|
if (calculateStringDistance(name, possibleAlternative) <= maxDistance) {
|
||||||
candidates.add(possibleAlternative);
|
candidates.add(possibleAlternative);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -215,21 +213,16 @@ public abstract class PropertyMatches {
|
||||||
return StringUtils.toStringArray(candidates);
|
return StringUtils.toStringArray(candidates);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String buildErrorMessage() {
|
public String buildErrorMessage() {
|
||||||
String propertyName = getPropertyName();
|
StringBuilder msg = new StringBuilder(160);
|
||||||
String[] possibleMatches = getPossibleMatches();
|
msg.append("Bean property '").append(getPropertyName()).append(
|
||||||
StringBuilder msg = new StringBuilder();
|
"' is not writable or has an invalid setter method. ");
|
||||||
msg.append("Bean property '");
|
if (!ObjectUtils.isEmpty(getPossibleMatches())) {
|
||||||
msg.append(propertyName);
|
appendHintMessage(msg);
|
||||||
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?");
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
appendHintMessage(msg);
|
msg.append("Does the parameter type of the setter match the return type of the getter?");
|
||||||
}
|
}
|
||||||
return msg.toString();
|
return msg.toString();
|
||||||
}
|
}
|
||||||
|
|
@ -242,11 +235,11 @@ public abstract class PropertyMatches {
|
||||||
super(propertyName, calculateMatches(propertyName, beanClass, maxDistance));
|
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<>();
|
final List<String> candidates = new ArrayList<>();
|
||||||
ReflectionUtils.doWithFields(beanClass, field -> {
|
ReflectionUtils.doWithFields(clazz, field -> {
|
||||||
String possibleAlternative = field.getName();
|
String possibleAlternative = field.getName();
|
||||||
if (calculateStringDistance(propertyName, possibleAlternative) <= maxDistance) {
|
if (calculateStringDistance(name, possibleAlternative) <= maxDistance) {
|
||||||
candidates.add(possibleAlternative);
|
candidates.add(possibleAlternative);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -256,14 +249,10 @@ public abstract class PropertyMatches {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String buildErrorMessage() {
|
public String buildErrorMessage() {
|
||||||
String propertyName = getPropertyName();
|
StringBuilder msg = new StringBuilder(80);
|
||||||
String[] possibleMatches = getPossibleMatches();
|
msg.append("Bean property '").append(getPropertyName()).append("' has no matching field.");
|
||||||
StringBuilder msg = new StringBuilder();
|
if (!ObjectUtils.isEmpty(getPossibleMatches())) {
|
||||||
msg.append("Bean property '");
|
msg.append(' ');
|
||||||
msg.append(propertyName);
|
|
||||||
msg.append("' has no matching field. ");
|
|
||||||
|
|
||||||
if (!ObjectUtils.isEmpty(possibleMatches)) {
|
|
||||||
appendHintMessage(msg);
|
appendHintMessage(msg);
|
||||||
}
|
}
|
||||||
return msg.toString();
|
return msg.toString();
|
||||||
|
|
|
||||||
|
|
@ -22,17 +22,16 @@
|
||||||
<xsd:complexType>
|
<xsd:complexType>
|
||||||
<xsd:annotation>
|
<xsd:annotation>
|
||||||
<xsd:documentation source="java:org.springframework.cache.annotation.AnnotationCacheOperationDefinitionSource"><![CDATA[
|
<xsd:documentation source="java:org.springframework.cache.annotation.AnnotationCacheOperationDefinitionSource"><![CDATA[
|
||||||
Indicates that cache configuration is defined by Java 5
|
Indicates that cache configuration is defined by annotations on bean classes,
|
||||||
annotations on bean classes, and that proxies are automatically
|
and that proxies are automatically to be created for the relevant annotated beans.
|
||||||
to be created for the relevant annotated beans.
|
|
||||||
|
|
||||||
The default annotations supported are Spring's @Cacheable, @CachePut and @CacheEvict. If
|
The default annotations supported are Spring's @Cacheable, @CachePut and @CacheEvict.
|
||||||
spring-context-support and the JSR-107 API are on the classpath, additional proxies are
|
If spring-context-support and the JSR-107 API are on the classpath, additional proxies
|
||||||
automatically created for JSR-107 annotated beans, that is @CacheResult, @CachePut,
|
are automatically created for JSR-107 annotated beans, that is @CacheResult, @CachePut,
|
||||||
@CacheRemove and @CacheRemoveAll.
|
@CacheRemove and @CacheRemoveAll.
|
||||||
|
|
||||||
See org.springframework.cache.annotation.EnableCaching Javadoc
|
See org.springframework.cache.annotation.EnableCaching javadoc for information on
|
||||||
for information on code-based alternatives to this XML element.
|
code-based alternatives to this XML element.
|
||||||
]]></xsd:documentation>
|
]]></xsd:documentation>
|
||||||
</xsd:annotation>
|
</xsd:annotation>
|
||||||
<xsd:attribute name="cache-manager" type="xsd:string" default="cacheManager">
|
<xsd:attribute name="cache-manager" type="xsd:string" default="cacheManager">
|
||||||
|
|
@ -148,8 +147,7 @@
|
||||||
<xsd:complexType>
|
<xsd:complexType>
|
||||||
<xsd:annotation>
|
<xsd:annotation>
|
||||||
<xsd:documentation source="java:org.springframework.cache.interceptor.CacheInterceptor"><![CDATA[
|
<xsd:documentation source="java:org.springframework.cache.interceptor.CacheInterceptor"><![CDATA[
|
||||||
Defines the cache semantics of the AOP advice that is to be
|
Defines the cache semantics of the AOP advice that is to be executed.
|
||||||
executed.
|
|
||||||
|
|
||||||
That is, this advice element is where the cacheable semantics of
|
That is, this advice element is where the cacheable semantics of
|
||||||
any number of methods are defined (where cacheable semantics
|
any number of methods are defined (where cacheable semantics
|
||||||
|
|
@ -243,7 +241,6 @@
|
||||||
example, 'get*', 'handle*', '*Order', 'on*Event', etc.]]></xsd:documentation>
|
example, 'get*', 'handle*', '*Order', 'on*Event', etc.]]></xsd:documentation>
|
||||||
</xsd:annotation>
|
</xsd:annotation>
|
||||||
</xsd:attribute>
|
</xsd:attribute>
|
||||||
|
|
||||||
</xsd:complexType>
|
</xsd:complexType>
|
||||||
|
|
||||||
<xsd:complexType name="definitionsType">
|
<xsd:complexType name="definitionsType">
|
||||||
|
|
@ -303,7 +300,6 @@
|
||||||
invoked (default) or before.]]></xsd:documentation>
|
invoked (default) or before.]]></xsd:documentation>
|
||||||
</xsd:annotation>
|
</xsd:annotation>
|
||||||
</xsd:attribute>
|
</xsd:attribute>
|
||||||
|
|
||||||
</xsd:extension>
|
</xsd:extension>
|
||||||
</xsd:complexContent>
|
</xsd:complexContent>
|
||||||
</xsd:complexType>
|
</xsd:complexType>
|
||||||
|
|
|
||||||
|
|
@ -20,12 +20,12 @@
|
||||||
<xsd:element name="annotation-driven">
|
<xsd:element name="annotation-driven">
|
||||||
<xsd:annotation>
|
<xsd:annotation>
|
||||||
<xsd:documentation><![CDATA[
|
<xsd:documentation><![CDATA[
|
||||||
Enables the detection of @JmsListener annotation on any Spring-managed object. If
|
Enables the detection of @JmsListener annotation on any Spring-managed object.
|
||||||
present, a message listener container will be created to receive the relevant
|
If present, a message listener container will be created to receive the relevant
|
||||||
messages and invoke the annotated method accordingly.
|
messages and invoke the annotated method accordingly.
|
||||||
|
|
||||||
See Javadoc for the org.springframework.jms.annotation.EnableJms annotation for
|
See org.springframework.jms.annotation.EnableJms javadoc for information on
|
||||||
information on code-based alternatives to this XML element.
|
code-based alternatives to this XML element.
|
||||||
]]></xsd:documentation>
|
]]></xsd:documentation>
|
||||||
</xsd:annotation>
|
</xsd:annotation>
|
||||||
<xsd:complexType>
|
<xsd:complexType>
|
||||||
|
|
@ -68,7 +68,7 @@
|
||||||
processor. By default, DefaultMessageHandlerMethodFactory is used and it can be configured
|
processor. By default, DefaultMessageHandlerMethodFactory is used and it can be configured
|
||||||
further to support additional method arguments or to customize conversion and validation
|
further to support additional method arguments or to customize conversion and validation
|
||||||
support. See org.springframework.messaging.handler.annotation.support.DefaultMessageHandlerMethodFactory
|
support. See org.springframework.messaging.handler.annotation.support.DefaultMessageHandlerMethodFactory
|
||||||
Javadoc for more details.
|
javadoc for more details.
|
||||||
]]></xsd:documentation>
|
]]></xsd:documentation>
|
||||||
<xsd:appinfo>
|
<xsd:appinfo>
|
||||||
<tool:annotation kind="ref">
|
<tool:annotation kind="ref">
|
||||||
|
|
@ -77,8 +77,6 @@
|
||||||
</xsd:appinfo>
|
</xsd:appinfo>
|
||||||
</xsd:annotation>
|
</xsd:annotation>
|
||||||
</xsd:attribute>
|
</xsd:attribute>
|
||||||
|
|
||||||
|
|
||||||
</xsd:complexType>
|
</xsd:complexType>
|
||||||
</xsd:element>
|
</xsd:element>
|
||||||
|
|
||||||
|
|
@ -378,14 +376,13 @@
|
||||||
<xsd:element name="jca-listener-container">
|
<xsd:element name="jca-listener-container">
|
||||||
<xsd:annotation>
|
<xsd:annotation>
|
||||||
<xsd:documentation><![CDATA[
|
<xsd:documentation><![CDATA[
|
||||||
Each listener child element will be hosted by a container whose configuration
|
Each listener child element will be hosted by a container whose configuration is
|
||||||
is determined by this parent element. This variant builds standard JCA-based
|
determined by this parent element. This variant builds standard JCA-based listener
|
||||||
listener containers, operating against a specified JCA ResourceAdapter
|
containers, operating against a specified JCA ResourceAdapter (which needs to be
|
||||||
(which needs to be provided by the JMS message broker, e.g. ActiveMQ). When
|
provided by the JMS message broker, e.g. ActiveMQ). When a factory-id attribute is
|
||||||
a factory-id attribute is present, the configuration defined by this element is
|
present, the configuration defined by this element is exposed as a bean of type
|
||||||
exposed as a org.springframework.jms.config.JmsListenerContainerFactory. It is
|
org.springframework.jms.config.JmsListenerContainerFactory. It is therefore possible
|
||||||
therefore possible to only define this element without any child to just expose
|
to only define this element without any child to just expose a container factory.
|
||||||
a container factory.
|
|
||||||
]]></xsd:documentation>
|
]]></xsd:documentation>
|
||||||
<xsd:appinfo>
|
<xsd:appinfo>
|
||||||
<tool:annotation>
|
<tool:annotation>
|
||||||
|
|
@ -400,7 +397,8 @@
|
||||||
<xsd:attribute name="factory-id" type="xsd:string">
|
<xsd:attribute name="factory-id" type="xsd:string">
|
||||||
<xsd:annotation>
|
<xsd:annotation>
|
||||||
<xsd:documentation><![CDATA[
|
<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.
|
so that they can be reused with other endpoints.
|
||||||
]]></xsd:documentation>
|
]]></xsd:documentation>
|
||||||
</xsd:annotation>
|
</xsd:annotation>
|
||||||
|
|
@ -478,8 +476,8 @@
|
||||||
<xsd:attribute name="response-destination-type" default="queue">
|
<xsd:attribute name="response-destination-type" default="queue">
|
||||||
<xsd:annotation>
|
<xsd:annotation>
|
||||||
<xsd:documentation><![CDATA[
|
<xsd:documentation><![CDATA[
|
||||||
The JMS destination type for responses: "queue", "topic". Default
|
The JMS destination type for responses: "queue", "topic".
|
||||||
is the value of the "destination-type" attribute.
|
Default is the value of the "destination-type" attribute.
|
||||||
]]></xsd:documentation>
|
]]></xsd:documentation>
|
||||||
</xsd:annotation>
|
</xsd:annotation>
|
||||||
<xsd:simpleType>
|
<xsd:simpleType>
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@ import java.util.LinkedHashMap;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
@ -182,11 +181,10 @@ public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMe
|
||||||
* but not by consumable/producible media types
|
* but not by consumable/producible media types
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected HandlerMethod handleNoMatch(Set<RequestMappingInfo> infos, String lookupPath,
|
protected HandlerMethod handleNoMatch(
|
||||||
HttpServletRequest request) throws ServletException {
|
Set<RequestMappingInfo> infos, String lookupPath, HttpServletRequest request) throws ServletException {
|
||||||
|
|
||||||
PartialMatchHelper helper = new PartialMatchHelper(infos, request);
|
PartialMatchHelper helper = new PartialMatchHelper(infos, request);
|
||||||
|
|
||||||
if (helper.isEmpty()) {
|
if (helper.isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue