|
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();
}
}
|