📄 beanmorpher.java
字号:
/*
* Copyright 2006-2007 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 net.sf.ezmorph.bean;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.Map;
import net.sf.ezmorph.MorphException;
import net.sf.ezmorph.MorpherRegistry;
import net.sf.ezmorph.ObjectMorpher;
import net.sf.ezmorph.object.IdentityObjectMorpher;
import org.apache.commons.beanutils.DynaBean;
import org.apache.commons.beanutils.DynaProperty;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Converts a JavaBean into another JavaBean or DynaBean.<br>
* This Morpher will try to match every property from the target JavaBean's
* class to the properties of the source JavaBean. If any target property
* differs in type from the source property, it will try to morph it. If a
* Morpher is not found for that type, the conversion will be aborted with a
* MorphException; this may be changed by setting the Morpher to be lenient, in
* that way it will ignore the property (the resulting value will be null).
*
* @author Andres Almiray <aalmiray@users.sourceforge.net>
*/
public final class BeanMorpher implements ObjectMorpher
{
private static final Log log = LogFactory.getLog( BeanMorpher.class );
private final Class beanClass;
private boolean lenient;
private final MorpherRegistry morpherRegistry;
public BeanMorpher( Class beanClass, MorpherRegistry morpherRegistry )
{
this( beanClass, morpherRegistry, false );
}
public BeanMorpher( Class beanClass, MorpherRegistry morpherRegistry, boolean lenient )
{
validateClass( beanClass );
if( morpherRegistry == null ){
throw new MorphException( "morpherRegistry is null" );
}
this.beanClass = beanClass;
this.morpherRegistry = morpherRegistry;
this.lenient = lenient;
}
public Object morph( Object sourceBean )
{
if( sourceBean == null ){
return null;
}
if( !supports( sourceBean.getClass() ) ){
throw new MorphException( "unsupported class: " + sourceBean.getClass()
.getName() );
}
Object targetBean = null;
try{
targetBean = beanClass.newInstance();
PropertyDescriptor[] targetPds = PropertyUtils.getPropertyDescriptors( beanClass );
for( int i = 0; i < targetPds.length; i++ ){
PropertyDescriptor targetPd = targetPds[i];
String name = targetPd.getName();
if( targetPd.getWriteMethod() == null ){
log.info( "Property '" + beanClass.getName() + "." + name
+ "' has no write method. SKIPPED." );
continue;
}
Class sourceType = null;
if( sourceBean instanceof DynaBean ){
DynaBean dynaBean = (DynaBean) sourceBean;
DynaProperty dynaProperty = dynaBean.getDynaClass()
.getDynaProperty( name );
sourceType = dynaProperty.getType();
}else{
PropertyDescriptor sourcePd = PropertyUtils.getPropertyDescriptor( sourceBean, name );
if( sourcePd.getReadMethod() == null ){
log.warn( "Property '" + sourceBean.getClass()
.getName() + "." + name + "' has no read method. SKIPPED." );
continue;
}
sourceType = sourcePd.getPropertyType();
}
Class targetType = targetPd.getPropertyType();
Object value = PropertyUtils.getProperty( sourceBean, name );
setProperty( targetBean, name, sourceType, targetType, value );
}
}
catch( MorphException me ){
throw me;
}
catch( Exception e ){
throw new MorphException( e );
}
return targetBean;
}
public Class morphsTo()
{
return beanClass;
}
public boolean supports( Class clazz )
{
return !clazz.isArray();
}
private void setProperty( Object targetBean, String name, Class sourceType, Class targetType,
Object value ) throws IllegalAccessException, InvocationTargetException,
NoSuchMethodException
{
if( targetType.isAssignableFrom( sourceType ) ){
if( value == null && targetType.isPrimitive() ){
value = morpherRegistry.morph( targetType, value );
}
PropertyUtils.setProperty( targetBean, name, value );
}else{
if( targetType.equals( Object.class ) ){
// no conversion
PropertyUtils.setProperty( targetBean, name, value );
}else{
if( value == null ){
if( targetType.isPrimitive() ){
PropertyUtils.setProperty( targetBean, name, morpherRegistry.morph( targetType,
value ) );
}
}else{
if( IdentityObjectMorpher.getInstance() == morpherRegistry.getMorpherFor( targetType ) ){
if( !lenient ){
throw new MorphException( "Can't find a morpher for target class "
+ targetType.getName() + " (" + name + ")" );
}else{
log.info( "Can't find a morpher for target class " + targetType.getName()
+ " (" + name + ") SKIPPED" );
}
}else{
PropertyUtils.setProperty( targetBean, name, morpherRegistry.morph( targetType,
value ) );
}
}
}
}
}
private void validateClass( Class clazz )
{
if( clazz == null ){
throw new MorphException( "target class is null" );
}else if( clazz.isPrimitive() ){
throw new MorphException( "target class is a primitive" );
}else if( clazz.isArray() ){
throw new MorphException( "target class is an array" );
}else if( clazz.isInterface() ){
throw new MorphException( "target class is an interface" );
}else if( DynaBean.class.isAssignableFrom( clazz ) ){
throw new MorphException( "target class is a DynaBean" );
}else if( Number.class.isAssignableFrom( clazz ) || Boolean.class.isAssignableFrom( clazz )
|| Character.class.isAssignableFrom( clazz ) ){
throw new MorphException( "target class is a wrapper" );
}else if( String.class.isAssignableFrom( clazz ) ){
throw new MorphException( "target class is a String" );
}else if( Collection.class.isAssignableFrom( clazz ) ){
throw new MorphException( "target class is a Collection" );
}else if( Map.class.isAssignableFrom( clazz ) ){
throw new MorphException( "target class is a Map" );
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -