|
|
|
@ -1,5 +1,5 @@ |
|
|
|
/* |
|
|
|
/* |
|
|
|
* Copyright 2002-2010 the original author or authors. |
|
|
|
* Copyright 2002-2011 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. |
|
|
|
@ -37,6 +37,7 @@ import java.util.Set; |
|
|
|
|
|
|
|
|
|
|
|
import org.apache.commons.logging.Log; |
|
|
|
import org.apache.commons.logging.Log; |
|
|
|
import org.apache.commons.logging.LogFactory; |
|
|
|
import org.apache.commons.logging.LogFactory; |
|
|
|
|
|
|
|
|
|
|
|
import org.springframework.core.CollectionFactory; |
|
|
|
import org.springframework.core.CollectionFactory; |
|
|
|
import org.springframework.core.GenericCollectionTypeResolver; |
|
|
|
import org.springframework.core.GenericCollectionTypeResolver; |
|
|
|
import org.springframework.core.MethodParameter; |
|
|
|
import org.springframework.core.MethodParameter; |
|
|
|
@ -119,6 +120,8 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra |
|
|
|
|
|
|
|
|
|
|
|
private boolean autoGrowNestedPaths = false; |
|
|
|
private boolean autoGrowNestedPaths = false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private int autoGrowCollectionLimit = Integer.MAX_VALUE; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Create new empty BeanWrapperImpl. Wrapped instance needs to be set afterwards. |
|
|
|
* Create new empty BeanWrapperImpl. Wrapped instance needs to be set afterwards. |
|
|
|
@ -183,6 +186,7 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra |
|
|
|
setWrappedInstance(object, nestedPath, superBw.getWrappedInstance()); |
|
|
|
setWrappedInstance(object, nestedPath, superBw.getWrappedInstance()); |
|
|
|
setExtractOldValueForEditor(superBw.isExtractOldValueForEditor()); |
|
|
|
setExtractOldValueForEditor(superBw.isExtractOldValueForEditor()); |
|
|
|
setAutoGrowNestedPaths(superBw.isAutoGrowNestedPaths()); |
|
|
|
setAutoGrowNestedPaths(superBw.isAutoGrowNestedPaths()); |
|
|
|
|
|
|
|
setAutoGrowCollectionLimit(superBw.getAutoGrowCollectionLimit()); |
|
|
|
setConversionService(superBw.getConversionService()); |
|
|
|
setConversionService(superBw.getConversionService()); |
|
|
|
setSecurityContext(superBw.acc); |
|
|
|
setSecurityContext(superBw.acc); |
|
|
|
} |
|
|
|
} |
|
|
|
@ -250,22 +254,38 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* If this BeanWrapper should "auto grow" nested paths. |
|
|
|
* Set whether this BeanWrapper should attempt to "auto-grow" a nested path that contains a null value. |
|
|
|
* When true, auto growth is triggered on nested paths when null values are encountered. |
|
|
|
* <p>If "true", a null path location will be populated with a default object value and traversed |
|
|
|
* When true, auto growth is triggered on collection properties when out of bounds indexes are accessed. |
|
|
|
* instead of resulting in a {@link NullValueInNestedPathException}. Turning this flag on also |
|
|
|
* Default is false. |
|
|
|
* enables auto-growth of collection elements when accessing an out-of-bounds index. |
|
|
|
|
|
|
|
* <p>Default is "false" on a plain BeanWrapper. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public void setAutoGrowNestedPaths(boolean autoGrowNestedPaths) { |
|
|
|
public void setAutoGrowNestedPaths(boolean autoGrowNestedPaths) { |
|
|
|
this.autoGrowNestedPaths = autoGrowNestedPaths; |
|
|
|
this.autoGrowNestedPaths = autoGrowNestedPaths; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* If this BeanWrapper should "auto grow" nested paths. |
|
|
|
* Return whether "auto-growing" of nested paths has been activated. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public boolean isAutoGrowNestedPaths() { |
|
|
|
public boolean isAutoGrowNestedPaths() { |
|
|
|
return this.autoGrowNestedPaths; |
|
|
|
return this.autoGrowNestedPaths; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Specify a limit for array and collection auto-growing. |
|
|
|
|
|
|
|
* <p>Default is unlimited on a plain BeanWrapper. |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
public void setAutoGrowCollectionLimit(int autoGrowCollectionLimit) { |
|
|
|
|
|
|
|
this.autoGrowCollectionLimit = autoGrowCollectionLimit; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Return the limit for array and collection auto-growing. |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
public int getAutoGrowCollectionLimit() { |
|
|
|
|
|
|
|
return this.autoGrowCollectionLimit; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Set the security context used during the invocation of the wrapped instance methods. |
|
|
|
* Set the security context used during the invocation of the wrapped instance methods. |
|
|
|
* Can be null. |
|
|
|
* Can be null. |
|
|
|
@ -832,7 +852,7 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra |
|
|
|
return array; |
|
|
|
return array; |
|
|
|
} |
|
|
|
} |
|
|
|
int length = Array.getLength(array); |
|
|
|
int length = Array.getLength(array); |
|
|
|
if (index >= length) { |
|
|
|
if (index >= length && index < this.autoGrowCollectionLimit) { |
|
|
|
Class<?> componentType = array.getClass().getComponentType(); |
|
|
|
Class<?> componentType = array.getClass().getComponentType(); |
|
|
|
Object newArray = Array.newInstance(componentType, index + 1); |
|
|
|
Object newArray = Array.newInstance(componentType, index + 1); |
|
|
|
System.arraycopy(array, 0, newArray, 0, length); |
|
|
|
System.arraycopy(array, 0, newArray, 0, length); |
|
|
|
@ -855,7 +875,8 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra |
|
|
|
if (!this.autoGrowNestedPaths) { |
|
|
|
if (!this.autoGrowNestedPaths) { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
if (index >= collection.size()) { |
|
|
|
int size = collection.size(); |
|
|
|
|
|
|
|
if (index >= size && index < this.autoGrowCollectionLimit) { |
|
|
|
Class elementType = GenericCollectionTypeResolver.getCollectionReturnType(pd.getReadMethod(), nestingLevel); |
|
|
|
Class elementType = GenericCollectionTypeResolver.getCollectionReturnType(pd.getReadMethod(), nestingLevel); |
|
|
|
if (elementType != null) { |
|
|
|
if (elementType != null) { |
|
|
|
for (int i = collection.size(); i < index + 1; i++) { |
|
|
|
for (int i = collection.size(); i < index + 1; i++) { |
|
|
|
|