Java tutorial
/* * Copyright (C) 2008 feilong * * 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.feilong.core.bean; import static java.util.Collections.emptyMap; import java.lang.reflect.Field; import java.util.Collections; import java.util.List; import java.util.Map; import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.beanutils.BeanUtilsBean; import org.apache.commons.beanutils.ConvertUtils; import org.apache.commons.beanutils.ConvertUtilsBean; import org.apache.commons.beanutils.Converter; import org.apache.commons.beanutils.DynaBean; import org.apache.commons.beanutils.LazyDynaBean; import org.apache.commons.beanutils.PropertyUtils; import org.apache.commons.beanutils.converters.ArrayConverter; import org.apache.commons.beanutils.locale.converters.DateLocaleConverter; import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.reflect.FieldUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import static com.feilong.core.Validator.isNotNullOrEmpty; import static com.feilong.core.Validator.isNullOrEmpty; import static com.feilong.core.util.MapUtil.newHashMap; /** * {@link org.apache.commons.beanutils.BeanUtils}??. * * <p> * ? checkedException ?? {@link BeanUtilException} * </p> * * <h3>{@link PropertyUtils} {@link BeanUtils}:</h3> * * <blockquote> * * <pre class="code"> * BeanUtils.setProperty(pt1, "x", "9"); // 9String * PropertyUtils.setProperty(pt1, "x", 9); // int * // BeanUtilsPropertyUtils,?int,?? * </pre> * * <p> * {@link PropertyUtils} {@link BeanUtils}??,??.<br> * BeanUtils??"Bean",String,<br> * PropertyUtils??,Object. * </p> * </blockquote> * * <h3> {@link BeanUtils#copyProperty(Object, String, Object) copyProperty} {@link BeanUtils#setProperty(Object, String, Object) * setProperty}:</h3> * * <blockquote> * * <pre class="code"> * ,: * copyProperty ??bean,?beansetter * copyProperty ??beanMap,?beanMapsetter * * ?bean?,{@link BeanUtils#copyProperty(Object, String, Object)}?; * {@link BeanUtils#setProperty(Object, String, Object)} {@link BeanUtils#populate(Object,Map)},?populate(),?override {@link BeanUtils#setProperty(Object, String, Object)}. * ,?,{@link BeanUtils#setProperty(Object, String, Object)}???. * </pre> * * </blockquote> * * <h3><a name="propertyName">propertyName</a></h3> * * <blockquote> * getPropertysetProperty,?2?,JavaBean,????. * * <pre class="code"> * Company c = new Company(); * c.setName("Simple"); * </pre> * * <ul> * <li> * <p> * <b>Simple(?,String Int)</b> * </p> * * <pre class="code"> * Simple,????? * LOGGER.debug(BeanUtils.getProperty(c, "name")); * </pre> * * </li> * * <li> * <p> * <b>Map</b> * </p> * Map,?"??(key)"? * * <pre class="code"> * LOGGER.debug(BeanUtils.getProperty(c, "address (A2)")); * Map am = new HashMap(); * am.put("1", "234-222-1222211"); * am.put("2", "021-086-1232323"); * BeanUtils.setProperty(c, "telephone", am); * LOGGER.debug(BeanUtils.getProperty(c, "telephone (2)")); * </pre> * * </li> * <li> * <p> * <b>(Indexed), arrayList</b> * </p> * * Indexed,"??[]",?ArrayList???. * * <pre class="code"> * LOGGER.debug(BeanUtils.getProperty(c, "otherInfo[2]")); * BeanUtils.setProperty(c, "product[1]", "NOTES SERVER"); * LOGGER.debug(BeanUtils.getProperty(c, "product[1]")); * </pre> * * </li> * * <li> * <p> * <b>?(nest)</b> * </p> * * <pre class="code"> * 3???? * LOGGER.debug(BeanUtils.getProperty(c, "employee[1].name")); * </pre> * * </li> * </ul> * </blockquote> * * @author <a href="http://feitianbenyue.iteye.com/">feilong</a> * @see com.feilong.core.bean.PropertyUtil * * @see java.beans.BeanInfo * @see java.beans.PropertyDescriptor * @see java.beans.MethodDescriptor * * @see org.apache.commons.beanutils.BeanUtils * @see org.apache.commons.beanutils.Converter * @see org.apache.commons.beanutils.converters.DateConverter * @see org.apache.commons.beanutils.converters.DateTimeConverter * @see org.apache.commons.beanutils.converters.AbstractConverter * * @see org.apache.commons.beanutils.ConvertUtils#register(org.apache.commons.beanutils.Converter, Class) * * @see org.apache.commons.beanutils.ConvertUtilsBean#registerPrimitives(boolean) * @see org.apache.commons.beanutils.ConvertUtilsBean#registerStandard(boolean, boolean) * @see org.apache.commons.beanutils.ConvertUtilsBean#registerOther(boolean) * @see org.apache.commons.beanutils.ConvertUtilsBean#registerArrays(boolean, int) * * @see "org.springframework.beans.BeanUtils" * * @since 1.0.0 */ public final class BeanUtil { /** The Constant LOGGER. */ private static final Logger LOGGER = LoggerFactory.getLogger(BeanUtil.class); /** Don't let anyone instantiate this class. */ private BeanUtil() { //AssertionError?. ?????. ???. //see Effective Java 2nd throw new AssertionError("No " + getClass().getName() + " instances for you!"); } static { //?. initConverters(); } /** * ?. * * <h3>?:</h3> * * <blockquote> * <p> * ??, {@link org.apache.commons.beanutils.ConvertUtilsBean#register(boolean, boolean, int) ConvertUtilsBean.register(boolean, * boolean, int)}<br> * ??,beanUtils,????<br> * ?,,? {@link org.apache.commons.beanutils.Converter},<br> * ??: * </p> * * <ul> * <li>{@link ConvertUtilsBean#registerPrimitives(boolean) registerPrimitives(boolean throwException)}</li> * <li>{@link ConvertUtilsBean#registerStandard(boolean,boolean) registerStandard(boolean throwException, boolean defaultNull);}</li> * <li>{@link ConvertUtilsBean#registerOther(boolean) registerOther(boolean throwException);}</li> * <li>{@link ConvertUtilsBean#registerArrays(boolean,int) registerArrays(boolean throwException, int defaultArraySize);}</li> * </ul> * * register,{@link org.apache.commons.beanutils.ConvertUtilsBean#deregister(Class) ConvertUtilsBean.deregister(Class)} * </blockquote> * * <h3>:</h3> * * <blockquote> * * <pre class="code"> * * MyObject myObject = new MyObject(); * myObject.setId(3l); * myObject.setName("My Name"); * * ConvertUtilsBean cub = new ConvertUtilsBean(); * cub.deregister(Long.class); * cub.register(new MyLongConverter(), Long.class); * * LOGGER.debug(cub.lookup(Long.class)); * * BeanUtilsBean bub = new BeanUtilsBean(cub, new PropertyUtilsBean()); * * LOGGER.debug(bub.getProperty(myObject, "name")); * LOGGER.debug(bub.getProperty(myObject, "id")); * * </pre> * * </blockquote> * * @since 1.5.0 */ private static void initConverters() { //XXX initConverters? BeanUtilsBean beanUtilsBean = BeanUtilsBean.getInstance(); ConvertUtilsBean convertUtils = beanUtilsBean.getConvertUtils(); boolean throwException = false; boolean defaultNull = true; int defaultArraySize = 10; convertUtils.register(throwException, defaultNull, defaultArraySize); } /** * {@link ConvertUtils#register(Converter, Class)}?. * * <h3>:</h3> * * <blockquote> * <p> * ??,static???,?register converter,<br> * ?,ConvertUtilsConverter,?,<br> * : * </p> * * <pre class="code"> * ConvertUtils.register(new DateLocaleConverter(Locale.US, DatePattern.TO_STRING_STYLE), Date.class) * * User user1 = new User(); * user1.setDate(new Date()); * * User user2 = new User(); * BeanUtil.copyProperties(user2, user1, "date"); * </pre> * * <p> * {@link DateLocaleConverter} ?? static ? {@link org.apache.commons.beanutils.converters.DateConverter} ? * </p> * * <p> * ,<span style="color:red">,?commons-bean {@link ConvertUtils#register(Converter, Class)}</span> ,<br> * ?static??,? {@link Converter} ?? * </p> * </blockquote> * * @param converter * the converter * @param klass * the klass * @see org.apache.commons.beanutils.ConvertUtils#register(Converter, Class) * @since 1.5.0 */ public static void register(Converter converter, Class<?> klass) { ConvertUtils.register(converter, klass); } // [start] copyProperties /** * <code class="code">fromObj</code>,? <code>toObj</code>. * * <h3>?:</h3> * * <blockquote> * <ol> * <li>?copy <span style="color:red">?</span>,??2Bean???ref,??, .</li> * <li> {@link BeanUtils#copyProperties(Object, Object)},{@code Object--->String--->Object}?,<br> * ?copy?,<span style="color:red"></span>, * {@link PropertyUtil#copyProperties(Object, Object, String...)}</li> * </ol> * </blockquote> * * <h3>??:</h3> * <blockquote> * <p> * <code>includePropertyNames</code>?, {@link BeanUtils#copyProperties(Object, Object)}<br> * ?{@link #getProperty(Object, String)} ?{@link #setProperty(Object, String, Object)} <code>toObj</code> * </p> * </blockquote> * * <h3>?:</h3> * * <blockquote> * * <ol> * <li><code>includePropertyNames</code>,? <code>fromObj</code>??,</li> * <li><code>includePropertyNames</code>,? <code>fromObj</code>, <code>toObj</code>??,??,see * {@link BeanUtilsBean#copyProperty(Object, String, Object)} Line391</li> * </ol> * </blockquote> * * * <h3>:</h3> * * <blockquote> * * <pre class="code"> * pojo: useruserForm ?"enterpriseName","linkMan","phone" * * : * ..... * user.setEnterpriseName(userForm.getEnterpriseName()); * user.setLinkMan(userForm.getLinkMan()); * user.setPhone(userForm.getPhone()); * ...... * * ,? * BeanUtil.copyProperties(user,userForm,"enterpriseName","linkMan","phone"); * </pre> * * </blockquote> * * * <h3> {@link Converter}:</h3> * * <blockquote> * <p> * {@link java.util.Date} ?copy,?? {@link #register(Converter, Class)}:<br> * * <code>BeanUtil.register(new DateLocaleConverter(Locale.US, DatePattern.TO_STRING_STYLE),Date.class);</code> * * <br> * ,?? {@link #register(Converter, Class)} * </p> * </blockquote> * * * <h3>{@link BeanUtils#copyProperties(Object, Object)} {@link PropertyUtils#copyProperties(Object, Object)}</h3> * * <blockquote> * <ul> * <li>{@link BeanUtils#copyProperties(Object, Object)} ???,??JavaBean?????,???, * {@link PropertyUtils#copyProperties(Object, Object)}??,.</li> * <li>commons-beanutils v1.9.0? BeanUtils?? null,PropertyUtils?? null.<br> * (<b>:</b>commons-beanutils v1.9.0+?,BeanUtilsBean.copyProperties() no longer throws a ConversionException for null properties * of certain data types),?,??commons-beanutils * <a href="http://commons.apache.org/proper/commons-beanutils/javadocs/v1.9.2/RELEASE-NOTES.txt">RELEASE-NOTES.txt</a></li> * </ul> * </blockquote> * * @param toObj * * @param fromObj * * @param includePropertyNames * ???,(can be nested/indexed/mapped/combo)<br> * nullempty , {@link BeanUtils#copyProperties(Object, Object)} * @throws NullPointerException * <code>toObj</code> null, <code>fromObj</code> null * @throws BeanUtilException * api,?{@link BeanUtilException} * @see #setProperty(Object, String, Object) * @see org.apache.commons.beanutils.BeanUtilsBean#copyProperties(Object, Object) * @see <a href="http://www.cnblogs.com/kaka/archive/2013/03/06/2945514.html">Bean??(Apache BeanUtils?PropertyUtils,Spring * BeanUtils,Cglib BeanCopier)</a> */ //XXX add excludePropertyNames support public static void copyProperties(Object toObj, Object fromObj, String... includePropertyNames) { Validate.notNull(toObj, "toObj [destination bean] not specified!"); Validate.notNull(fromObj, "fromObj [origin bean] not specified!"); if (isNullOrEmpty(includePropertyNames)) { try { BeanUtils.copyProperties(toObj, fromObj); return; } catch (Exception e) { LOGGER.error(e.getClass().getName(), e); throw new BeanUtilException(e); } } for (String propertyName : includePropertyNames) { String value = getProperty(fromObj, propertyName); setProperty(toObj, propertyName, value); } } // [end] // [start] setProperty /** * {@link BeanUtils#setProperty(Object, String, Object)} ?(<b>?</b>). * * <p> * BeanUtils??,???(?) * </p> * * @param bean * Bean on which setting is to be performed * @param propertyName * Property name (can be nested/indexed/mapped/combo),??<a href="#propertyName">propertyName</a> * @param value * Value to be set * @throws BeanUtilException * ,?{@link BeanUtilException} * @see org.apache.commons.beanutils.BeanUtils#setProperty(Object, String, Object) * @see org.apache.commons.beanutils.BeanUtilsBean#setProperty(Object, String, Object) * @see org.apache.commons.beanutils.PropertyUtils#setProperty(Object, String, Object) * @see com.feilong.core.bean.PropertyUtil#setProperty(Object, String, Object) */ public static void setProperty(Object bean, String propertyName, Object value) { try { BeanUtils.setProperty(bean, propertyName, value); } catch (Exception e) { LOGGER.error(e.getClass().getName(), e); throw new BeanUtilException(e); } } // [end] // [start] getProperty /** * {@link BeanUtils#getProperty(Object, String)} ?,?care,? {@link String}. * * @param bean * bean * @param propertyName * ?? (can be nested/indexed/mapped/combo),?? <a href="#propertyName">propertyName</a> * @return {@link BeanUtils#getProperty(Object, String)} ? * @throws NullPointerException * <code>bean</code> null, <code>propertyName</code> null * @throws IllegalArgumentException * <code>propertyName</code> blank * @throws BeanUtilException * {@link BeanUtils#getProperty(Object, String)},?{@link BeanUtilException} * @see org.apache.commons.beanutils.BeanUtils#getProperty(Object, String) * @see org.apache.commons.beanutils.PropertyUtils#getProperty(Object, String) * @see com.feilong.core.bean.PropertyUtil#getProperty(Object, String) */ public static String getProperty(Object bean, String propertyName) { Validate.notNull(bean, "bean can't be null!"); Validate.notBlank(propertyName, "propertyName can't be blank!"); try { return BeanUtils.getProperty(bean, propertyName); } catch (Exception e) { LOGGER.error(e.getClass().getName(), e); throw new BeanUtilException(e); } } // [end] // [start] cloneBean /** * {@link BeanUtils#cloneBean(Object)}. * * <p> * bean,???bean,?bean {@link Cloneable}? . * </p> * * <h3>?:</h3> * <blockquote> * * <ol> * <li>clone</li> * <li>?? <b>getPropertyUtils().copyProperties(newBean, bean)</b>;?<b>?,clone</b><br> * ???,???(?),?clone,,? * </li> * <li> {@link java.lang.Class#newInstance() Class.newInstance()}?,?clone<b>?</b>,? * {@link java.lang.InstantiationException InstantiationException}</li> * <li>?clone list,empty list,?? * <a href="https://issues.apache.org/jira/browse/BEANUTILS-471">BeanUtils.cloneBean with List is broken</a></li> * </ol> * </blockquote> * * <h3>clone:</h3> * * <blockquote> * <p> * ?clone,? {@link org.apache.commons.lang3.SerializationUtils#clone(java.io.Serializable) SerializationUtils.clone},?? * </p> * </blockquote> * * @param <T> * the generic type * @param bean * Bean to be cloned * @return the cloned bean (? ,clone) * @throws NullPointerException * <code>bean</code> null * @throws BeanUtilException * api,?{@link BeanUtilException} * @see org.apache.commons.beanutils.BeanUtils#cloneBean(Object) * @see org.apache.commons.beanutils.PropertyUtilsBean#copyProperties(Object, Object) * @see org.apache.commons.lang3.SerializationUtils#clone(java.io.Serializable) * @see org.apache.commons.lang3.ObjectUtils#clone(Object) * @see org.apache.commons.lang3.ObjectUtils#cloneIfPossible(Object) */ @SuppressWarnings("unchecked") public static <T> T cloneBean(T bean) { Validate.notNull(bean, "bean can't be null!"); try { return (T) BeanUtils.cloneBean(bean); } catch (Exception e) { LOGGER.error(e.getClass().getName(), e); throw new BeanUtilException(e); } } // [end] // [start] populate() properties/map?bean /** * properties/map? <code>populate</code> <b>()</b>bean. * * <p> * Map{@code <Key,value>}(StringString[])?bean,Keybean??. * </p> * * <h3>:</h3> * <blockquote> * * <pre class="code"> * User user = new User(); * user.setId(5L); * * Map{@code <String, Object>} properties = new HashMap{@code <String, Object>}(); * properties.put("id", 8L); * * BeanUtil.populate(user, properties); * LOGGER.info(JsonUtil.format(user)); * </pre> * * <b>:</b> * * <pre class="code"> * { * "date": null, * "id": 8, * "loves": [] * } * </pre> * * </blockquote> * * * <h3>?:</h3> * * <blockquote> * <p> * apachejavadoc,?http?,???.?? {@link #copyProperties(Object, Object, String...)} * </p> * </blockquote> * * * <h3>? {@link BeanUtilsBean#populate(Object, Map)}:</h3> * * <blockquote> * <p> * map, {@link BeanUtilsBean#setProperty(Object, String, Object)} , <code>bean</code> * </p> * </blockquote> * * @param <T> * the generic type * @param bean * JavaBean whose properties are being populated * @param properties * Map keyed by property name,with the corresponding (String or String[]) value(s) to be set * @return the t * @throws NullPointerException * <code>bean</code> null, <code>properties</code> null * @throws BeanUtilException * {@link BeanUtils#populate(Object, Map)},?{@link BeanUtilException} * @see org.apache.commons.beanutils.BeanUtils#populate(Object, Map) */ public static <T> T populate(T bean, Map<String, ?> properties) { Validate.notNull(bean, "bean can't be null/empty!"); Validate.notNull(properties, "properties can't be null/empty!"); try { BeanUtils.populate(bean, properties); return bean; } catch (Exception e) { throw new BeanUtilException(e); } } /** * alias value map <code>populate</code> <b>()</b> <code>aliasBean</code>. * * <h3>:</h3> * * <blockquote> * <p> * {@link BeanUtil} populate,{@link #populate(Object, Map)} ,? mapkey bean??<br> * , map key <b>"memcached.alivecheck"</b> (?properties ?), <b>"ALIVECHECK"</b> (?? xml??)<br> * bean??? java bean ??, <b>"aliveCheck"</b>, {@link #populate(Object, Map)} <br> * </p> * * <p> * ? {@link #populateAliasBean(Object, Map)}~~ * </p> * </blockquote> * * <h3>:</h3> * * <blockquote> * * <p> * <b>aliasAndValueMap</b>?: * </p> * * <pre class="code"> * { * "memcached.alivecheck": "false", * "memcached.expiretime": "180", * "memcached.initconnection": "10", * "memcached.maintSleep": "30", * "memcached.maxconnection": "250", * "memcached.minconnection": "5", * "memcached.nagle": "false", * "memcached.poolname": "sidsock2", * "memcached.serverlist": "172.20.31.23:11211,172.20.31.22:11211", * "memcached.serverweight": "2", * "memcached.socketto": "3000" * } * * </pre> * * <p> * <b>aliasBean</b>?: * </p> * * <pre class="code"> * * public class DangaMemCachedConfig{ * * <span style="color:green">//** The serverlist.</span> * @Alias(name = "memcached.serverlist",sampleValue = "172.20.31.23:11211,172.20.31.22:11211") * private String[] serverList; * * <span style="color:green">//@Alias(name = "memcached.poolname",sampleValue = "sidsock2")</span> * private String poolName; * * <span style="color:green">//** The expire time ??.</span> * @Alias(name = "memcached.expiretime",sampleValue = "180") * private Integer expireTime; * * <span style="color:green">//** ??. </span> * @Alias(name = "memcached.serverweight",sampleValue = "2,1") * private Integer[] weight; * * <span style="color:green">//** The init connection. </span> * @Alias(name = "memcached.initconnection",sampleValue = "10") * private Integer initConnection; * * <span style="color:green">//** The min connection.</span> * @Alias(name = "memcached.minconnection",sampleValue = "5") * private Integer minConnection; * * <span style="color:green">//** The max connection. </span> * @Alias(name = "memcached.maxconnection",sampleValue = "250") * private Integer maxConnection; * * <span style="color:green">//** ?,?30?,??.</span> * @Alias(name = "memcached.maintSleep",sampleValue = "30") * private Integer maintSleep; * * <span style="color:green">//** . </span> * @Alias(name = "memcached.nagle",sampleValue = "false") * private Boolean nagle; * * <span style="color:green">//** ?.</span> * @Alias(name = "memcached.socketto",sampleValue = "3000") * private Integer socketTo; * * <span style="color:green">//** The alive check.</span> * @Alias(name = "memcached.alivecheck",sampleValue = "false") * private Boolean aliveCheck; * * <span style="color:green">//setter getter </span> * } * * </pre> * * <b> * ??: * </b> * * <pre class="code"> * Map{@code <String, String>} readPropertiesToMap = ResourceBundleUtil.readPropertiesToMap("memcached"); * * DangaMemCachedConfig dangaMemCachedConfig = new DangaMemCachedConfig(); * BeanUtil.populateAliasBean(dangaMemCachedConfig, readPropertiesToMap); * LOGGER.debug(JsonUtil.format(dangaMemCachedConfig)); * </pre> * * <b>:</b> * * <pre class="code"> { "maxConnection": 250, "expireTime": 180, "serverList": [ "172.20.31.23", "11211", "172.20.31.22", "11211" ], "weight": [2], "nagle": false, "initConnection": 10, "aliveCheck": false, "poolName": "sidsock2", "maintSleep": 30, "socketTo": 3000, "minConnection": 5 } * </pre> * * <p> * ?,? serverList ["172.20.31.23:11211","172.20.31.22:11211"],??,<br> * , {@link ArrayConverter} ? allowedChars ? <code>'.', '-'</code>,?? * </p> * * <p> * ?: * </p> * * <pre class="code"> * Map{@code <String, String>} readPropertiesToMap = ResourceBundleUtil.readPropertiesToMap("memcached"); * * DangaMemCachedConfig dangaMemCachedConfig = new DangaMemCachedConfig(); * * <span style="color:blue">ArrayConverter arrayConverter = new ArrayConverter(String[].class, new StringConverter(), 2);</span> * <span style="color:blue">char[] allowedChars = { ':' };</span> * <span style="color:blue">arrayConverter.setAllowedChars(allowedChars);</span> * <span style="color:blue">BeanUtil.register(arrayConverter, String[].class);</span> * * BeanUtil.populateAliasBean(dangaMemCachedConfig, readPropertiesToMap); * LOGGER.debug(JsonUtil.format(dangaMemCachedConfig)); * </pre> * * <b>:</b> * * <pre class="code"> { "maxConnection": 250, "expireTime": 180, "serverList": [ "172.20.31.23:11211", "172.20.31.22:11211" ], "weight": [2], "nagle": false, "initConnection": 10, "aliveCheck": false, "poolName": "sidsock2", "maintSleep": 30, "socketTo": 3000, "minConnection": 5 } * </pre> * * </blockquote> * * @param <T> * the generic type * @param aliasBean * the bean * @param aliasAndValueMap * the key and value map * @return <code>aliasAndValueMap</code> nullempty, <code>bean</code><br> * <code>alias name</code> ?<code>aliasAndValueMap</code>,emty,? <code>aliasBean</code> * @throws NullPointerException * <code>bean</code> null * @since 1.8.1 */ public static <T> T populateAliasBean(T aliasBean, Map<String, ?> aliasAndValueMap) { Validate.notNull(aliasBean, "aliasBean can't be null!"); if (isNullOrEmpty(aliasAndValueMap)) { return aliasBean; } Map<String, String> propertyNameAndAliasMap = buildPropertyNameAndAliasMap(aliasBean.getClass()); for (Map.Entry<String, String> entry : propertyNameAndAliasMap.entrySet()) { String alias = entry.getValue(); Object value = aliasAndValueMap.get(alias); if (isNotNullOrEmpty(value)) { setProperty(aliasBean, entry.getKey(), value); } } return aliasBean; } /** * ??? klass {@link Alias} , ?? {@link Alias#name()} ?map . * * @param klass * the klass * @return <code>klass</code> {@link Alias} , {@link Collections#emptyMap()} * @throws NullPointerException * <code>klass</code> null * @since 1.8.1 */ private static Map<String, String> buildPropertyNameAndAliasMap(Class<?> klass) { Validate.notNull(klass, "klass can't be null!"); List<Field> aliasFieldsList = FieldUtils.getFieldsListWithAnnotation(klass, Alias.class); if (isNullOrEmpty(aliasFieldsList)) { return emptyMap(); } //??key Map<String, String> propertyNameAndAliasMap = newHashMap(aliasFieldsList.size()); for (Field field : aliasFieldsList) { Alias alias = field.getAnnotation(Alias.class); propertyNameAndAliasMap.put(field.getName(), alias.name()); } return propertyNameAndAliasMap; } // [end] /** * New dyna bean. * * <p> * {@link LazyDynaBean}????DynaClass?LazyDynaBean??<br> * {@link LazyDynaBean}???mapkey-value pairLazyDynaBeanmapmetadatametadata<br> * * ?, {@link org.apache.commons.beanutils.LazyDynaClass} * </p> * * <h3>:</h3> * * <blockquote> * * <pre class="code"> * * DynaBean newDynaBean = BeanUtil.newDynaBean(toMap(// * Pair.of("address", (Object) new HashMap()), * Pair.of("firstName", (Object) "Fred"), * Pair.of("lastName", (Object) "Flintstone"))); * LOGGER.debug(JsonUtil.format(newDynaBean)); * * </pre> * * <b>:</b> * * <pre class="code"> * { "address": {}, "firstName": "Fred", "lastName": "Flintstone" } * </pre> * * </blockquote> * * @param valueMap * the value map * @return the dyna bean * @see org.apache.commons.beanutils.LazyDynaBean * @throws NullPointerException * <code>valueMap</code> null, mapkeynull * @since 1.8.1 */ public static DynaBean newDynaBean(Map<String, ?> valueMap) { Validate.notNull(valueMap, "valueMap can't be null!"); LazyDynaBean lazyDynaBean = new LazyDynaBean(); for (Map.Entry<String, ?> entry : valueMap.entrySet()) { Validate.notBlank(entry.getKey(), "entry.getKey() can't be blank!"); lazyDynaBean.set(entry.getKey(), entry.getValue()); } return lazyDynaBean; } }