diff options
author | Emmanuel Bourg <ebourg@apache.org> | 2018-04-08 23:27:38 +0200 |
---|---|---|
committer | Emmanuel Bourg <ebourg@apache.org> | 2018-04-08 23:27:38 +0200 |
commit | e9dafb5ce16aa2faa4fee1019417cc0a7456af57 (patch) | |
tree | c38471d22f5c367a45673724d3a6571d5daf591b /spring-beans/src/main/java/org/springframework | |
parent | 6dc3d6835b664af0d21e774a5342b90d4417f628 (diff) |
New upstream version 4.3.15
Diffstat (limited to 'spring-beans/src/main/java/org/springframework')
26 files changed, 196 insertions, 183 deletions
diff --git a/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java b/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java index c29eaf53..0cdf050a 100644 --- a/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java +++ b/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java @@ -311,23 +311,23 @@ public abstract class BeanUtils { public static Method resolveSignature(String signature, Class<?> clazz) { Assert.hasText(signature, "'signature' must not be empty"); Assert.notNull(clazz, "Class must not be null"); - int firstParen = signature.indexOf("("); - int lastParen = signature.indexOf(")"); - if (firstParen > -1 && lastParen == -1) { + int startParen = signature.indexOf('('); + int endParen = signature.indexOf(')'); + if (startParen > -1 && endParen == -1) { throw new IllegalArgumentException("Invalid method signature '" + signature + "': expected closing ')' for args list"); } - else if (lastParen > -1 && firstParen == -1) { + else if (startParen == -1 && endParen > -1) { throw new IllegalArgumentException("Invalid method signature '" + signature + "': expected opening '(' for args list"); } - else if (firstParen == -1 && lastParen == -1) { + else if (startParen == -1 && endParen == -1) { return findMethodWithMinimalParameters(clazz, signature); } else { - String methodName = signature.substring(0, firstParen); + String methodName = signature.substring(0, startParen); String[] parameterTypeNames = - StringUtils.commaDelimitedListToStringArray(signature.substring(firstParen + 1, lastParen)); + StringUtils.commaDelimitedListToStringArray(signature.substring(startParen + 1, endParen)); Class<?>[] parameterTypes = new Class<?>[parameterTypeNames.length]; for (int i = 0; i < parameterTypeNames.length; i++) { String parameterTypeName = parameterTypeNames[i].trim(); diff --git a/spring-beans/src/main/java/org/springframework/beans/BeanWrapperImpl.java b/spring-beans/src/main/java/org/springframework/beans/BeanWrapperImpl.java index 4d10dc0c..a1686d0e 100644 --- a/spring-beans/src/main/java/org/springframework/beans/BeanWrapperImpl.java +++ b/spring-beans/src/main/java/org/springframework/beans/BeanWrapperImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 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. @@ -224,10 +224,7 @@ public class BeanWrapperImpl extends AbstractNestablePropertyAccessor implements @Override protected BeanPropertyHandler getLocalPropertyHandler(String propertyName) { PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(propertyName); - if (pd != null) { - return new BeanPropertyHandler(pd); - } - return null; + return (pd != null ? new BeanPropertyHandler(pd) : null); } @Override @@ -238,8 +235,7 @@ public class BeanWrapperImpl extends AbstractNestablePropertyAccessor implements @Override protected NotWritablePropertyException createNotWritablePropertyException(String propertyName) { PropertyMatches matches = PropertyMatches.forProperty(propertyName, getRootClass()); - throw new NotWritablePropertyException( - getRootClass(), getNestedPath() + propertyName, + throw new NotWritablePropertyException(getRootClass(), getNestedPath() + propertyName, matches.buildErrorMessage(), matches.getPossibleMatches()); } diff --git a/spring-beans/src/main/java/org/springframework/beans/DirectFieldAccessor.java b/spring-beans/src/main/java/org/springframework/beans/DirectFieldAccessor.java index 35623113..b4777d44 100644 --- a/spring-beans/src/main/java/org/springframework/beans/DirectFieldAccessor.java +++ b/spring-beans/src/main/java/org/springframework/beans/DirectFieldAccessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 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. @@ -76,8 +76,8 @@ public class DirectFieldAccessor extends AbstractNestablePropertyAccessor { Field field = ReflectionUtils.findField(getWrappedClass(), propertyName); if (field != null) { propertyHandler = new FieldPropertyHandler(field); + this.fieldMap.put(propertyName, propertyHandler); } - this.fieldMap.put(propertyName, propertyHandler); } return propertyHandler; } diff --git a/spring-beans/src/main/java/org/springframework/beans/Mergeable.java b/spring-beans/src/main/java/org/springframework/beans/Mergeable.java index cba64d94..d3d127c0 100644 --- a/spring-beans/src/main/java/org/springframework/beans/Mergeable.java +++ b/spring-beans/src/main/java/org/springframework/beans/Mergeable.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 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. @@ -41,7 +41,7 @@ public interface Mergeable { * @param parent the object to merge with * @return the result of the merge operation * @throws IllegalArgumentException if the supplied parent is {@code null} - * @exception IllegalStateException if merging is not enabled for this instance + * @throws IllegalStateException if merging is not enabled for this instance * (i.e. {@code mergeEnabled} equals {@code false}). */ Object merge(Object parent); diff --git a/spring-beans/src/main/java/org/springframework/beans/MutablePropertyValues.java b/spring-beans/src/main/java/org/springframework/beans/MutablePropertyValues.java index efb4ae9b..8167613a 100644 --- a/spring-beans/src/main/java/org/springframework/beans/MutablePropertyValues.java +++ b/spring-beans/src/main/java/org/springframework/beans/MutablePropertyValues.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 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. @@ -262,7 +262,7 @@ public class MutablePropertyValues implements PropertyValues, Serializable { /** * Get the raw property value, if any. * @param propertyName the name to search for - * @return the raw property value, or {@code null} + * @return the raw property value, or {@code null} if none found * @since 4.0 * @see #getPropertyValue(String) * @see PropertyValue#getValue() @@ -283,11 +283,7 @@ public class MutablePropertyValues implements PropertyValues, Serializable { for (PropertyValue newPv : this.propertyValueList) { // if there wasn't an old one, add it PropertyValue pvOld = old.getPropertyValue(newPv.getName()); - if (pvOld == null) { - changes.addPropertyValue(newPv); - } - else if (!pvOld.equals(newPv)) { - // it's changed + if (pvOld == null || !pvOld.equals(newPv)) { changes.addPropertyValue(newPv); } } diff --git a/spring-beans/src/main/java/org/springframework/beans/PropertyDescriptorUtils.java b/spring-beans/src/main/java/org/springframework/beans/PropertyDescriptorUtils.java index 5e766690..f90d718a 100644 --- a/spring-beans/src/main/java/org/springframework/beans/PropertyDescriptorUtils.java +++ b/spring-beans/src/main/java/org/springframework/beans/PropertyDescriptorUtils.java @@ -75,7 +75,7 @@ class PropertyDescriptorUtils { } if (writeMethod != null) { - Class<?> params[] = writeMethod.getParameterTypes(); + Class<?>[] params = writeMethod.getParameterTypes(); if (params.length != 1) { throw new IntrospectionException("Bad write method arg count: " + writeMethod); } @@ -109,7 +109,7 @@ class PropertyDescriptorUtils { Class<?> indexedPropertyType = null; if (indexedReadMethod != null) { - Class<?> params[] = indexedReadMethod.getParameterTypes(); + Class<?>[] params = indexedReadMethod.getParameterTypes(); if (params.length != 1) { throw new IntrospectionException("Bad indexed read method arg count: " + indexedReadMethod); } @@ -123,7 +123,7 @@ class PropertyDescriptorUtils { } if (indexedWriteMethod != null) { - Class<?> params[] = indexedWriteMethod.getParameterTypes(); + Class<?>[] params = indexedWriteMethod.getParameterTypes(); if (params.length != 2) { throw new IntrospectionException("Bad indexed write method arg count: " + indexedWriteMethod); } diff --git a/spring-beans/src/main/java/org/springframework/beans/PropertyMatches.java b/spring-beans/src/main/java/org/springframework/beans/PropertyMatches.java index f0d607a1..8cfbc4a0 100644 --- a/spring-beans/src/main/java/org/springframework/beans/PropertyMatches.java +++ b/spring-beans/src/main/java/org/springframework/beans/PropertyMatches.java @@ -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. @@ -156,8 +156,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; } @@ -166,18 +166,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); } } @@ -190,24 +189,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<String>(); - 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); } } @@ -216,21 +214,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(); } @@ -243,13 +236,13 @@ 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<String>(); - ReflectionUtils.doWithFields(beanClass, new ReflectionUtils.FieldCallback() { + ReflectionUtils.doWithFields(clazz, new ReflectionUtils.FieldCallback() { @Override public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException { String possibleAlternative = field.getName(); - if (calculateStringDistance(propertyName, possibleAlternative) <= maxDistance) { + if (calculateStringDistance(name, possibleAlternative) <= maxDistance) { candidates.add(possibleAlternative); } } @@ -260,14 +253,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(); diff --git a/spring-beans/src/main/java/org/springframework/beans/TypeConverterDelegate.java b/spring-beans/src/main/java/org/springframework/beans/TypeConverterDelegate.java index 6531d6b9..ef7d44eb 100644 --- a/spring-beans/src/main/java/org/springframework/beans/TypeConverterDelegate.java +++ b/spring-beans/src/main/java/org/springframework/beans/TypeConverterDelegate.java @@ -325,7 +325,7 @@ class TypeConverterDelegate { if (Enum.class == requiredType) { // target type is declared as raw enum, treat the trimmed value as <enum.fqn>.FIELD_NAME - int index = trimmedValue.lastIndexOf("."); + int index = trimmedValue.lastIndexOf('.'); if (index > - 1) { String enumType = trimmedValue.substring(0, index); String fieldName = trimmedValue.substring(index + 1); diff --git a/spring-beans/src/main/java/org/springframework/beans/TypeMismatchException.java b/spring-beans/src/main/java/org/springframework/beans/TypeMismatchException.java index 2f81b70a..7bc7a901 100644 --- a/spring-beans/src/main/java/org/springframework/beans/TypeMismatchException.java +++ b/spring-beans/src/main/java/org/springframework/beans/TypeMismatchException.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 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. @@ -41,7 +41,7 @@ public class TypeMismatchException extends PropertyAccessException { /** - * Create a new TypeMismatchException. + * Create a new {@code TypeMismatchException}. * @param propertyChangeEvent the PropertyChangeEvent that resulted in the problem * @param requiredType the required target type */ @@ -50,7 +50,7 @@ public class TypeMismatchException extends PropertyAccessException { } /** - * Create a new TypeMismatchException. + * Create a new {@code TypeMismatchException}. * @param propertyChangeEvent the PropertyChangeEvent that resulted in the problem * @param requiredType the required target type (or {@code null} if not known) * @param cause the root cause (may be {@code null}) @@ -69,7 +69,7 @@ public class TypeMismatchException extends PropertyAccessException { } /** - * Create a new TypeMismatchException without PropertyChangeEvent. + * Create a new {@code TypeMismatchException} without a {@code PropertyChangeEvent}. * @param value the offending value that couldn't be converted (may be {@code null}) * @param requiredType the required target type (or {@code null} if not known) */ @@ -78,7 +78,7 @@ public class TypeMismatchException extends PropertyAccessException { } /** - * Create a new TypeMismatchException without PropertyChangeEvent. + * Create a new {@code TypeMismatchException} without a {@code PropertyChangeEvent}. * @param value the offending value that couldn't be converted (may be {@code null}) * @param requiredType the required target type (or {@code null} if not known) * @param cause the root cause (may be {@code null}) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/BeanFactoryUtils.java b/spring-beans/src/main/java/org/springframework/beans/factory/BeanFactoryUtils.java index 42b749e6..7a67710e 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/BeanFactoryUtils.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/BeanFactoryUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 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. @@ -147,14 +147,7 @@ public abstract class BeanFactoryUtils { if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) { String[] parentResult = beanNamesForTypeIncludingAncestors( (ListableBeanFactory) hbf.getParentBeanFactory(), type); - List<String> resultList = new ArrayList<String>(); - resultList.addAll(Arrays.asList(result)); - for (String beanName : parentResult) { - if (!resultList.contains(beanName) && !hbf.containsLocalBean(beanName)) { - resultList.add(beanName); - } - } - result = StringUtils.toStringArray(resultList); + result = mergeNamesWithParent(result, parentResult, hbf); } } return result; @@ -180,14 +173,7 @@ public abstract class BeanFactoryUtils { if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) { String[] parentResult = beanNamesForTypeIncludingAncestors( (ListableBeanFactory) hbf.getParentBeanFactory(), type); - List<String> resultList = new ArrayList<String>(); - resultList.addAll(Arrays.asList(result)); - for (String beanName : parentResult) { - if (!resultList.contains(beanName) && !hbf.containsLocalBean(beanName)) { - resultList.add(beanName); - } - } - result = StringUtils.toStringArray(resultList); + result = mergeNamesWithParent(result, parentResult, hbf); } } return result; @@ -223,14 +209,7 @@ public abstract class BeanFactoryUtils { if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) { String[] parentResult = beanNamesForTypeIncludingAncestors( (ListableBeanFactory) hbf.getParentBeanFactory(), type, includeNonSingletons, allowEagerInit); - List<String> resultList = new ArrayList<String>(); - resultList.addAll(Arrays.asList(result)); - for (String beanName : parentResult) { - if (!resultList.contains(beanName) && !hbf.containsLocalBean(beanName)) { - resultList.add(beanName); - } - } - result = StringUtils.toStringArray(resultList); + result = mergeNamesWithParent(result, parentResult, hbf); } } return result; @@ -446,6 +425,29 @@ public abstract class BeanFactoryUtils { return uniqueBean(type, beansOfType); } + + /** + * Merge the given bean names result with the given parent result. + * @param result the local bean name result + * @param parentResult the parent bean name result (possibly empty) + * @param hbf the local bean factory + * @return the merged result (possibly the local result as-is) + * @since 4.3.15 + */ + private static String[] mergeNamesWithParent(String[] result, String[] parentResult, HierarchicalBeanFactory hbf) { + if (parentResult.length == 0) { + return result; + } + List<String> merged = new ArrayList<String>(result.length + parentResult.length); + merged.addAll(Arrays.asList(result)); + for (String beanName : parentResult) { + if (!merged.contains(beanName) && !hbf.containsLocalBean(beanName)) { + merged.add(beanName); + } + } + return StringUtils.toStringArray(merged); + } + /** * Extract a unique bean for the given type from the given Map of matching beans. * @param type type of bean to match @@ -455,11 +457,11 @@ public abstract class BeanFactoryUtils { * @throws NoUniqueBeanDefinitionException if more than one bean of the given type was found */ private static <T> T uniqueBean(Class<T> type, Map<String, T> matchingBeans) { - int nrFound = matchingBeans.size(); - if (nrFound == 1) { + int count = matchingBeans.size(); + if (count == 1) { return matchingBeans.values().iterator().next(); } - else if (nrFound > 1) { + else if (count > 1) { throw new NoUniqueBeanDefinitionException(type, matchingBeans.keySet()); } else { diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/CannotLoadBeanClassException.java b/spring-beans/src/main/java/org/springframework/beans/factory/CannotLoadBeanClassException.java index 26de990a..17b8f162 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/CannotLoadBeanClassException.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/CannotLoadBeanClassException.java @@ -46,7 +46,7 @@ public class CannotLoadBeanClassException extends FatalBeanException { public CannotLoadBeanClassException( String resourceDescription, String beanName, String beanClassName, ClassNotFoundException cause) { - super("Cannot find class [" + String.valueOf(beanClassName) + "] for bean with name '" + beanName + "'" + + super("Cannot find class [" + beanClassName + "] for bean with name '" + beanName + "'" + (resourceDescription != null ? " defined in " + resourceDescription : ""), cause); this.resourceDescription = resourceDescription; this.beanName = beanName; @@ -64,7 +64,7 @@ public class CannotLoadBeanClassException extends FatalBeanException { public CannotLoadBeanClassException( String resourceDescription, String beanName, String beanClassName, LinkageError cause) { - super("Error loading class [" + String.valueOf(beanClassName) + "] for bean with name '" + beanName + "'" + + super("Error loading class [" + beanClassName + "] for bean with name '" + beanName + "'" + (resourceDescription != null ? " defined in " + resourceDescription : "") + ": problem with class file or dependent class", cause); this.resourceDescription = resourceDescription; diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/ObjectFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/ObjectFactory.java index 40f807dd..9b923624 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/ObjectFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/ObjectFactory.java @@ -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. @@ -40,7 +40,7 @@ public interface ObjectFactory<T> { /** * Return an instance (possibly shared or independent) * of the object managed by this factory. - * @return an instance of the bean (should never be {@code null}) + * @return the resulting instance * @throws BeansException in case of creation errors */ T getObject() throws BeansException; diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/YamlProcessor.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/YamlProcessor.java index 5acddd8c..38381ea1 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/config/YamlProcessor.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/config/YamlProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 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. @@ -25,7 +25,6 @@ import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.Map.Entry; import java.util.Properties; import java.util.Set; @@ -201,7 +200,7 @@ public abstract class YamlProcessor { } Map<Object, Object> map = (Map<Object, Object>) object; - for (Entry<Object, Object> entry : map.entrySet()) { + for (Map.Entry<Object, Object> entry : map.entrySet()) { Object value = entry.getValue(); if (value instanceof Map) { value = asMap(value); @@ -273,7 +272,7 @@ public abstract class YamlProcessor { } private void buildFlattenedMap(Map<String, Object> result, Map<String, Object> source, String path) { - for (Entry<String, Object> entry : source.entrySet()) { + for (Map.Entry<String, Object> entry : source.entrySet()) { String key = entry.getKey(); if (StringUtils.hasText(path)) { if (key.startsWith("[")) { diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java index 3c8eeacf..00adea84 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java @@ -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. @@ -908,12 +908,16 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac if (bw != null) { return (FactoryBean<?>) bw.getWrappedInstance(); } + Object beanInstance = getSingleton(beanName, false); + if (beanInstance instanceof FactoryBean) { + return (FactoryBean<?>) beanInstance; + } if (isSingletonCurrentlyInCreation(beanName) || (mbd.getFactoryBeanName() != null && isSingletonCurrentlyInCreation(mbd.getFactoryBeanName()))) { return null; } - Object instance = null; + Object instance; try { // Mark this bean as currently in creation, even if just partially. beforeSingletonCreation(beanName); @@ -1484,15 +1488,13 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac return; } + if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) { + ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext()); + } + MutablePropertyValues mpvs = null; List<PropertyValue> original; - if (System.getSecurityManager() != null) { - if (bw instanceof BeanWrapperImpl) { - ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext()); - } - } - if (pvs instanceof MutablePropertyValues) { mpvs = (MutablePropertyValues) pvs; if (mpvs.isConverted()) { @@ -1628,7 +1630,6 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } - if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } @@ -1780,8 +1781,21 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac */ @Override protected void removeSingleton(String beanName) { - super.removeSingleton(beanName); - this.factoryBeanInstanceCache.remove(beanName); + synchronized (getSingletonMutex()) { + super.removeSingleton(beanName); + this.factoryBeanInstanceCache.remove(beanName); + } + } + + /** + * Overridden to clear FactoryBean instance cache as well. + */ + @Override + protected void clearSingletonCache() { + synchronized (getSingletonMutex()) { + super.clearSingletonCache(); + this.factoryBeanInstanceCache.clear(); + } } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java index 279da655..9e0044c0 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java @@ -293,7 +293,13 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); } registerDependentBean(dep, beanName); - getBean(dep); + try { + getBean(dep); + } + catch (NoSuchBeanDefinitionException ex) { + throw new BeanCreationException(mbd.getResourceDescription(), beanName, + "'" + beanName + "' depends on missing bean '" + dep + "'", ex); + } } } @@ -1509,7 +1515,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp return getTypeForFactoryBean(factoryBean); } catch (BeanCreationException ex) { - if (ex instanceof BeanCurrentlyInCreationException) { + if (ex.contains(BeanCurrentlyInCreationException.class)) { if (logger.isDebugEnabled()) { logger.debug("Bean currently in creation on FactoryBean type check: " + ex); } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AutowireCandidateQualifier.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AutowireCandidateQualifier.java index f5991ac9..9674e5cc 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AutowireCandidateQualifier.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AutowireCandidateQualifier.java @@ -32,7 +32,7 @@ import org.springframework.util.Assert; @SuppressWarnings("serial") public class AutowireCandidateQualifier extends BeanMetadataAttributeAccessor { - public static String VALUE_KEY = "value"; + public static final String VALUE_KEY = "value"; private final String typeName; diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/ConstructorResolver.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/ConstructorResolver.java index 7c871d46..aa485efc 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/ConstructorResolver.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/ConstructorResolver.java @@ -855,11 +855,11 @@ class ConstructorResolver { */ private static class ArgumentsHolder { - public final Object rawArguments[]; + public final Object[] rawArguments; - public final Object arguments[]; + public final Object[] arguments; - public final Object preparedArguments[]; + public final Object[] preparedArguments; public boolean resolveNecessary = false; diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java index 8269379b..58ee2b2d 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java @@ -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. @@ -419,7 +419,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); // Only check bean definition if it is complete. if (!mbd.isAbstract() && (allowEagerInit || - ((mbd.hasBeanClass() || !mbd.isLazyInit() || isAllowEagerClassLoading())) && + (mbd.hasBeanClass() || !mbd.isLazyInit() || isAllowEagerClassLoading()) && !requiresEagerInitForType(mbd.getFactoryBeanName()))) { // In case of FactoryBean, match object created by FactoryBean. boolean isFactoryBean = isFactoryBean(beanName, mbd); @@ -553,7 +553,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto results.add(beanName); } } - return results.toArray(new String[results.size()]); + return StringUtils.toStringArray(results); } @Override @@ -1009,7 +1009,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto } } if (!autowireCandidates.isEmpty()) { - candidateNames = autowireCandidates.toArray(new String[autowireCandidates.size()]); + candidateNames = StringUtils.toStringArray(autowireCandidates); } } @@ -1742,7 +1742,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto if (targetType != null && targetType != obj.getClass()) { sources.add(targetType); } - return sources.toArray(new Object[sources.size()]); + return sources.toArray(); } private RootBeanDefinition getRootBeanDefinition(String beanName) { diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultSingletonBeanRegistry.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultSingletonBeanRegistry.java index 17b949a1..c40dc7ba 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultSingletonBeanRegistry.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultSingletonBeanRegistry.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 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. @@ -386,15 +386,8 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements * @see #registerDependentBean */ public void registerContainedBean(String containedBeanName, String containingBeanName) { - // A quick check for an existing entry upfront, avoiding synchronization... - Set<String> containedBeans = this.containedBeanMap.get(containingBeanName); - if (containedBeans != null && containedBeans.contains(containedBeanName)) { - return; - } - - // No entry yet -> fully synchronized manipulation of the containedBeans Set synchronized (this.containedBeanMap) { - containedBeans = this.containedBeanMap.get(containingBeanName); + Set<String> containedBeans = this.containedBeanMap.get(containingBeanName); if (containedBeans == null) { containedBeans = new LinkedHashSet<String>(8); this.containedBeanMap.put(containingBeanName, containedBeans); @@ -411,16 +404,10 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements * @param dependentBeanName the name of the dependent bean */ public void registerDependentBean(String beanName, String dependentBeanName) { - // A quick check for an existing entry upfront, avoiding synchronization... String canonicalName = canonicalName(beanName); - Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName); - if (dependentBeans != null && dependentBeans.contains(dependentBeanName)) { - return; - } - // No entry yet -> fully synchronized manipulation of the dependentBeans Set synchronized (this.dependentBeanMap) { - dependentBeans = this.dependentBeanMap.get(canonicalName); + Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName); if (dependentBeans == null) { dependentBeans = new LinkedHashSet<String>(8); this.dependentBeanMap.put(canonicalName, dependentBeans); @@ -445,7 +432,9 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements * @since 4.0 */ protected boolean isDependent(String beanName, String dependentBeanName) { - return isDependent(beanName, dependentBeanName, null); + synchronized (this.dependentBeanMap) { + return isDependent(beanName, dependentBeanName, null); + } } private boolean isDependent(String beanName, String dependentBeanName, Set<String> alreadySeen) { @@ -490,7 +479,9 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements if (dependentBeans == null) { return new String[0]; } - return StringUtils.toStringArray(dependentBeans); + synchronized (this.dependentBeanMap) { + return StringUtils.toStringArray(dependentBeans); + } } /** @@ -504,7 +495,9 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements if (dependenciesForBean == null) { return new String[0]; } - return dependenciesForBean.toArray(new String[dependenciesForBean.size()]); + synchronized (this.dependenciesForBeanMap) { + return StringUtils.toStringArray(dependenciesForBean); + } } public void destroySingletons() { @@ -527,6 +520,14 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements this.dependentBeanMap.clear(); this.dependenciesForBeanMap.clear(); + clearSingletonCache(); + } + + /** + * Clear all cached singleton instances in this registry. + * @since 4.3.15 + */ + protected void clearSingletonCache() { synchronized (this.singletonObjects) { this.singletonObjects.clear(); this.singletonFactories.clear(); @@ -562,7 +563,11 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements */ protected void destroyBean(String beanName, DisposableBean bean) { // Trigger destruction of dependent beans first... - Set<String> dependencies = this.dependentBeanMap.remove(beanName); + Set<String> dependencies; + synchronized (this.dependentBeanMap) { + // Within full synchronization in order to guarantee a disconnected Set + dependencies = this.dependentBeanMap.remove(beanName); + } if (dependencies != null) { if (logger.isDebugEnabled()) { logger.debug("Retrieved dependent beans for bean '" + beanName + "': " + dependencies); @@ -583,7 +588,11 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements } // Trigger destruction of contained beans... - Set<String> containedBeans = this.containedBeanMap.remove(beanName); + Set<String> containedBeans; + synchronized (this.containedBeanMap) { + // Within full synchronization in order to guarantee a disconnected Set + containedBeans = this.containedBeanMap.remove(beanName); + } if (containedBeans != null) { for (String containedBeanName : containedBeans) { destroySingleton(containedBeanName); diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/FactoryBeanRegistrySupport.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/FactoryBeanRegistrySupport.java index 1170486b..b2177c70 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/FactoryBeanRegistrySupport.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/FactoryBeanRegistrySupport.java @@ -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. @@ -117,7 +117,9 @@ public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanReg "Post-processing of FactoryBean's singleton object failed", ex); } } - this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT)); + if (containsSingleton(beanName)) { + this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT)); + } } } return (object != NULL_OBJECT ? object : null); @@ -218,17 +220,21 @@ public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanReg */ @Override protected void removeSingleton(String beanName) { - super.removeSingleton(beanName); - this.factoryBeanObjectCache.remove(beanName); + synchronized (getSingletonMutex()) { + super.removeSingleton(beanName); + this.factoryBeanObjectCache.remove(beanName); + } } /** * Overridden to clear the FactoryBean object cache as well. */ @Override - public void destroySingletons() { - super.destroySingletons(); - this.factoryBeanObjectCache.clear(); + protected void clearSingletonCache() { + synchronized (getSingletonMutex()) { + super.clearSingletonCache(); + this.factoryBeanObjectCache.clear(); + } } /** diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java index 12eaf2d5..f5aee86b 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java @@ -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. @@ -333,7 +333,7 @@ public class StaticListableBeanFactory implements ListableBeanFactory { results.add(beanName); } } - return results.toArray(new String[results.size()]); + return StringUtils.toStringArray(results); } @Override diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/xml/BeanDefinitionParserDelegate.java b/spring-beans/src/main/java/org/springframework/beans/factory/xml/BeanDefinitionParserDelegate.java index 89b1726d..64d429c4 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/xml/BeanDefinitionParserDelegate.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/xml/BeanDefinitionParserDelegate.java @@ -402,8 +402,8 @@ public class BeanDefinitionParserDelegate { public BeanDefinitionDefaults getBeanDefinitionDefaults() { BeanDefinitionDefaults bdd = new BeanDefinitionDefaults(); bdd.setLazyInit("TRUE".equalsIgnoreCase(this.defaults.getLazyInit())); - bdd.setDependencyCheck(this.getDependencyCheck(DEFAULT_VALUE)); - bdd.setAutowireMode(this.getAutowireMode(DEFAULT_VALUE)); + bdd.setDependencyCheck(getDependencyCheck(DEFAULT_VALUE)); + bdd.setAutowireMode(getAutowireMode(DEFAULT_VALUE)); bdd.setInitMethodName(this.defaults.getInitMethod()); bdd.setDestroyMethodName(this.defaults.getDestroyMethod()); return bdd; @@ -1255,7 +1255,7 @@ public class BeanDefinitionParserDelegate { boolean hasKeyAttribute = entryEle.hasAttribute(KEY_ATTRIBUTE); boolean hasKeyRefAttribute = entryEle.hasAttribute(KEY_REF_ATTRIBUTE); if ((hasKeyAttribute && hasKeyRefAttribute) || - ((hasKeyAttribute || hasKeyRefAttribute)) && keyEle != null) { + (hasKeyAttribute || hasKeyRefAttribute) && keyEle != null) { error("<entry> element is only allowed to contain either " + "a 'key' attribute OR a 'key-ref' attribute OR a <key> sub-element", entryEle); } @@ -1284,7 +1284,7 @@ public class BeanDefinitionParserDelegate { boolean hasValueRefAttribute = entryEle.hasAttribute(VALUE_REF_ATTRIBUTE); boolean hasValueTypeAttribute = entryEle.hasAttribute(VALUE_TYPE_ATTRIBUTE); if ((hasValueAttribute && hasValueRefAttribute) || - ((hasValueAttribute || hasValueRefAttribute)) && valueEle != null) { + (hasValueAttribute || hasValueRefAttribute) && valueEle != null) { error("<entry> element is only allowed to contain either " + "'value' attribute OR 'value-ref' attribute OR <value> sub-element", entryEle); } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/xml/BeansDtdResolver.java b/spring-beans/src/main/java/org/springframework/beans/factory/xml/BeansDtdResolver.java index ad096bff..fe971fdc 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/xml/BeansDtdResolver.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/xml/BeansDtdResolver.java @@ -58,7 +58,7 @@ public class BeansDtdResolver implements EntityResolver { "] and system ID [" + systemId + "]"); } if (systemId != null && systemId.endsWith(DTD_EXTENSION)) { - int lastPathSeparator = systemId.lastIndexOf("/"); + int lastPathSeparator = systemId.lastIndexOf('/'); int dtdNameStart = systemId.indexOf(DTD_NAME, lastPathSeparator); if (dtdNameStart != -1) { String dtdFile = DTD_FILENAME + DTD_EXTENSION; diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/xml/ParserContext.java b/spring-beans/src/main/java/org/springframework/beans/factory/xml/ParserContext.java index c36314c0..2c780cd4 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/xml/ParserContext.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/xml/ParserContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 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. @@ -44,7 +44,7 @@ public final class ParserContext { private BeanDefinition containingBeanDefinition; - private final Stack<ComponentDefinition> containingComponents = new Stack<ComponentDefinition>(); + private final Stack<CompositeComponentDefinition> containingComponents = new Stack<CompositeComponentDefinition>(); public ParserContext(XmlReaderContext readerContext, BeanDefinitionParserDelegate delegate) { @@ -90,8 +90,7 @@ public final class ParserContext { } public CompositeComponentDefinition getContainingComponent() { - return (!this.containingComponents.isEmpty() ? - (CompositeComponentDefinition) this.containingComponents.lastElement() : null); + return (!this.containingComponents.isEmpty() ? this.containingComponents.lastElement() : null); } public void pushContainingComponent(CompositeComponentDefinition containingComponent) { @@ -99,7 +98,7 @@ public final class ParserContext { } public CompositeComponentDefinition popContainingComponent() { - return (CompositeComponentDefinition) this.containingComponents.pop(); + return this.containingComponents.pop(); } public void popAndRegisterContainingComponent() { diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/xml/UtilNamespaceHandler.java b/spring-beans/src/main/java/org/springframework/beans/factory/xml/UtilNamespaceHandler.java index ba6b41ac..6736e0df 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/xml/UtilNamespaceHandler.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/xml/UtilNamespaceHandler.java @@ -88,7 +88,7 @@ public class UtilNamespaceHandler extends NamespaceHandlerSupport { parserContext.getReaderContext().error("Attribute 'path' must not be empty", element); return; } - int dotIndex = path.indexOf("."); + int dotIndex = path.indexOf('.'); if (dotIndex == -1) { parserContext.getReaderContext().error( "Attribute 'path' must follow pattern 'beanName.propertyName'", element); diff --git a/spring-beans/src/main/java/org/springframework/beans/propertyeditors/URIEditor.java b/spring-beans/src/main/java/org/springframework/beans/propertyeditors/URIEditor.java index 7dc173a0..dece70f1 100644 --- a/spring-beans/src/main/java/org/springframework/beans/propertyeditors/URIEditor.java +++ b/spring-beans/src/main/java/org/springframework/beans/propertyeditors/URIEditor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 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. @@ -67,6 +67,7 @@ public class URIEditor extends PropertyEditorSupport { * Create a new URIEditor, converting "classpath:" locations into * standard URIs (not trying to resolve them into physical resources). * @param encode indicates whether Strings will be encoded or not + * @since 3.0 */ public URIEditor(boolean encode) { this.classLoader = null; @@ -89,6 +90,7 @@ public class URIEditor extends PropertyEditorSupport { * @param classLoader the ClassLoader to use for resolving "classpath:" locations * (may be {@code null} to indicate the default ClassLoader) * @param encode indicates whether Strings will be encoded or not + * @since 3.0 */ public URIEditor(ClassLoader classLoader, boolean encode) { this.classLoader = (classLoader != null ? classLoader : ClassUtils.getDefaultClassLoader()); @@ -101,18 +103,14 @@ public class URIEditor extends PropertyEditorSupport { if (StringUtils.hasText(text)) { String uri = text.trim(); if (this.classLoader != null && uri.startsWith(ResourceUtils.CLASSPATH_URL_PREFIX)) { - ClassPathResource resource = - new ClassPathResource(uri.substring(ResourceUtils.CLASSPATH_URL_PREFIX.length()), this.classLoader); + ClassPathResource resource = new ClassPathResource( + uri.substring(ResourceUtils.CLASSPATH_URL_PREFIX.length()), this.classLoader); try { - String url = resource.getURL().toString(); - setValue(createURI(url)); + setValue(resource.getURI()); } catch (IOException ex) { throw new IllegalArgumentException("Could not retrieve URI for " + resource + ": " + ex.getMessage()); } - catch (URISyntaxException ex) { - throw new IllegalArgumentException("Invalid URI syntax: " + ex); - } } else { try { @@ -129,9 +127,8 @@ public class URIEditor extends PropertyEditorSupport { } /** - * Create a URI instance for the given (resolved) String value. - * <p>The default implementation encodes the value into a RFC - * 2396 compliant URI. + * Create a URI instance for the given user-specified String value. + * <p>The default implementation encodes the value into a RFC-2396 compliant URI. * @param value the value to convert into a URI instance * @return the URI instance * @throws java.net.URISyntaxException if URI conversion failed |