private Object newValue(Class<?> type, String name) { try { if (type.isArray()) { Class<?> componentType = type.getComponentType(); // TODO - only handles 2-dimensional arrays if (componentType.isArray()) { Object array = Array.newInstance(componentType, 1); Array.set(array, 0, Array.newInstance(componentType.getComponentType(), 0)); return array; } else { return Array.newInstance(componentType, 0); } } else if (Collection.class.isAssignableFrom(type)) { return CollectionFactory.createCollection(type, 16); } else if (Map.class.isAssignableFrom(type)) { return CollectionFactory.createMap(type, 16); } else { return type.newInstance(); } } catch (Exception ex) { // TODO Root cause exception context is lost here... should we throw another exception type // that preserves context instead? throw new NullValueInNestedPathException( getRootClass(), this.nestedPath + name, "Could not instantiate property type [" + type.getName() + "] to auto-grow nested property path: " + ex); } }
/** * 将对象中的属性值置入到fields中。 * * <p>对于<code>isValidated()</code>为<code>true</code>的group,该方法无效。 */ public void mapTo(Object object) { if (isValidated() || object == null) { return; } if (log.isDebugEnabled()) { log.debug( "Mapping properties to fields: group=\"{}\", object={}", getName(), ObjectUtil.identityToString(object)); } BeanWrapper bean = new BeanWrapperImpl(object); getForm().getFormConfig().getPropertyEditorRegistrar().registerCustomEditors(bean); for (Field field : getFields()) { String propertyName = field.getFieldConfig().getPropertyName(); if (bean.isReadableProperty(propertyName)) { Object propertyValue = bean.getPropertyValue(propertyName); Class<?> propertyType = bean.getPropertyType(propertyName); PropertyEditor editor = bean.findCustomEditor(propertyType, propertyName); if (editor == null) { editor = BeanUtils.findEditorByConvention(propertyType); } if (editor == null) { if (propertyType.isArray() || CollectionFactory.isApproximableCollectionType(propertyType)) { field.setValues((String[]) bean.convertIfNecessary(propertyValue, String[].class)); } else { field.setValue(bean.convertIfNecessary(propertyValue, String.class)); } } else { editor.setValue(propertyValue); field.setValue(editor.getAsText()); } } else { log.debug( "No readable property \"{}\" found in type {}", propertyName, object.getClass().getName()); } } }
/** * Reads the given {@link DBObject} into a {@link Map}. will recursively resolve nested {@link * Map}s as well. * * @param type the {@link Map} {@link TypeInformation} to be used to unmarshall this {@link * DBObject}. * @param dbObject must not be {@literal null} * @param path must not be {@literal null} * @return */ @SuppressWarnings("unchecked") protected Map<Object, Object> readMap( TypeInformation<?> type, DBObject dbObject, ObjectPath path) { Assert.notNull(dbObject, "DBObject must not be null!"); Assert.notNull(path, "Object path must not be null!"); Class<?> mapType = typeMapper.readType(dbObject, type).getType(); TypeInformation<?> keyType = type.getComponentType(); Class<?> rawKeyType = keyType == null ? null : keyType.getType(); TypeInformation<?> valueType = type.getMapValueType(); Class<?> rawValueType = valueType == null ? null : valueType.getType(); Map<Object, Object> map = CollectionFactory.createMap(mapType, rawKeyType, dbObject.keySet().size()); Map<String, Object> sourceMap = dbObject.toMap(); for (Entry<String, Object> entry : sourceMap.entrySet()) { if (typeMapper.isTypeKey(entry.getKey())) { continue; } Object key = potentiallyUnescapeMapKey(entry.getKey()); if (rawKeyType != null) { key = conversionService.convert(key, rawKeyType); } Object value = entry.getValue(); if (value instanceof DBObject) { map.put(key, read(valueType, (DBObject) value, path)); } else if (value instanceof DBRef) { map.put( key, DBRef.class.equals(rawValueType) ? value : read(valueType, readRef((DBRef) value))); } else { Class<?> valueClass = valueType == null ? null : valueType.getType(); map.put(key, getPotentiallyConvertedSimpleRead(value, valueClass)); } } return map; }
/** * Reads the given {@link BasicDBList} into a collection of the given {@link TypeInformation}. * * @param targetType must not be {@literal null}. * @param sourceValue must not be {@literal null}. * @param path must not be {@literal null}. * @return the converted {@link Collection} or array, will never be {@literal null}. */ private Object readCollectionOrArray( TypeInformation<?> targetType, BasicDBList sourceValue, ObjectPath path) { Assert.notNull(targetType, "Target type must not be null!"); Assert.notNull(path, "Object path must not be null!"); Class<?> collectionType = targetType.getType(); if (sourceValue.isEmpty()) { return getPotentiallyConvertedSimpleRead(new HashSet<Object>(), collectionType); } TypeInformation<?> componentType = targetType.getComponentType(); Class<?> rawComponentType = componentType == null ? null : componentType.getType(); collectionType = Collection.class.isAssignableFrom(collectionType) ? collectionType : List.class; Collection<Object> items = targetType.getType().isArray() ? new ArrayList<Object>() : CollectionFactory.createCollection( collectionType, rawComponentType, sourceValue.size()); for (int i = 0; i < sourceValue.size(); i++) { Object dbObjItem = sourceValue.get(i); if (dbObjItem instanceof DBRef) { items.add( DBRef.class.equals(rawComponentType) ? dbObjItem : read(componentType, readRef((DBRef) dbObjItem), path)); } else if (dbObjItem instanceof DBObject) { items.add(read(componentType, (DBObject) dbObjItem, path)); } else { items.add(getPotentiallyConvertedSimpleRead(dbObjItem, rawComponentType)); } } return getPotentiallyConvertedSimpleRead(items, targetType.getType()); }
public Map getBeansOfType(Class type, boolean includePrototypes, boolean includeFactoryBeans) throws BeansException { String[] beanNames = getBeanNamesForType(type, includePrototypes, includeFactoryBeans); Map result = CollectionFactory.createLinkedMapIfPossible(beanNames.length); for (int i = 0; i < beanNames.length; i++) { String beanName = beanNames[i]; try { result.put(beanName, getBean(beanName)); } catch (BeanCreationException ex) { if (ex.contains(BeanCurrentlyInCreationException.class)) { if (logger.isDebugEnabled()) { logger.debug("Ignoring match to currently created bean '" + beanName + "'", ex); } // Ignore: indicates a circular reference when autowiring constructors. // We want to find matches other than the currently created bean itself. } else { throw ex; } } } return result; }
@Override public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { if (source == null) { return null; } String string = (String) source; String[] fields = StringUtils.commaDelimitedListToStringArray(string); Collection<Object> target = CollectionFactory.createCollection(targetType.getType(), fields.length); if (targetType.getElementTypeDescriptor() == null) { for (String field : fields) { target.add(field.trim()); } } else { for (String field : fields) { Object targetElement = this.conversionService.convert( field.trim(), sourceType, targetType.getElementTypeDescriptor()); target.add(targetElement); } } return target; }
/** @author diogomariano */ public class CpfHttpServletRequest implements HttpServletRequest { public static final String DEFAULT_PROTOCOL = "http"; public static final String DEFAULT_SERVER_ADDR = "127.0.0.1"; public static final String DEFAULT_SERVER_NAME = "localhost"; public static final int DEFAULT_SERVER_PORT = 8080; public static final String DEFAULT_REMOTE_ADDR = "127.0.0.1"; public static final String DEFAULT_REMOTE_HOST = "localhost"; private String protocol = DEFAULT_PROTOCOL; private String scheme = DEFAULT_PROTOCOL; private String serverName = DEFAULT_SERVER_NAME; private int serverPort = DEFAULT_SERVER_PORT; private int localPort = DEFAULT_SERVER_PORT; private boolean secure = false; private int remotePort = DEFAULT_SERVER_PORT; private String localName = DEFAULT_SERVER_NAME; private String localAddr = DEFAULT_SERVER_ADDR; private String remoteAddr = DEFAULT_REMOTE_ADDR; private String remoteHost = DEFAULT_REMOTE_HOST; private final ServletContext servletContext; private String method; private String pathInfo; private String requestURI; private String contextPath = ""; private final Vector locales = new Vector(); private String authType; private Cookie[] cookies; private final Hashtable headers = new Hashtable(); private final Hashtable attributes = new Hashtable(); private final Map parameters = CollectionFactory.createLinkedMapIfPossible(16); private final Set userRoles = new HashSet(); private boolean active = true; private String servletPath; private Principal userPrincipal; private String queryString; private String remoteUser; private HttpSession session; private boolean requestedSessionIdValid = true; private boolean requestedSessionIdFromCookie = true; private boolean requestedSessionIdFromURL = false; private String characterEncoding; private byte[] content; private String contentType; public CpfHttpServletRequest() { this(null, "", ""); } public CpfHttpServletRequest(String method, String requestURI) { this(null, method, requestURI); } public CpfHttpServletRequest(ServletContext servletContext) { this(servletContext, "", ""); } public CpfHttpServletRequest(ServletContext servletContext, String method, String requestURI) { this.servletContext = (servletContext != null ? servletContext : new CpfServletContext()); this.method = method; this.requestURI = requestURI; this.locales.add(Locale.ENGLISH); } public boolean isActive() { return this.active; } public void close() { this.active = false; } public void invalidate() { close(); clearAttributes(); } protected void checkActive() throws IllegalStateException { if (!this.active) { throw new IllegalStateException("Request is not active anymore"); } } @Override public String getAuthType() { return this.authType; } public void setAuthType(String authType) { this.authType = authType; } @Override public Cookie[] getCookies() { return this.cookies; } public void setCookies(Cookie[] cookies) { this.cookies = cookies; } public void addHeader(String name, Object value) { HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name); if (header == null) { header = new HeaderValueHolder(); this.headers.put(name, header); } if (value instanceof Collection) { header.addValues((Collection) value); } else if (value.getClass().isArray()) { header.addValueArray(value); } else { header.addValue(value); } } @Override public long getDateHeader(String name) { HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name); Object value = (header != null ? header.getValue() : null); if (value instanceof Date) { return ((Date) value).getTime(); } else if (value instanceof Number) { return ((Number) value).longValue(); } else if (value != null) { throw new IllegalArgumentException( "Value for header '" + name + "' is neither a Date nor a Number: " + value); } else { return -1L; } } @Override public String getHeader(String name) { HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name); return (header != null ? header.getValue().toString() : null); } @Override public Enumeration getHeaders(String name) { HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name); return Collections.enumeration(header != null ? header.getValues() : Collections.EMPTY_LIST); } @Override public Enumeration getHeaderNames() { return this.headers.keys(); } @Override public int getIntHeader(String name) { HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name); Object value = (header != null ? header.getValue() : null); if (value instanceof Number) { return ((Number) value).intValue(); } else if (value instanceof String) { return Integer.parseInt((String) value); } else if (value != null) { throw new NumberFormatException("Value for header '" + name + "' is not a Number: " + value); } else { return -1; } } @Override public String getMethod() { return this.method; } public void setMethod() { this.method = method; } @Override public String getPathInfo() { return this.pathInfo; } public void setPathInfo(String pathInfo) { this.pathInfo = pathInfo; } @Override public String getPathTranslated() { return (this.pathInfo != null ? getRealPath(this.pathInfo) : null); } @Override public String getContextPath() { return this.contextPath; } public void setContextPath(String contextPath) { this.contextPath = contextPath; } @Override public String getQueryString() { return this.queryString; } public void setQueryString(String queryString) { this.queryString = queryString; } @Override public String getRemoteUser() { throw new UnsupportedOperationException("Not supported yet."); } public void setRemoteUser(String remoteUser) { this.remoteUser = remoteUser; } public void addRole(String role) { addUserRole(role); } public void addUserRole(String role) { this.userRoles.add(role); } @Override public boolean isUserInRole(String role) { return this.userRoles.contains(role); } @Override public Principal getUserPrincipal() { return this.userPrincipal; } public void setUserPrincipal(Principal userPrincipal) { this.userPrincipal = userPrincipal; } @Override public String getRequestedSessionId() { HttpSession session = getSession(); return (session != null ? session.getId() : null); } @Override public String getRequestURI() { return this.requestURI; } public void setRequestURI(String requestURI) { this.requestURI = requestURI; } @Override public StringBuffer getRequestURL() { StringBuffer url = new StringBuffer(this.scheme); url.append("://").append(this.serverName).append(':').append(this.serverPort); url.append(getRequestURI()); return url; } @Override public String getServletPath() { return this.servletPath; } public void setServletPath(String servletPath) { this.servletPath = servletPath; } @Override public HttpSession getSession(boolean create) { checkActive(); // Reset session if invalidated. if (this.session instanceof CpfHttpSession && ((CpfHttpSession) this.session).isInvalid()) { this.session = null; } // Create new session if necessary. if (this.session == null && create) { this.session = new CpfHttpSession(this.servletContext); } return this.session; } @Override public HttpSession getSession() { return getSession(true); } public void setSession(HttpSession session) { this.session = session; if (session instanceof CpfHttpSession) { CpfHttpSession cpfSession = ((CpfHttpSession) session); cpfSession.access(); } } @Override public boolean isRequestedSessionIdValid() { return this.requestedSessionIdValid; } public void setRequestedSessionIdValid(boolean requestedSessionIdValid) { this.requestedSessionIdValid = requestedSessionIdValid; } @Override public boolean isRequestedSessionIdFromCookie() { return this.requestedSessionIdFromCookie; } public void setRequestedSessionIdFromCookie(boolean requestedSessionIdFromCookie) { this.requestedSessionIdFromCookie = requestedSessionIdFromCookie; } @Override public boolean isRequestedSessionIdFromURL() { return this.requestedSessionIdFromURL; } public boolean isRequestedSessionIdFromUrl() { return isRequestedSessionIdFromURL(); } public void setRequestedSessionIdFromURL(boolean requestedSessionIdFromURL) { this.requestedSessionIdFromURL = requestedSessionIdFromURL; } @Override public Object getAttribute(String name) { checkActive(); return this.attributes.get(name); } @Override public Enumeration getAttributeNames() { return this.attributes.keys(); } @Override public String getCharacterEncoding() { return this.characterEncoding; } @Override public void setCharacterEncoding(String characterEncoding) throws UnsupportedEncodingException { this.characterEncoding = characterEncoding; } public void setContent(byte[] content) { this.content = content; } @Override public int getContentLength() { return (this.content != null ? this.content.length : -1); } @Override public String getContentType() { return this.contentType; } public void setContentType(String contentType) { this.contentType = contentType; } @Override public ServletInputStream getInputStream() throws IOException { if (this.content != null) { return new DelegatingServletInputStream(new ByteArrayInputStream(this.content)); } else { return null; } } @Override public String getParameter(String name) { String[] arr = (String[]) this.parameters.get(name); return (arr != null && arr.length > 0 ? arr[0] : null); } public void setParameter(String name, String value) { setParameter(name, new String[] {value}); } public void setParameter(String name, String[] values) { this.parameters.put(name, values); } public void addParameter(String name, String value) { addParameter(name, new String[] {value}); } public void addParameter(String name, String[] values) { String[] oldArr = (String[]) this.parameters.get(name); if (oldArr != null) { String[] newArr = new String[oldArr.length + values.length]; System.arraycopy(oldArr, 0, newArr, 0, oldArr.length); System.arraycopy(values, 0, newArr, oldArr.length, values.length); this.parameters.put(name, newArr); } else { this.parameters.put(name, values); } } public void removeParameter(String name) { this.parameters.remove(name); } @Override public Enumeration getParameterNames() { return Collections.enumeration(this.parameters.keySet()); } @Override public String[] getParameterValues(String name) { return (String[]) this.parameters.get(name); } @Override public Map getParameterMap() { return Collections.unmodifiableMap(this.parameters); } @Override public String getProtocol() { return this.protocol; } public void setProtocol(String protocol) { this.protocol = protocol; } @Override public String getScheme() { return this.scheme; } public void setScheme(String scheme) { this.scheme = scheme; } @Override public String getServerName() { return this.serverName; } public void setServerName(String serverName) { this.serverName = serverName; } @Override public int getServerPort() { return this.serverPort; } public void setServerPort(int serverPort) { this.serverPort = serverPort; } @Override public BufferedReader getReader() throws IOException { if (this.content != null) { InputStream sourceStream = new ByteArrayInputStream(this.content); Reader sourceReader = (this.characterEncoding != null) ? new InputStreamReader(sourceStream, this.characterEncoding) : new InputStreamReader(sourceStream); return new BufferedReader(sourceReader); } else { return null; } } @Override public String getRemoteAddr() { return this.remoteAddr; } public void setRemoteAddr(String remoteAddr) { this.remoteAddr = remoteAddr; } @Override public String getRemoteHost() { return this.remoteHost; } public void setRemoteHost(String remoteHost) { this.remoteHost = remoteHost; } @Override public void setAttribute(String name, Object value) { checkActive(); if (value != null) { this.attributes.put(name, value); } else { this.attributes.remove(name); } } @Override public void removeAttribute(String name) { checkActive(); this.attributes.remove(name); } public void clearAttributes() { this.attributes.clear(); } public void addPreferredLocale(Locale locale) { this.locales.add(0, locale); } @Override public Locale getLocale() { return (Locale) this.locales.get(0); } @Override public Enumeration getLocales() { return this.locales.elements(); } @Override public boolean isSecure() { return this.secure; } public void setSecure(boolean secure) { this.secure = secure; } @Override public RequestDispatcher getRequestDispatcher(String path) { return new CpfRequestDispatcher(path); } @Override public String getRealPath(String path) { return this.servletContext.getRealPath(path); } @Override public int getRemotePort() { return this.remotePort; } public void setRemotePort(int remotePort) { this.remotePort = remotePort; } @Override public String getLocalName() { return this.localName; } public void setLocalName(String localName) { this.localName = localName; } @Override public String getLocalAddr() { return this.localAddr; } public void setLocalAddr(String localAddr) { this.localAddr = localAddr; } @Override public int getLocalPort() { return this.localPort; } public void setLocalPort(int localPort) { this.localPort = localPort; } }
@SuppressWarnings("unchecked") protected Map convertToTypedMap( Map original, String propertyName, Class requiredType, TypeDescriptor typeDescriptor) { boolean originalAllowed = requiredType.isInstance(original); if (!originalAllowed && !Map.class.isAssignableFrom(requiredType)) { return original; } Class keyType = null; Class valueType = null; MethodParameter methodParam = typeDescriptor.getMethodParameter(); if (methodParam != null) { keyType = GenericCollectionTypeResolver.getMapKeyParameterType(methodParam); valueType = GenericCollectionTypeResolver.getMapValueParameterType(methodParam); } if (keyType == null && valueType == null && originalAllowed && !this.propertyEditorRegistry.hasCustomEditorForElement(null, propertyName)) { return original; } Iterator it; try { it = original.entrySet().iterator(); if (it == null) { if (logger.isDebugEnabled()) { logger.debug( "Map of type [" + original.getClass().getName() + "] returned null Iterator - injecting original Map as-is"); } return original; } } catch (Throwable ex) { if (logger.isDebugEnabled()) { logger.debug( "Cannot access Map of type [" + original.getClass().getName() + "] - injecting original Map as-is", ex); } return original; } Map convertedCopy; try { if (CollectionFactory.isApproximableMapType(requiredType)) { convertedCopy = CollectionFactory.createApproximateMap(original, original.size()); } else { convertedCopy = (Map) requiredType.newInstance(); } } catch (Throwable ex) { if (logger.isDebugEnabled()) { logger.debug( "Cannot create copy of Map type [" + original.getClass().getName() + "] - injecting original Map as-is", ex); } return original; } while (it.hasNext()) { Map.Entry entry = (Map.Entry) it.next(); Object key = entry.getKey(); Object value = entry.getValue(); String keyedPropertyName = buildKeyedPropertyName(propertyName, key); if (methodParam != null) { methodParam.increaseNestingLevel(); methodParam.setTypeIndexForCurrentLevel(0); } Object convertedKey = convertIfNecessary(keyedPropertyName, null, key, keyType, typeDescriptor); if (methodParam != null) { methodParam.setTypeIndexForCurrentLevel(1); } Object convertedValue = convertIfNecessary(keyedPropertyName, null, value, valueType, typeDescriptor); if (methodParam != null) { methodParam.decreaseNestingLevel(); } try { convertedCopy.put(convertedKey, convertedValue); } catch (Throwable ex) { if (logger.isDebugEnabled()) { logger.debug( "Map type [" + original.getClass().getName() + "] seems to be read-only - injecting original Map as-is", ex); } return original; } originalAllowed = originalAllowed && (key == convertedKey) && (value == convertedValue); } return (originalAllowed ? original : convertedCopy); }
@SuppressWarnings("unchecked") protected Collection convertToTypedCollection( Collection original, String propertyName, Class requiredType, TypeDescriptor typeDescriptor) { boolean originalAllowed = requiredType.isInstance(original); if (!originalAllowed && !Collection.class.isAssignableFrom(requiredType)) { return original; } MethodParameter methodParam = typeDescriptor.getMethodParameter(); Class elementType = null; if (methodParam != null) { elementType = GenericCollectionTypeResolver.getCollectionParameterType(methodParam); } if (elementType == null && originalAllowed && !this.propertyEditorRegistry.hasCustomEditorForElement(null, propertyName)) { return original; } Iterator it; try { it = original.iterator(); if (it == null) { if (logger.isDebugEnabled()) { logger.debug( "Collection of type [" + original.getClass().getName() + "] returned null Iterator - injecting original Collection as-is"); } return original; } } catch (Throwable ex) { if (logger.isDebugEnabled()) { logger.debug( "Cannot access Collection of type [" + original.getClass().getName() + "] - injecting original Collection as-is", ex); } return original; } Collection convertedCopy; try { if (CollectionFactory.isApproximableCollectionType(requiredType)) { convertedCopy = CollectionFactory.createApproximateCollection(original, original.size()); } else { convertedCopy = (Collection) requiredType.newInstance(); } } catch (Throwable ex) { if (logger.isDebugEnabled()) { logger.debug( "Cannot create copy of Collection type [" + original.getClass().getName() + "] - injecting original Collection as-is", ex); } return original; } int i = 0; for (; it.hasNext(); i++) { Object element = it.next(); String indexedPropertyName = buildIndexedPropertyName(propertyName, i); if (methodParam != null) { methodParam.increaseNestingLevel(); } Object convertedElement = convertIfNecessary(indexedPropertyName, null, element, elementType, typeDescriptor); if (methodParam != null) { methodParam.decreaseNestingLevel(); } try { convertedCopy.add(convertedElement); } catch (Throwable ex) { if (logger.isDebugEnabled()) { logger.debug( "Collection type [" + original.getClass().getName() + "] seems to be read-only - injecting original Collection as-is", ex); } return original; } originalAllowed = originalAllowed && (element == convertedElement); } return (originalAllowed ? original : convertedCopy); }
@SuppressWarnings("unchecked") private Map<?, ?> convertToTypedMap( Map<?, ?> original, String propertyName, Class<?> requiredType, TypeDescriptor typeDescriptor) { if (!Map.class.isAssignableFrom(requiredType)) { return original; } boolean approximable = CollectionFactory.isApproximableMapType(requiredType); if (!approximable && !canCreateCopy(requiredType)) { if (logger.isDebugEnabled()) { logger.debug( "Custom Map type [" + original.getClass().getName() + "] does not allow for creating a copy - injecting original Map as-is"); } return original; } boolean originalAllowed = requiredType.isInstance(original); TypeDescriptor keyType = typeDescriptor.getMapKeyTypeDescriptor(); TypeDescriptor valueType = typeDescriptor.getMapValueTypeDescriptor(); if (keyType == null && valueType == null && originalAllowed && !this.propertyEditorRegistry.hasCustomEditorForElement(null, propertyName)) { return original; } Iterator<?> it; try { it = original.entrySet().iterator(); if (it == null) { if (logger.isDebugEnabled()) { logger.debug( "Map of type [" + original.getClass().getName() + "] returned null Iterator - injecting original Map as-is"); } return original; } } catch (Throwable ex) { if (logger.isDebugEnabled()) { logger.debug( "Cannot access Map of type [" + original.getClass().getName() + "] - injecting original Map as-is: " + ex); } return original; } Map<Object, Object> convertedCopy; try { if (approximable) { convertedCopy = CollectionFactory.createApproximateMap(original, original.size()); } else { convertedCopy = (Map<Object, Object>) ReflectionUtils.accessibleConstructor(requiredType).newInstance(); } } catch (Throwable ex) { if (logger.isDebugEnabled()) { logger.debug( "Cannot create copy of Map type [" + original.getClass().getName() + "] - injecting original Map as-is: " + ex); } return original; } while (it.hasNext()) { Map.Entry<?, ?> entry = (Map.Entry<?, ?>) it.next(); Object key = entry.getKey(); Object value = entry.getValue(); String keyedPropertyName = buildKeyedPropertyName(propertyName, key); Object convertedKey = convertIfNecessary( keyedPropertyName, null, key, (keyType != null ? keyType.getType() : null), keyType); Object convertedValue = convertIfNecessary( keyedPropertyName, null, value, (valueType != null ? valueType.getType() : null), valueType); try { convertedCopy.put(convertedKey, convertedValue); } catch (Throwable ex) { if (logger.isDebugEnabled()) { logger.debug( "Map type [" + original.getClass().getName() + "] seems to be read-only - injecting original Map as-is: " + ex); } return original; } originalAllowed = originalAllowed && (key == convertedKey) && (value == convertedValue); } return (originalAllowed ? original : convertedCopy); }
@SuppressWarnings("unchecked") private Collection<?> convertToTypedCollection( Collection<?> original, String propertyName, Class<?> requiredType, TypeDescriptor typeDescriptor) { if (!Collection.class.isAssignableFrom(requiredType)) { return original; } boolean approximable = CollectionFactory.isApproximableCollectionType(requiredType); if (!approximable && !canCreateCopy(requiredType)) { if (logger.isDebugEnabled()) { logger.debug( "Custom Collection type [" + original.getClass().getName() + "] does not allow for creating a copy - injecting original Collection as-is"); } return original; } boolean originalAllowed = requiredType.isInstance(original); TypeDescriptor elementType = typeDescriptor.getElementTypeDescriptor(); if (elementType == null && originalAllowed && !this.propertyEditorRegistry.hasCustomEditorForElement(null, propertyName)) { return original; } Iterator<?> it; try { it = original.iterator(); if (it == null) { if (logger.isDebugEnabled()) { logger.debug( "Collection of type [" + original.getClass().getName() + "] returned null Iterator - injecting original Collection as-is"); } return original; } } catch (Throwable ex) { if (logger.isDebugEnabled()) { logger.debug( "Cannot access Collection of type [" + original.getClass().getName() + "] - injecting original Collection as-is: " + ex); } return original; } Collection<Object> convertedCopy; try { if (approximable) { convertedCopy = CollectionFactory.createApproximateCollection(original, original.size()); } else { convertedCopy = (Collection<Object>) ReflectionUtils.accessibleConstructor(requiredType).newInstance(); } } catch (Throwable ex) { if (logger.isDebugEnabled()) { logger.debug( "Cannot create copy of Collection type [" + original.getClass().getName() + "] - injecting original Collection as-is: " + ex); } return original; } int i = 0; for (; it.hasNext(); i++) { Object element = it.next(); String indexedPropertyName = buildIndexedPropertyName(propertyName, i); Object convertedElement = convertIfNecessary( indexedPropertyName, null, element, (elementType != null ? elementType.getType() : null), elementType); try { convertedCopy.add(convertedElement); } catch (Throwable ex) { if (logger.isDebugEnabled()) { logger.debug( "Collection type [" + original.getClass().getName() + "] seems to be read-only - injecting original Collection as-is: " + ex); } return original; } originalAllowed = originalAllowed && (element == convertedElement); } return (originalAllowed ? original : convertedCopy); }