⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 beanwrapperimpl.java

📁 一个关于Spring框架的示例应用程序,简单使用,可以参考.
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
/*
 * Copyright 2002-2004 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.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.beans;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyDescriptor;
import java.beans.PropertyEditor;
import java.beans.PropertyEditorManager;
import java.io.File;
import java.io.InputStream;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.SortedSet;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.beans.propertyeditors.ByteArrayPropertyEditor;
import org.springframework.beans.propertyeditors.ClassEditor;
import org.springframework.beans.propertyeditors.CustomBooleanEditor;
import org.springframework.beans.propertyeditors.CustomCollectionEditor;
import org.springframework.beans.propertyeditors.CustomNumberEditor;
import org.springframework.beans.propertyeditors.FileEditor;
import org.springframework.beans.propertyeditors.InputStreamEditor;
import org.springframework.beans.propertyeditors.LocaleEditor;
import org.springframework.beans.propertyeditors.PropertiesEditor;
import org.springframework.beans.propertyeditors.StringArrayPropertyEditor;
import org.springframework.beans.propertyeditors.URLEditor;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.ResourceArrayPropertyEditor;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

/**
 * Default implementation of the BeanWrapper interface that should be sufficient
 * for all typical use cases. Caches introspection results for efficiency.
 *
 * <p>Note: This class never tries to load a class by name, as this can pose
 * class loading problems in J2EE applications with multiple deployment modules.
 * The caller is responsible for loading a target class.
 *
 * <p>Note: Auto-registers default property editors from the
 * <code>org.springframework.beans.propertyeditors</code> package, which apply
 * in addition to the JDK's standard PropertyEditors. Applications can call
 * BeanWrapper's <code>registerCustomEditor</code> method to register an editor
 * for the particular instance (i.e. they're not shared across the application).
 *
 * <p>BeanWrapperImpl will convert collection and array values to the
 * corresponding target collections or arrays, if necessary. Custom property
 * editors that deal with collections or arrays can either be written via
 * PropertyEditor's <code>setValue</code>, or against a comma-delimited String
 * via <code>setAsText</code>, as String arrays are converted in such a format
 * if the array itself is not assignable.
 *
 * @author Rod Johnson
 * @author Juergen Hoeller
 * @since 15 April 2001
 * @see #registerCustomEditor
 * @see java.beans.PropertyEditorManager
 * @see java.beans.PropertyEditorSupport#setAsText
 * @see java.beans.PropertyEditorSupport#setValue
 * @see org.springframework.beans.propertyeditors.ByteArrayPropertyEditor
 * @see org.springframework.beans.propertyeditors.ClassEditor
 * @see org.springframework.beans.propertyeditors.CustomBooleanEditor
 * @see org.springframework.beans.propertyeditors.CustomNumberEditor
 * @see org.springframework.beans.propertyeditors.CustomCollectionEditor
 * @see org.springframework.beans.propertyeditors.FileEditor
 * @see org.springframework.beans.propertyeditors.InputStreamEditor
 * @see org.springframework.jndi.JndiTemplateEditor
 * @see org.springframework.beans.propertyeditors.LocaleEditor
 * @see org.springframework.beans.propertyeditors.PropertiesEditor
 * @see org.springframework.beans.PropertyValuesEditor
 * @see org.springframework.core.io.support.ResourceArrayPropertyEditor
 * @see org.springframework.core.io.ResourceEditor
 * @see org.springframework.beans.propertyeditors.StringArrayPropertyEditor
 * @see org.springframework.transaction.interceptor.TransactionAttributeEditor
 * @see org.springframework.transaction.interceptor.TransactionAttributeSourceEditor
 * @see org.springframework.beans.propertyeditors.URLEditor
 */
public class BeanWrapperImpl implements BeanWrapper {

	/** We'll create a lot of these objects, so we don't want a new logger every time */
	private static final Log logger = LogFactory.getLog(BeanWrapperImpl.class);


	//---------------------------------------------------------------------
	// Instance data
	//---------------------------------------------------------------------

	/** The wrapped object */
	private Object object;

	/** The nested path of the object */
	private String nestedPath = "";

	private Object rootObject;

	/** Registry for default PropertyEditors */
	private final Map defaultEditors;

	/** Map with custom PropertyEditor instances */
	private Map customEditors;

	/**
	 * Cached introspections results for this object, to prevent encountering
	 * the cost of JavaBeans introspection every time.
	 */
	private CachedIntrospectionResults cachedIntrospectionResults;

	/* Map with cached nested BeanWrappers */
	private Map nestedBeanWrappers;


	//---------------------------------------------------------------------
	// Constructors
	//---------------------------------------------------------------------

	/**
	 * Create new empty BeanWrapperImpl. Wrapped instance needs to be set afterwards.
	 * @see #setWrappedInstance
	 */
	public BeanWrapperImpl() {
		// Register default editors in this class, for restricted environments.
		// We're not using the JRE's PropertyEditorManager to avoid potential
		// SecurityExceptions when running in a SecurityManager.
		this.defaultEditors = new HashMap(20);

		// Simple editors, without parameterization capabilities.
		this.defaultEditors.put(byte[].class, new ByteArrayPropertyEditor());
		this.defaultEditors.put(Class.class, new ClassEditor());
		this.defaultEditors.put(File.class, new FileEditor());
		this.defaultEditors.put(InputStream.class, new InputStreamEditor());
		this.defaultEditors.put(Locale.class, new LocaleEditor());
		this.defaultEditors.put(Properties.class, new PropertiesEditor());
		this.defaultEditors.put(Resource[].class, new ResourceArrayPropertyEditor());
		this.defaultEditors.put(String[].class, new StringArrayPropertyEditor());
		this.defaultEditors.put(URL.class, new URLEditor());

		// Default instances of boolean and number editors.
		// Can be overridden by registering custom instances of those as custom editors.
		this.defaultEditors.put(Boolean.class, new CustomBooleanEditor(false));
		this.defaultEditors.put(Short.class, new CustomNumberEditor(Short.class, false));
		this.defaultEditors.put(Integer.class, new CustomNumberEditor(Integer.class, false));
		this.defaultEditors.put(Long.class, new CustomNumberEditor(Long.class, false));
		this.defaultEditors.put(BigInteger.class, new CustomNumberEditor(BigInteger.class, false));
		this.defaultEditors.put(Float.class, new CustomNumberEditor(Float.class, false));
		this.defaultEditors.put(Double.class, new CustomNumberEditor(Double.class, false));
		this.defaultEditors.put(BigDecimal.class, new CustomNumberEditor(BigDecimal.class, false));

		// Default instances of collection editors.
		// Can be overridden by registering custom instances of those as custom editors.
		this.defaultEditors.put(Collection.class, new CustomCollectionEditor(Collection.class));
		this.defaultEditors.put(Set.class, new CustomCollectionEditor(Set.class));
		this.defaultEditors.put(SortedSet.class, new CustomCollectionEditor(SortedSet.class));
		this.defaultEditors.put(List.class, new CustomCollectionEditor(List.class));
	}

	/**
	 * Create new BeanWrapperImpl for the given object.
	 * @param object object wrapped by this BeanWrapper
	 */
	public BeanWrapperImpl(Object object) {
		this();
		setWrappedInstance(object);
	}

	/**
	 * Create new BeanWrapperImpl, wrapping a new instance of the specified class.
	 * @param clazz class to instantiate and wrap
	 */
	public BeanWrapperImpl(Class clazz) {
		this();
		setWrappedInstance(BeanUtils.instantiateClass(clazz));
	}

	/**
	 * @deprecated in favor of BeanWrapperImpl(object, nestedPath, rootObject)
	 * @see #BeanWrapperImpl(Object, String, Object)
	 */
	public BeanWrapperImpl(Object object, String nestedPath) {
		this();
		setWrappedInstance(object, nestedPath);
	}

	/**
	 * Create new BeanWrapperImpl for the given object,
	 * registering a nested path that the object is in.
	 * @param object object wrapped by this BeanWrapper.
	 * @param nestedPath the nested path of the object
	 * @param rootObject the root object at the top of the path
	 */
	public BeanWrapperImpl(Object object, String nestedPath, Object rootObject) {
		this();
		setWrappedInstance(object, nestedPath, rootObject);
	}

	/**
	 * Create new BeanWrapperImpl for the given object,
	 * registering a nested path that the object is in.
	 * @param object object wrapped by this BeanWrapper.
	 * @param nestedPath the nested path of the object
	 * @param superBw the containing BeanWrapper (must not be null)
	 */
	private BeanWrapperImpl(Object object, String nestedPath, BeanWrapperImpl superBw) {
		this.defaultEditors = superBw.defaultEditors;
		setWrappedInstance(object, nestedPath, superBw.getWrappedInstance());
	}


	//---------------------------------------------------------------------
	// Implementation of BeanWrapper
	//---------------------------------------------------------------------

	/**
	 * Switch the target object, replacing the cached introspection results only
	 * if the class of the new object is different to that of the replaced object.
	 * @param object new target
	 */
	public void setWrappedInstance(Object object) {
		setWrappedInstance(object, "", null);
	}

	/**
	 * @deprecated in favor of setWrappedInstance(object, nestedPath, rootObject)
	 * @see #setWrappedInstance(Object, String, Object)
	 */
	public void setWrappedInstance(Object object, String nestedPath) {
		setWrappedInstance(object, nestedPath, null);
	}

	/**
	 * Switch the target object, replacing the cached introspection results only
	 * if the class of the new object is different to that of the replaced object.
	 * @param object new target
	 * @param nestedPath the nested path of the object
	 * @param rootObject the root object at the top of the path
	 */
	public void setWrappedInstance(Object object, String nestedPath, Object rootObject) {
		if (object == null) {
			throw new IllegalArgumentException("Cannot set BeanWrapperImpl target to a null object");
		}
		this.object = object;
		this.nestedPath = (nestedPath != null ? nestedPath : "");
		this.rootObject = (!"".equals(this.nestedPath) ? rootObject : object);
		this.nestedBeanWrappers = null;
		setIntrospectionClass(object.getClass());
	}

	public Object getWrappedInstance() {
		return this.object;
	}

	public Class getWrappedClass() {
		return this.object.getClass();
	}

	/**
	 * Return the nested path of the object wrapped by this BeanWrapper.
	 */
	public String getNestedPath() {
		return this.nestedPath;
	}

	/**
	 * Return the root object at the top of the path of this BeanWrapper.
	 * @see #getNestedPath
	 */
	public Object getRootInstance() {
		return this.rootObject;
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -