From: <one...@us...> - 2002-11-09 01:38:10
|
Update of /cvsroot/hibernate/Hibernate/cirrus/hibernate/type In directory usw-pr-cvs1:/tmp/cvs-serv6168/hibernate/type Modified Files: ComponentType.java Log Message: committed Jon Lipsky's patch to allow components with private constructors Index: ComponentType.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate/cirrus/hibernate/type/ComponentType.java,v retrieving revision 1.44 retrieving revision 1.45 diff -C2 -d -r1.44 -r1.45 *** ComponentType.java 27 Oct 2002 18:30:56 -0000 1.44 --- ComponentType.java 9 Nov 2002 01:38:06 -0000 1.45 *************** *** 1,275 **** ! //$Id$ ! package cirrus.hibernate.type; ! ! import java.io.Serializable; ! import java.lang.reflect.Method; ! import java.sql.PreparedStatement; ! import java.sql.ResultSet; ! import java.sql.SQLException; ! ! import cirrus.hibernate.HibernateException; ! import cirrus.hibernate.InstantiationException; ! import cirrus.hibernate.MappingException; ! import cirrus.hibernate.engine.Cascades; ! import cirrus.hibernate.engine.Mapping; ! import cirrus.hibernate.engine.SessionFactoryImplementor; ! import cirrus.hibernate.engine.SessionImplementor; ! import cirrus.hibernate.helpers.ArrayHelper; ! import cirrus.hibernate.helpers.ReflectHelper; ! ! public class ComponentType extends AbstractType implements AbstractComponentType { ! ! private final Class componentClass; ! private final Type[] types; ! private final Method[] getters; ! private final Method[] setters; ! private final String[] propertyNames; ! private final Cascades.CascadeStyle[] cascade; ! private final int propertySpan; ! private final int[] joinedFetch; ! private final String parentProperty; ! private final Method parentSetter; ! ! public int[] sqlTypes(Mapping pi) throws MappingException { ! //Not called at runtime so doesn't matter if its slow :) ! int[] sqlTypes = new int[ getColumnSpan(pi) ]; ! int n=0; ! for ( int i=0; i<propertySpan; i++ ) { ! int[] subtypes = types[i].sqlTypes(pi); ! for ( int j=0; j<subtypes.length; j++ ) { ! sqlTypes[n++] = subtypes[j]; ! } ! } ! return sqlTypes; ! } ! ! public int getColumnSpan(Mapping pi) throws MappingException { ! int span = 0; ! for ( int i=0; i<types.length; i++ ) { ! span += types[i].getColumnSpan(pi); ! } ! return span; ! } ! ! public ComponentType( ! Class componentClass, ! Type[] types, ! String[] properties, ! int[] joinedFetch, ! Cascades.CascadeStyle[] ! cascade, ! String parentProperty, ! boolean embedded ! ) throws MappingException { ! ! this.componentClass = componentClass; ! this.types = types; ! propertySpan = properties.length; ! getters = new Method[propertySpan]; ! setters = new Method[propertySpan]; ! for ( int i=0; i<properties.length; i++ ) { ! getters[i] = ReflectHelper.getGetterMethod( componentClass, properties[i] ); ! setters[i] = ReflectHelper.getSetterMethod( componentClass, properties[i] ); ! } ! this.parentSetter = (parentProperty==null) ? null : ReflectHelper.getSetterMethod(componentClass, parentProperty); ! this.parentProperty = parentProperty; ! this.propertyNames = properties; ! this.cascade = cascade; ! this.joinedFetch = joinedFetch; ! } ! ! public boolean isPersistentCollectionType() { ! return false; ! } ! public final boolean isComponentType() { ! return true; ! } ! public final boolean isEntityType() { ! return false; ! } ! ! public Class returnedClass() { ! return componentClass; ! } ! ! public boolean equals(Object x, Object y) throws HibernateException { ! if (x==y) return true; ! if (x==null || y==null) return false; ! for ( int i=0; i<getters.length; i++ ) { ! try { ! if ( !types[i].equals( getters[i].invoke(x, null), getters[i].invoke(y, null) ) ) return false; ! } ! catch (Exception e) { ! throw new HibernateException( "Could not compare component property values: " + componentClass.getName() ); ! } ! } ! return true; ! } ! ! public boolean isDirty(Object x, Object y, Object owner, SessionFactoryImplementor factory) throws HibernateException { ! if (x==y) return false; ! if (x==null || y==null) return true; ! for ( int i=0; i<getters.length; i++ ) { ! try { ! if ( types[i].isDirty( getters[i].invoke(x, null), getters[i].invoke(y, null), owner, factory ) ) return true; ! } ! catch (Exception e) { ! throw new HibernateException( "Could not compare component property values: " + componentClass.getName() ); ! } ! } ! return false; ! } ! ! 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 = types[i].getColumnSpan( session.getFactory() ); ! String[] range = ArrayHelper.slice(names, begin, length); //cache this ! Object val = types[i].nullSafeGet(rs, range, session, owner); ! if (val!=null) notNull=true; ! values[i] = val; ! begin+=length; ! } ! ! if (notNull) { ! Object result = instantiate(owner); ! for ( int i=0; i<propertySpan; i++ ) { ! ReflectHelper.set( setters[i], result, values[i], componentClass, propertyNames[i] ); ! } ! return result; ! } ! else { ! return null; ! } ! } ! ! 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++ ) { ! types[i].nullSafeSet(st, subvalues[i], begin, session); ! begin += types[i].getColumnSpan( session.getFactory() ); ! } ! } ! ! private Object[] nullSafeGetValues(Object value) throws HibernateException { ! if ( value==null ) { ! return new Object[propertySpan]; ! } ! else { ! return getPropertyValues(value); ! } ! } ! ! public Object nullSafeGet(ResultSet rs, String name, SessionImplementor session, Object owner) ! throws HibernateException, SQLException { ! ! return nullSafeGet(rs, new String[] {name}, session, owner); ! } ! ! public Object getPropertyValue(Object component, int i) throws HibernateException { ! return ReflectHelper.get( getters[i], component, componentClass, propertyNames[i] ); ! } ! ! public Object[] getPropertyValues(Object component) throws HibernateException { ! Object[] values = new Object[propertySpan]; ! for ( int i=0; i<propertySpan; i++ ) { ! values[i] = getPropertyValue(component, i); ! } ! return values; ! } ! ! public void setPropertyValues(Object component, Object[] values) throws HibernateException { ! for ( int i=0; i<propertySpan; i++ ) { ! ReflectHelper.set( setters[i], component, values[i], componentClass, propertyNames[i] ); ! } ! } ! public Type[] getSubtypes() { ! return types; ! } ! public String getName() { return componentClass.getName(); } ! public String toXML(Object value, SessionFactoryImplementor factory) { ! return (value==null) ? null : value.toString(); ! } ! public String[] getPropertyNames() { ! return propertyNames; ! } ! ! 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] = types[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; ! } ! ! public Object instantiate(Object parent) throws HibernateException { ! try { ! Object inst = componentClass.newInstance(); ! if (parentSetter!=null) ReflectHelper.set(parentSetter, inst, parent, componentClass, parentProperty); ! return inst; ! } ! catch (Exception e) { ! throw new InstantiationException("Could not instantiate component ", componentClass, e); ! } ! } ! ! public Cascades.CascadeStyle cascade(int i) { ! return cascade[i]; ! } ! ! public boolean isMutable() { ! return true; ! } ! ! public Serializable disassemble(Object value, SessionImplementor session) ! throws HibernateException { ! ! if (value==null) { ! return null; ! } ! else { ! Object[] values = getPropertyValues(value); ! for ( int i=0; i<types.length; i++ ) { ! values[i] = types[i].disassemble(values[i], session); ! } ! return values; ! } ! } ! ! public Object assemble(Serializable object, SessionImplementor session, Object owner) throws HibernateException, SQLException { ! if ( object==null ) { ! return null; ! } ! else { ! Object[] values = (Object[]) object; ! Object[] assembled = new Object[values.length]; ! for ( int i=0; i<types.length; i++ ) { ! assembled[i] = types[i].assemble( (Serializable) values[i], session, owner ); ! } ! Object result = instantiate(owner); ! setPropertyValues(result, assembled); ! return result; ! } ! } ! ! public boolean hasNiceEquals() { ! return false; ! } ! ! public int enableJoinedFetch(int i) { ! return joinedFetch[i]; ! } ! ! } ! --- 1,277 ---- ! //$Id$ ! package cirrus.hibernate.type; ! ! import java.io.Serializable; ! import java.lang.reflect.Constructor; ! import java.lang.reflect.Method; ! import java.sql.PreparedStatement; ! import java.sql.ResultSet; ! import java.sql.SQLException; ! ! import cirrus.hibernate.HibernateException; ! import cirrus.hibernate.InstantiationException; ! import cirrus.hibernate.MappingException; ! import cirrus.hibernate.engine.Cascades; ! import cirrus.hibernate.engine.Mapping; ! import cirrus.hibernate.engine.SessionFactoryImplementor; ! import cirrus.hibernate.engine.SessionImplementor; ! import cirrus.hibernate.helpers.ArrayHelper; ! import cirrus.hibernate.helpers.ReflectHelper; ! ! public class ComponentType extends AbstractType implements AbstractComponentType { ! ! private final Class componentClass; ! private final Type[] types; ! private final Method[] getters; ! private final Method[] setters; ! private final String[] propertyNames; ! private final Cascades.CascadeStyle[] cascade; ! private final int propertySpan; ! private final int[] joinedFetch; ! private final String parentProperty; ! private final Method parentSetter; ! ! public int[] sqlTypes(Mapping pi) throws MappingException { ! //Not called at runtime so doesn't matter if its slow :) ! int[] sqlTypes = new int[ getColumnSpan(pi) ]; ! int n=0; ! for ( int i=0; i<propertySpan; i++ ) { ! int[] subtypes = types[i].sqlTypes(pi); ! for ( int j=0; j<subtypes.length; j++ ) { ! sqlTypes[n++] = subtypes[j]; ! } ! } ! return sqlTypes; ! } ! ! public int getColumnSpan(Mapping pi) throws MappingException { ! int span = 0; ! for ( int i=0; i<types.length; i++ ) { ! span += types[i].getColumnSpan(pi); ! } ! return span; ! } ! ! public ComponentType( ! Class componentClass, ! Type[] types, ! String[] properties, ! int[] joinedFetch, ! Cascades.CascadeStyle[] ! cascade, ! String parentProperty, ! boolean embedded ! ) throws MappingException { ! ! this.componentClass = componentClass; ! this.types = types; ! propertySpan = properties.length; ! getters = new Method[propertySpan]; ! setters = new Method[propertySpan]; ! for ( int i=0; i<properties.length; i++ ) { ! getters[i] = ReflectHelper.getGetterMethod( componentClass, properties[i] ); ! setters[i] = ReflectHelper.getSetterMethod( componentClass, properties[i] ); ! } ! this.parentSetter = (parentProperty==null) ? null : ReflectHelper.getSetterMethod(componentClass, parentProperty); ! this.parentProperty = parentProperty; ! this.propertyNames = properties; ! this.cascade = cascade; ! this.joinedFetch = joinedFetch; ! } ! ! public boolean isPersistentCollectionType() { ! return false; ! } ! public final boolean isComponentType() { ! return true; ! } ! public final boolean isEntityType() { ! return false; ! } ! ! public Class returnedClass() { ! return componentClass; ! } ! ! public boolean equals(Object x, Object y) throws HibernateException { ! if (x==y) return true; ! if (x==null || y==null) return false; ! for ( int i=0; i<getters.length; i++ ) { ! try { ! if ( !types[i].equals( getters[i].invoke(x, null), getters[i].invoke(y, null) ) ) return false; ! } ! catch (Exception e) { ! throw new HibernateException( "Could not compare component property values: " + componentClass.getName() ); ! } ! } ! return true; ! } ! ! public boolean isDirty(Object x, Object y, Object owner, SessionFactoryImplementor factory) throws HibernateException { ! if (x==y) return false; ! if (x==null || y==null) return true; ! for ( int i=0; i<getters.length; i++ ) { ! try { ! if ( types[i].isDirty( getters[i].invoke(x, null), getters[i].invoke(y, null), owner, factory ) ) return true; ! } ! catch (Exception e) { ! throw new HibernateException( "Could not compare component property values: " + componentClass.getName() ); ! } ! } ! return false; ! } ! ! 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 = types[i].getColumnSpan( session.getFactory() ); ! String[] range = ArrayHelper.slice(names, begin, length); //cache this ! Object val = types[i].nullSafeGet(rs, range, session, owner); ! if (val!=null) notNull=true; ! values[i] = val; ! begin+=length; ! } ! ! if (notNull) { ! Object result = instantiate(owner); ! for ( int i=0; i<propertySpan; i++ ) { ! ReflectHelper.set( setters[i], result, values[i], componentClass, propertyNames[i] ); ! } ! return result; ! } ! else { ! return null; ! } ! } ! ! 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++ ) { ! types[i].nullSafeSet(st, subvalues[i], begin, session); ! begin += types[i].getColumnSpan( session.getFactory() ); ! } ! } ! ! private Object[] nullSafeGetValues(Object value) throws HibernateException { ! if ( value==null ) { ! return new Object[propertySpan]; ! } ! else { ! return getPropertyValues(value); ! } ! } ! ! public Object nullSafeGet(ResultSet rs, String name, SessionImplementor session, Object owner) ! throws HibernateException, SQLException { ! ! return nullSafeGet(rs, new String[] {name}, session, owner); ! } ! ! public Object getPropertyValue(Object component, int i) throws HibernateException { ! return ReflectHelper.get( getters[i], component, componentClass, propertyNames[i] ); ! } ! ! public Object[] getPropertyValues(Object component) throws HibernateException { ! Object[] values = new Object[propertySpan]; ! for ( int i=0; i<propertySpan; i++ ) { ! values[i] = getPropertyValue(component, i); ! } ! return values; ! } ! ! public void setPropertyValues(Object component, Object[] values) throws HibernateException { ! for ( int i=0; i<propertySpan; i++ ) { ! ReflectHelper.set( setters[i], component, values[i], componentClass, propertyNames[i] ); ! } ! } ! public Type[] getSubtypes() { ! return types; ! } ! public String getName() { return componentClass.getName(); } ! public String toXML(Object value, SessionFactoryImplementor factory) { ! return (value==null) ? null : value.toString(); ! } ! public String[] getPropertyNames() { ! return propertyNames; ! } ! ! 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] = types[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; ! } ! ! public Object instantiate(Object parent) throws HibernateException { ! try { ! Constructor constructor = ReflectHelper.getDefaultConstructor(componentClass); ! Object inst = constructor.newInstance(null); ! if (parentSetter!=null) ReflectHelper.set(parentSetter, inst, parent, componentClass, parentProperty); ! return inst; ! } ! catch (Exception e) { ! throw new InstantiationException("Could not instantiate component ", componentClass, e); ! } ! } ! ! public Cascades.CascadeStyle cascade(int i) { ! return cascade[i]; ! } ! ! public boolean isMutable() { ! return true; ! } ! ! public Serializable disassemble(Object value, SessionImplementor session) ! throws HibernateException { ! ! if (value==null) { ! return null; ! } ! else { ! Object[] values = getPropertyValues(value); ! for ( int i=0; i<types.length; i++ ) { ! values[i] = types[i].disassemble(values[i], session); ! } ! return values; ! } ! } ! ! public Object assemble(Serializable object, SessionImplementor session, Object owner) throws HibernateException, SQLException { ! if ( object==null ) { ! return null; ! } ! else { ! Object[] values = (Object[]) object; ! Object[] assembled = new Object[values.length]; ! for ( int i=0; i<types.length; i++ ) { ! assembled[i] = types[i].assemble( (Serializable) values[i], session, owner ); ! } ! Object result = instantiate(owner); ! setPropertyValues(result, assembled); ! return result; ! } ! } ! ! public boolean hasNiceEquals() { ! return false; ! } ! ! public int enableJoinedFetch(int i) { ! return joinedFetch[i]; ! } ! ! } ! |