From: <one...@us...> - 2003-01-19 11:48:43
|
Update of /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/type In directory sc8-pr-cvs1:/tmp/cvs-serv29573/sf/hibernate/type Added Files: DynaBeanType.java Log Message: added DynaBean support --- NEW FILE: DynaBeanType.java --- //$Id: DynaBeanType.java,v 1.1 2003/01/19 11:48:39 oneovthafew Exp $ package net.sf.hibernate.type; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import org.apache.commons.beanutils.DynaClass; import org.apache.commons.beanutils.DynaBean; import net.sf.hibernate.HibernateException; import net.sf.hibernate.MappingException; import net.sf.hibernate.engine.Mapping; import net.sf.hibernate.engine.SessionFactoryImplementor; import net.sf.hibernate.engine.SessionImplementor; import net.sf.hibernate.engine.Cascades; import net.sf.hibernate.util.ArrayHelper; public class DynaBeanType extends AbstractType implements AbstractComponentType { private DynaClass clazz; private String[] propertyNames; private Type[] propertyTypes; private int propertySpan; private final Cascades.CascadeStyle[] cascade; private final int[] joinedFetch; public DynaBeanType( DynaClass clazz, String[] propertyNames, Type[] propertyTypes, int[] joinedFetch, Cascades.CascadeStyle[] cascade ) { this.clazz = clazz; this.propertyNames = propertyNames; this.propertyTypes = propertyTypes; this.joinedFetch = joinedFetch; this.cascade = cascade; propertySpan = propertyTypes.length; } /** * @see net.sf.hibernate.type.AbstractComponentType#cascade(int) */ public Cascades.CascadeStyle cascade(int i) { return cascade[i]; } /** * @see net.sf.hibernate.type.AbstractComponentType#enableJoinedFetch(int) */ public int enableJoinedFetch(int i) { return joinedFetch[i]; } /** * @see net.sf.hibernate.type.AbstractComponentType#getPropertyNames() */ public String[] getPropertyNames() { return propertyNames; } /** * @see net.sf.hibernate.type.AbstractComponentType#getPropertyValue(java.lang.Object, int) */ public Object getPropertyValue(Object component, int i) throws HibernateException { return ( (DynaBean) component).get( propertyNames[i] ); } /** * @see net.sf.hibernate.type.AbstractComponentType#getPropertyValues(java.lang.Object) */ public Object[] getPropertyValues(Object component) throws HibernateException { DynaBean bean = (DynaBean) component; Object[] result = new Object[propertySpan]; for (int i=0; i<propertySpan; i++) { result[i] = bean.get( propertyNames[i] ); } return result; } /** * @see net.sf.hibernate.type.AbstractComponentType#getSubtypes() */ public Type[] getSubtypes() { return propertyTypes; } /** * @see net.sf.hibernate.type.AbstractComponentType#instantiate(java.lang.Object) */ public Object instantiate(Object parent) throws HibernateException { try { return clazz.newInstance(); } catch (Exception e) { throw new net.sf.hibernate.InstantiationException("Could no instantiate DynaBean: " + clazz.getName(), DynaBean.class, e); } } /** * @see net.sf.hibernate.type.AbstractComponentType#setPropertyValues(java.lang.Object, java.lang.Object) */ public void setPropertyValues(Object component, Object[] values) throws HibernateException { DynaBean bean = (DynaBean) component; for (int i=0; i<propertySpan; i++) { bean.set( propertyNames[i], values[i] ); } } /** * @see net.sf.hibernate.type.Type#deepCopy(java.lang.Object) */ public Object deepCopy(Object component) throws HibernateException { if (component==null) return null; Object[] values = getPropertyValues(component); for ( int i=0; i<propertySpan; i++ ) { values[i] = propertyTypes[i].deepCopy( values[i] ); } Object result = instantiate(null); //TODO: note that this doesn't copy reference to parent. Is that okay?? setPropertyValues(result, values); return result; } /** * @see net.sf.hibernate.type.Type#equals(java.lang.Object, java.lang.Object) */ public boolean equals(Object x, Object y) throws HibernateException { if (x==y) return true; if (x==null || y==null) return false; DynaBean xbean = (DynaBean) x; DynaBean ybean = (DynaBean) y; for ( int i=0; i<propertySpan; i++ ) { if ( !propertyTypes[i].equals( xbean.get( propertyNames[i] ), ybean.get( propertyNames[i] ) ) ) return false; } return true; } /** * @see net.sf.hibernate.type.Type#getColumnSpan(net.sf.hibernate.engine.Mapping) */ public int getColumnSpan(Mapping mapping) throws MappingException { int span = 0; for ( int i=0; i<propertySpan; i++ ) { span += propertyTypes[i].getColumnSpan(mapping); } return span; } /** * @see net.sf.hibernate.type.Type#getName() */ public String getName() { return clazz.getName(); } /** * @see net.sf.hibernate.type.Type#hasNiceEquals() */ public boolean hasNiceEquals() { return false; } /** * @see net.sf.hibernate.type.Type#isMutable() */ public boolean isMutable() { return true; } private Object[] nullSafeGetValues(Object value) throws HibernateException { if ( value==null ) { return new Object[propertySpan]; } else { return getPropertyValues(value); } } /** * @see net.sf.hibernate.type.Type#nullSafeGet(java.sql.ResultSet, java.lang.String, net.sf.hibernate.engine.SessionImplementor, java.lang.Object) */ public Object nullSafeGet( ResultSet rs, String name, SessionImplementor session, Object owner) throws HibernateException, SQLException { return nullSafeGet(rs, new String[] {name}, session, owner); } /** * @see net.sf.hibernate.type.Type#nullSafeGet(java.sql.ResultSet, java.lang.String, net.sf.hibernate.engine.SessionImplementor, java.lang.Object) */ public Object nullSafeGet( ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException, SQLException { int begin=0; boolean notNull=false; Object[] values = new Object[propertySpan]; for ( int i=0; i<propertySpan; i++ ) { int length = propertyTypes[i].getColumnSpan( session.getFactory() ); String[] range = ArrayHelper.slice(names, begin, length); //cache this Object val = propertyTypes[i].nullSafeGet(rs, range, session, owner); if (val!=null) notNull=true; values[i] = val; begin+=length; } if (notNull) { DynaBean result = (DynaBean) instantiate(owner); for ( int i=0; i<propertySpan; i++ ) { result.set( propertyNames[i], values[i] ); } return result; } else { return null; } } /** * @see net.sf.hibernate.type.Type#nullSafeSet(java.sql.PreparedStatement, java.lang.Object, int, net.sf.hibernate.engine.SessionImplementor) */ public void nullSafeSet( PreparedStatement st, Object value, int begin, SessionImplementor session) throws HibernateException, SQLException { Object[] subvalues = nullSafeGetValues(value); for ( int i=0; i<propertySpan; i++ ) { propertyTypes[i].nullSafeSet(st, subvalues[i], begin, session); begin += propertyTypes[i].getColumnSpan( session.getFactory() ); } } /** * @see net.sf.hibernate.type.Type#returnedClass() */ public Class getReturnedClass() { return DynaBean.class; } /** * @see net.sf.hibernate.type.Type#sqlTypes(net.sf.hibernate.engine.Mapping) */ public int[] sqlTypes(Mapping mapping) throws MappingException { //Not called at runtime so doesn't matter if its slow :) int[] sqlTypes = new int[ getColumnSpan(mapping) ]; int n=0; for ( int i=0; i<propertySpan; i++ ) { int[] subtypes = propertyTypes[i].sqlTypes(mapping); for ( int j=0; j<subtypes.length; j++ ) { sqlTypes[n++] = subtypes[j]; } } return sqlTypes; } /** * @see net.sf.hibernate.type.Type#toXML(java.lang.Object, net.sf.hibernate.engine.SessionFactoryImplementor) */ public String toXML(Object value, SessionFactoryImplementor factory) throws HibernateException { return (value==null) ? null : value.toString(); } } |