All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.viiyue.plugins.mybatis.utils.BeanUtil Maven / Gradle / Ivy

Go to download

Mybatis generic mapper plugin for solving most basic operations, simplifying sql syntax and improving dynamic execution efficiency

There is a newer version: 1.3.7
Show newest version
/**
 * Copyright (C) 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.
 * 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 com.viiyue.plugins.mybatis.utils;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Java entity bean tool class
 *
 * @author tangxbai
 * @since 1.1.0
 */
public class BeanUtil {
	
	private BeanUtil() {}
	
	private static final Map, Set> methodMappgins = new ConcurrentHashMap, Set>();
	private static final ThreadLocal> propertyValueLocals = new ThreadLocal>();
	
	/**
	 * Gets a collection of all non-null attribute names for the bean. This
	 * method will store all non-null values in the current thread variable. All
	 * non-null values can be obtained by {@link #getPropertyValues()}.
	 * 
	 * @param instance object instance
	 * @return attribute name set 
	 */
	public static Set getPropertiesIfNotNull( Object instance ) {
		if ( instance == null ) {
			return Collections.emptySet();
		}
		Set properties = null;
		Map propertyValues = null;
		Class type = instance.getClass();
		Set methods = methodMappgins.get( type );
		if ( methods == null ) {
			synchronized ( methodMappgins ) {
				PropertyDescriptor [] descriptors = FieldUtil.getPropertyDescriptors( type );
				methods = new HashSet( descriptors.length );
				properties = new HashSet( descriptors.length );
				propertyValues = new HashMap( descriptors.length );
				for ( PropertyDescriptor pd : descriptors ) {
					if ( ObjectUtil.isDifferent( "class", pd.getName() ) ) { // class attribute is belongs to Object
						Method getter = pd.getReadMethod();
						methods.add( getter );
						Object returnValue = MethodUtil.invoke( instance, true, getter );
						if ( returnValue != null ) {
							propertyValues.put( pd.getName(), returnValue );
							properties.add( pd.getName() );
						}
					}
				}
				methodMappgins.put( type, methods );
				propertyValueLocals.set( propertyValues );
				return properties;
			}
		}
		properties = new HashSet( methods.size() );
		propertyValues = new HashMap( methods.size() );
		for ( Method method : methods ) {
			Object returnValue = MethodUtil.invoke( instance, true, method );
			if ( returnValue != null ) {
				String propertyName = MethodUtil.getPropertyNameByReadMethod( method );
				properties.add( propertyName );
				propertyValues.put( propertyName, returnValue );
			}
		}
		propertyValueLocals.set( propertyValues );
		return properties;
	}
	
	/**
	 * Copy a new entity object, and you can modify the copied property value
	 * 
	 * @param target target object instance
	 * @param properties modified property collection, similar to map key-value
	 * @return the copyed entity object
	 */
	public static  T copy( T target, Object ... properties ) {
		boolean hasModifyProperties = ObjectUtil.isNotEmpty( properties );
		Class targetType = ( Class ) target.getClass();
		Map modify = hasModifyProperties ? MapUtil.newMap( properties ) : null;
		T newCopyed = ClassUtil.newInstance( targetType );
		for ( PropertyDescriptor pd : FieldUtil.getPropertyDescriptors( targetType ) ) {
			if ( ObjectUtil.isDifferent( "class", pd.getName() ) ) {
				Method getter = pd.getReadMethod();
				Method setter = pd.getWriteMethod();
				Assert.isFalse( getter == null || setter == null, "Not a standard JavaBean, no corresponding Getter/Setter method found" );
				Object returnValue = hasModifyProperties ? modify.get( pd.getName() ) : MethodUtil.invoke( target, true, getter );
				if ( returnValue != null ) {
					MethodUtil.invoke( newCopyed, true, setter, returnValue );
				}
			}
		}
		return newCopyed;
	}
	
	/**
	 * Get all attribute value mappings that
	 * {@link #getPropertiesIfNotNull(Object)} judged to be non-null
	 * 
	 * @return all non-null attribute value mappings
	 */
	public static Map getPropertyValues() {
		Map map = propertyValueLocals.get();
		Assert.notNull( map, "Currently there is no local thread variable value, please call BeanUtil#getPropertiesIfNotNull(Object) first." );
		propertyValueLocals.remove();
		return map;
	}

}