net.sf.ezmorph.bean.MorphDynaClass Maven / Gradle / Ivy
/*
* 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.io.Serializable;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import net.sf.ezmorph.MorphException;
import net.sf.ezmorph.MorphUtils;
import net.sf.ezmorph.MorpherRegistry;
import org.apache.commons.beanutils.DynaBean;
import org.apache.commons.beanutils.DynaClass;
import org.apache.commons.beanutils.DynaProperty;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
/**
* @author Andres Almiray
*/
public final class MorphDynaClass implements DynaClass, Serializable
{
private static final Comparator dynaPropertyComparator = new Comparator(){
public int compare( Object a, Object b )
{
if( a instanceof DynaProperty && b instanceof DynaProperty ){
DynaProperty p1 = (DynaProperty) a;
DynaProperty p2 = (DynaProperty) b;
return p1.getName()
.compareTo( p2.getName() );
}
return -1;
}
};
private static final long serialVersionUID = 689740135689363791L;
private Map attributes;
private Class beanClass;
private DynaProperty dynaProperties[];
private String name;
private Map properties = new HashMap();
private Class type;
public MorphDynaClass( Map attributes )
{
this( null, null, attributes );
}
public MorphDynaClass( String name, Class type, Map attributes )
{
if( name == null ){
name = "MorphDynaClass";
}
if( type == null ){
type = MorphDynaBean.class;
}
if( !MorphDynaBean.class.isAssignableFrom( type ) ){
throw new MorphException( "MorphDynaBean is not assignable from " + type.getName() );
}
if( attributes == null || attributes.isEmpty() ){
throw new MorphException( "Attributes map is null or empty." );
}
this.name = name;
this.type = type;
this.attributes = attributes;
process();
}
public boolean equals( Object obj )
{
if( this == obj ){
return true;
}
if( obj == null ){
return false;
}
if( !(obj instanceof MorphDynaClass) ){
return false;
}
MorphDynaClass other = (MorphDynaClass) obj;
EqualsBuilder builder = new EqualsBuilder().append( this.name, other.name )
.append( this.type, other.type );
if( dynaProperties.length != other.dynaProperties.length ){
return false;
}
for( int i = 0; i < dynaProperties.length; i++ ){
DynaProperty a = this.dynaProperties[i];
DynaProperty b = other.dynaProperties[i];
builder.append( a.getName(), b.getName() );
builder.append( a.getType(), b.getType() );
}
return builder.isEquals();
}
public DynaProperty[] getDynaProperties()
{
return dynaProperties;
}
public DynaProperty getDynaProperty( String propertyName )
{
if( propertyName == null ){
throw new MorphException( "Unnespecified bean property name" );
}
return (DynaProperty) properties.get( propertyName );
}
public String getName()
{
return this.name;
}
public int hashCode()
{
HashCodeBuilder builder = new HashCodeBuilder().append( name )
.append( type );
for( int i = 0; i < dynaProperties.length; i++ ){
builder.append( this.dynaProperties[i].getName() );
builder.append( this.dynaProperties[i].getType() );
}
return builder.toHashCode();
}
public DynaBean newInstance() throws IllegalAccessException, InstantiationException
{
return newInstance( null );
}
public DynaBean newInstance( MorpherRegistry morpherRegistry ) throws IllegalAccessException,
InstantiationException
{
if( morpherRegistry == null ){
morpherRegistry = new MorpherRegistry();
MorphUtils.registerStandardMorphers( morpherRegistry );
}
MorphDynaBean dynaBean = (MorphDynaBean) getBeanClass().newInstance();
dynaBean.setDynaBeanClass( this );
dynaBean.setMorpherRegistry( morpherRegistry );
Iterator keys = attributes.keySet()
.iterator();
while( keys.hasNext() ){
String key = (String) keys.next();
dynaBean.set( key, null );
}
return dynaBean;
}
public String toString()
{
return new ToStringBuilder( this ).append( "name", this.name )
.append( "type", this.type )
.append( "attributes", this.attributes )
.toString();
}
protected Class getBeanClass()
{
if( this.beanClass == null ){
process();
}
return this.beanClass;
}
private void process()
{
this.beanClass = this.type;
try{
Iterator entries = attributes.entrySet()
.iterator();
dynaProperties = new DynaProperty[attributes.size()];
int i = 0;
while( entries.hasNext() ){
Map.Entry entry = (Map.Entry) entries.next();
String pname = (String) entry.getKey();
Object pclass = entry.getValue();
DynaProperty dynaProperty = null;
if( pclass instanceof String ){
Class klass = (Class) Class.forName( (String) pclass );
if( klass.isArray() && klass.getComponentType()
.isArray() ){
throw new MorphException( "Multidimensional arrays are not supported" );
}
dynaProperty = new DynaProperty( pname, klass );
}else if( pclass instanceof Class ){
Class klass = (Class) pclass;
if( klass.isArray() && klass.getComponentType()
.isArray() ){
throw new MorphException( "Multidimensional arrays are not supported" );
}
dynaProperty = new DynaProperty( pname, klass );
}else{
throw new MorphException( "Type must be String or Class" );
}
properties.put( dynaProperty.getName(), dynaProperty );
dynaProperties[i++] = dynaProperty;
}
}
catch( ClassNotFoundException cnfe ){
throw new MorphException( cnfe );
}
// keep properties sorted by name
Arrays.sort( dynaProperties, 0, dynaProperties.length, dynaPropertyComparator );
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy