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

net.sf.ezmorph.bean.BeanMorpher Maven / Gradle / Ivy

There is a newer version: 1.0.6
Show newest version
/*
 * 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.
* 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 */ 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" ); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy