Save This Page
Home » hibernate-distribution-3.3.1.GA-dist » org.hibernate » type » [javadoc | source]
    1   /*
    2    * Hibernate, Relational Persistence for Idiomatic Java
    3    *
    4    * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
    5    * indicated by the @author tags or express copyright attribution
    6    * statements applied by the authors.  All third-party contributions are
    7    * distributed under license by Red Hat Middleware LLC.
    8    *
    9    * This copyrighted material is made available to anyone wishing to use, modify,
   10    * copy, or redistribute it subject to the terms and conditions of the GNU
   11    * Lesser General Public License, as published by the Free Software Foundation.
   12    *
   13    * This program is distributed in the hope that it will be useful,
   14    * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   15    * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
   16    * for more details.
   17    *
   18    * You should have received a copy of the GNU Lesser General Public License
   19    * along with this distribution; if not, write to:
   20    * Free Software Foundation, Inc.
   21    * 51 Franklin Street, Fifth Floor
   22    * Boston, MA  02110-1301  USA
   23    *
   24    */
   25   package org.hibernate.type;
   26   
   27   import java.io.Serializable;
   28   import java.math.BigDecimal;
   29   import java.math.BigInteger;
   30   import java.sql.Blob;
   31   import java.sql.Clob;
   32   import java.sql.Time;
   33   import java.sql.Timestamp;
   34   import java.util.Calendar;
   35   import java.util.Collections;
   36   import java.util.Comparator;
   37   import java.util.GregorianCalendar;
   38   import java.util.HashMap;
   39   import java.util.Locale;
   40   import java.util.Map;
   41   import java.util.Properties;
   42   import java.util.TimeZone;
   43   
   44   import org.hibernate.Hibernate;
   45   import org.hibernate.MappingException;
   46   import org.hibernate.classic.Lifecycle;
   47   import org.hibernate.engine.SessionImplementor;
   48   import org.hibernate.intercept.LazyPropertyInitializer;
   49   import org.hibernate.property.BackrefPropertyAccessor;
   50   import org.hibernate.tuple.StandardProperty;
   51   import org.hibernate.usertype.CompositeUserType;
   52   import org.hibernate.usertype.UserType;
   53   import org.hibernate.usertype.ParameterizedType;
   54   import org.hibernate.util.ReflectHelper;
   55   
   56   /**
   57    * Used internally to obtain instances of <tt>Type</tt>. Applications should use static methods
   58    * and constants on <tt>org.hibernate.Hibernate</tt>.
   59    *
   60    * @see org.hibernate.Hibernate
   61    * @author Gavin King
   62    */
   63   public final class TypeFactory {
   64   
   65   	private static final Map BASIC_TYPES;
   66   
   67   	static {
   68   		HashMap basics = new HashMap();
   69   		basics.put( boolean.class.getName(), Hibernate.BOOLEAN );
   70   		basics.put( long.class.getName(), Hibernate.LONG );
   71   		basics.put( short.class.getName(), Hibernate.SHORT );
   72   		basics.put( int.class.getName(), Hibernate.INTEGER );
   73   		basics.put( byte.class.getName(), Hibernate.BYTE );
   74   		basics.put( float.class.getName(), Hibernate.FLOAT );
   75   		basics.put( double.class.getName(), Hibernate.DOUBLE );
   76   		basics.put( char.class.getName(), Hibernate.CHARACTER );
   77   		basics.put( Hibernate.CHARACTER.getName(), Hibernate.CHARACTER );
   78   		basics.put( Hibernate.INTEGER.getName(), Hibernate.INTEGER );
   79   		basics.put( Hibernate.STRING.getName(), Hibernate.STRING );
   80   		basics.put( Hibernate.DATE.getName(), Hibernate.DATE );
   81   		basics.put( Hibernate.TIME.getName(), Hibernate.TIME );
   82   		basics.put( Hibernate.TIMESTAMP.getName(), Hibernate.TIMESTAMP );
   83   		basics.put( "dbtimestamp", new DbTimestampType() );
   84   		basics.put( Hibernate.LOCALE.getName(), Hibernate.LOCALE );
   85   		basics.put( Hibernate.CALENDAR.getName(), Hibernate.CALENDAR );
   86   		basics.put( Hibernate.CALENDAR_DATE.getName(), Hibernate.CALENDAR_DATE );
   87   		basics.put( Hibernate.CURRENCY.getName(), Hibernate.CURRENCY );
   88   		basics.put( Hibernate.TIMEZONE.getName(), Hibernate.TIMEZONE );
   89   		basics.put( Hibernate.CLASS.getName(), Hibernate.CLASS );
   90   		basics.put( Hibernate.TRUE_FALSE.getName(), Hibernate.TRUE_FALSE );
   91   		basics.put( Hibernate.YES_NO.getName(), Hibernate.YES_NO );
   92   		basics.put( Hibernate.BINARY.getName(), Hibernate.BINARY );
   93   		basics.put( Hibernate.TEXT.getName(), Hibernate.TEXT );
   94   		basics.put( Hibernate.BLOB.getName(), Hibernate.BLOB );
   95   		basics.put( Hibernate.CLOB.getName(), Hibernate.CLOB );
   96   		basics.put( Hibernate.BIG_DECIMAL.getName(), Hibernate.BIG_DECIMAL );
   97   		basics.put( Hibernate.BIG_INTEGER.getName(), Hibernate.BIG_INTEGER );
   98   		basics.put( Hibernate.SERIALIZABLE.getName(), Hibernate.SERIALIZABLE );
   99   		basics.put( Hibernate.OBJECT.getName(), Hibernate.OBJECT );
  100   		basics.put( Boolean.class.getName(), Hibernate.BOOLEAN );
  101   		basics.put( Long.class.getName(), Hibernate.LONG );
  102   		basics.put( Short.class.getName(), Hibernate.SHORT );
  103   		basics.put( Integer.class.getName(), Hibernate.INTEGER );
  104   		basics.put( Byte.class.getName(), Hibernate.BYTE );
  105   		basics.put( Float.class.getName(), Hibernate.FLOAT );
  106   		basics.put( Double.class.getName(), Hibernate.DOUBLE );
  107   		basics.put( Character.class.getName(), Hibernate.CHARACTER );
  108   		basics.put( String.class.getName(), Hibernate.STRING );
  109   		basics.put( java.util.Date.class.getName(), Hibernate.TIMESTAMP );
  110   		basics.put( Time.class.getName(), Hibernate.TIME );
  111   		basics.put( Timestamp.class.getName(), Hibernate.TIMESTAMP );
  112   		basics.put( java.sql.Date.class.getName(), Hibernate.DATE );
  113   		basics.put( BigDecimal.class.getName(), Hibernate.BIG_DECIMAL );
  114   		basics.put( BigInteger.class.getName(), Hibernate.BIG_INTEGER );
  115   		basics.put( Locale.class.getName(), Hibernate.LOCALE );
  116   		basics.put( Calendar.class.getName(), Hibernate.CALENDAR );
  117   		basics.put( GregorianCalendar.class.getName(), Hibernate.CALENDAR );
  118   		if ( CurrencyType.CURRENCY_CLASS != null ) {
  119   			basics.put( CurrencyType.CURRENCY_CLASS.getName(), Hibernate.CURRENCY );
  120   		}
  121   		basics.put( TimeZone.class.getName(), Hibernate.TIMEZONE );
  122   		basics.put( Object.class.getName(), Hibernate.OBJECT );
  123   		basics.put( Class.class.getName(), Hibernate.CLASS );
  124   		basics.put( byte[].class.getName(), Hibernate.BINARY );
  125   		basics.put( "byte[]", Hibernate.BINARY );
  126   		basics.put( Byte[].class.getName(), Hibernate.WRAPPER_BINARY );
  127   		basics.put( "Byte[]", Hibernate.WRAPPER_BINARY );
  128   		basics.put( char[].class.getName(), Hibernate.CHAR_ARRAY );
  129   		basics.put( "char[]", Hibernate.CHAR_ARRAY );
  130   		basics.put( Character[].class.getName(), Hibernate.CHARACTER_ARRAY );
  131   		basics.put( "Character[]", Hibernate.CHARACTER_ARRAY );
  132   		basics.put( Blob.class.getName(), Hibernate.BLOB );
  133   		basics.put( Clob.class.getName(), Hibernate.CLOB );
  134   		basics.put( Serializable.class.getName(), Hibernate.SERIALIZABLE );
  135   
  136   		Type type = new AdaptedImmutableType(Hibernate.DATE);
  137   		basics.put( type.getName(), type );
  138   		type = new AdaptedImmutableType(Hibernate.TIME);
  139   		basics.put( type.getName(), type );
  140   		type = new AdaptedImmutableType(Hibernate.TIMESTAMP);
  141   		basics.put( type.getName(), type );
  142   		type = new AdaptedImmutableType( new DbTimestampType() );
  143   		basics.put( type.getName(), type );
  144   		type = new AdaptedImmutableType(Hibernate.CALENDAR);
  145   		basics.put( type.getName(), type );
  146   		type = new AdaptedImmutableType(Hibernate.CALENDAR_DATE);
  147   		basics.put( type.getName(), type );
  148   		type = new AdaptedImmutableType(Hibernate.SERIALIZABLE);
  149   		basics.put( type.getName(), type );
  150   		type = new AdaptedImmutableType(Hibernate.BINARY);
  151   		basics.put( type.getName(), type );
  152   
  153   		BASIC_TYPES = Collections.unmodifiableMap( basics );
  154   	}
  155   
  156   	private TypeFactory() {
  157   		throw new UnsupportedOperationException();
  158   	}
  159   
  160   	/**
  161   	 * A one-to-one association type for the given class
  162   	 */
  163   	public static EntityType oneToOne(
  164   			String persistentClass,
  165   			ForeignKeyDirection foreignKeyType,
  166   			String uniqueKeyPropertyName,
  167   			boolean lazy,
  168   			boolean unwrapProxy,
  169   			boolean isEmbeddedInXML,
  170   			String entityName,
  171   			String propertyName
  172   	) {
  173   		return new OneToOneType(
  174   				persistentClass,
  175   				foreignKeyType,
  176   				uniqueKeyPropertyName,
  177   				lazy,
  178   				unwrapProxy,
  179   				isEmbeddedInXML,
  180   				entityName,
  181   				propertyName
  182   			);
  183   	}
  184   
  185   	/**
  186   	 * A many-to-one association type for the given class
  187   	 */
  188   	public static EntityType manyToOne(String persistentClass) {
  189   		return new ManyToOneType( persistentClass );
  190   	}
  191   
  192   	/**
  193   	 * A many-to-one association type for the given class
  194   	 */
  195   	public static EntityType manyToOne(String persistentClass, boolean lazy) {
  196   		return new ManyToOneType( persistentClass, lazy );
  197   	}
  198   
  199   	/**
  200   	 * A many-to-one association type for the given class
  201   	 */
  202   	public static EntityType manyToOne(
  203   			String persistentClass,
  204   			String uniqueKeyPropertyName,
  205   			boolean lazy,
  206   			boolean unwrapProxy,
  207   			boolean isEmbeddedInXML,
  208   			boolean ignoreNotFound
  209   	) {
  210   		return new ManyToOneType(
  211   				persistentClass,
  212   				uniqueKeyPropertyName,
  213   				lazy,
  214   				unwrapProxy,
  215   				isEmbeddedInXML,
  216   				ignoreNotFound
  217   			);
  218   	}
  219   
  220   	/**
  221   	 * Given the name of a Hibernate basic type, return an instance of
  222   	 * <tt>org.hibernate.type.Type</tt>.
  223   	 */
  224   	public static Type basic(String name) {
  225   		return (Type) BASIC_TYPES.get( name );
  226   	}
  227   
  228   	/**
  229   	 * Uses heuristics to deduce a Hibernate type given a string naming the type or Java class.
  230   	 * Return an instance of <tt>org.hibernate.type.Type</tt>.
  231   	 */
  232   	public static Type heuristicType(String typeName) throws MappingException {
  233   		return heuristicType( typeName, null );
  234   	}
  235   
  236   	/**
  237   	 * Uses heuristics to deduce a Hibernate type given a string naming the type or Java class.
  238   	 * Return an instance of <tt>org.hibernate.type.Type</tt>.
  239   	 */
  240   	public static Type heuristicType(String typeName, Properties parameters)
  241   			throws MappingException {
  242   		Type type = TypeFactory.basic( typeName );
  243   		if ( type == null ) {
  244   			Class typeClass;
  245   			try {
  246   				typeClass = ReflectHelper.classForName( typeName );
  247   			}
  248   			catch (ClassNotFoundException cnfe) {
  249   				typeClass = null;
  250   			}
  251   			if ( typeClass != null ) {
  252   				if ( Type.class.isAssignableFrom( typeClass ) ) {
  253   					try {
  254   						type = (Type) typeClass.newInstance();
  255   					}
  256   					catch (Exception e) {
  257   						throw new MappingException(
  258   								"Could not instantiate Type: " + typeClass.getName(),
  259   								e
  260   							);
  261   					}
  262   					injectParameters(type, parameters);
  263   				}
  264   				else if ( CompositeUserType.class.isAssignableFrom( typeClass ) ) {
  265   					type = new CompositeCustomType( typeClass, parameters );
  266   				}
  267   				else if ( UserType.class.isAssignableFrom( typeClass ) ) {
  268   					type = new CustomType( typeClass, parameters );
  269   				}
  270   				else if ( Lifecycle.class.isAssignableFrom( typeClass ) ) {
  271   					type = Hibernate.entity( typeClass );
  272   				}
  273   				else if ( Serializable.class.isAssignableFrom( typeClass ) ) {
  274   					type = Hibernate.serializable( typeClass );
  275   				}
  276   			}
  277   		}
  278   		return type;
  279   
  280   	}
  281   
  282   	/**
  283   	 * The legacy contract.
  284   	 *
  285   	 * @deprecated Use {@link #customCollection(String, java.util.Properties, String, String, boolean)} instead
  286   	 */
  287   	public static CollectionType customCollection(
  288   			String typeName,
  289   			String role,
  290   			String propertyRef,
  291   			boolean embedded) {
  292   		return customCollection( typeName, null, role, propertyRef, embedded );
  293   	}
  294   
  295   	public static CollectionType customCollection(
  296   			String typeName,
  297   			Properties typeParameters,
  298   			String role,
  299   			String propertyRef,
  300   			boolean embedded) {
  301   		Class typeClass;
  302   		try {
  303   			typeClass = ReflectHelper.classForName( typeName );
  304   		}
  305   		catch ( ClassNotFoundException cnfe ) {
  306   			throw new MappingException( "user collection type class not found: " + typeName, cnfe );
  307   		}
  308   		CustomCollectionType result = new CustomCollectionType( typeClass, role, propertyRef, embedded );
  309   		if ( typeParameters != null ) {
  310   			TypeFactory.injectParameters( result.getUserType(), typeParameters );
  311   		}
  312   		return result;
  313   	}
  314   
  315   	// Collection Types:
  316   
  317   	public static CollectionType array(String role, String propertyRef, boolean embedded,
  318   			Class elementClass) {
  319   		return new ArrayType( role, propertyRef, elementClass, embedded );
  320   	}
  321   
  322   	public static CollectionType list(String role, String propertyRef, boolean embedded) {
  323   		return new ListType( role, propertyRef, embedded );
  324   	}
  325   
  326   	public static CollectionType bag(String role, String propertyRef, boolean embedded) {
  327   		return new BagType( role, propertyRef, embedded );
  328   	}
  329   
  330   	public static CollectionType idbag(String role, String propertyRef, boolean embedded) {
  331   		return new IdentifierBagType( role, propertyRef, embedded );
  332   	}
  333   
  334   	public static CollectionType map(String role, String propertyRef, boolean embedded) {
  335   		return new MapType( role, propertyRef, embedded );
  336   	}
  337   
  338   	public static CollectionType orderedMap(String role, String propertyRef, boolean embedded) {
  339   		return new OrderedMapType( role, propertyRef, embedded );
  340   	}
  341   
  342   	public static CollectionType set(String role, String propertyRef, boolean embedded) {
  343   		return new SetType( role, propertyRef, embedded );
  344   	}
  345   
  346   	public static CollectionType orderedSet(String role, String propertyRef, boolean embedded) {
  347   		return new OrderedSetType( role, propertyRef, embedded );
  348   	}
  349   
  350   	public static CollectionType sortedMap(String role, String propertyRef, boolean embedded,
  351   			Comparator comparator) {
  352   		return new SortedMapType( role, propertyRef, comparator, embedded );
  353   	}
  354   
  355   	public static CollectionType sortedSet(String role, String propertyRef, boolean embedded,
  356   			Comparator comparator) {
  357   		return new SortedSetType( role, propertyRef, comparator, embedded );
  358   	}
  359   
  360   	public static void injectParameters(Object type, Properties parameters) {
  361   		if (type instanceof ParameterizedType) {
  362   			( (ParameterizedType) type ).setParameterValues(parameters);
  363   		}
  364   		else if ( parameters!=null && !parameters.isEmpty() ) {
  365   			throw new MappingException(
  366   					"type is not parameterized: " +
  367   					type.getClass().getName()
  368   				);
  369   		}
  370   	}
  371   
  372   
  373   	// convenience methods relating to operations across arrays of types...
  374   
  375   	/**
  376   	 * Deep copy a series of values from one array to another...
  377   	 *
  378   	 * @param values The values to copy (the source)
  379   	 * @param types The value types
  380   	 * @param copy an array indicating which values to include in the copy
  381   	 * @param target The array into which to copy the values
  382   	 * @param session The orginating session
  383   	 */
  384   	public static void deepCopy(
  385   			final Object[] values,
  386   			final Type[] types,
  387   			final boolean[] copy,
  388   			final Object[] target,
  389   			final SessionImplementor session) {
  390   		for ( int i = 0; i < types.length; i++ ) {
  391   			if ( copy[i] ) {
  392   				if ( values[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY
  393   					|| values[i] == BackrefPropertyAccessor.UNKNOWN ) {
  394   					target[i] = values[i];
  395   				}
  396   				else {
  397   					target[i] = types[i].deepCopy( values[i], session.getEntityMode(), session
  398   						.getFactory() );
  399   				}
  400   			}
  401   		}
  402   	}
  403   
  404   	/**
  405   	 * Apply the {@link Type#beforeAssemble} operation across a series of values.
  406   	 *
  407   	 * @param row The values
  408   	 * @param types The value types
  409   	 * @param session The orginating session
  410   	 */
  411   	public static void beforeAssemble(
  412   			final Serializable[] row,
  413   			final Type[] types,
  414   			final SessionImplementor session) {
  415   		for ( int i = 0; i < types.length; i++ ) {
  416   			if ( row[i] != LazyPropertyInitializer.UNFETCHED_PROPERTY
  417   				&& row[i] != BackrefPropertyAccessor.UNKNOWN ) {
  418   				types[i].beforeAssemble( row[i], session );
  419   			}
  420   		}
  421   	}
  422   
  423   	/**
  424   	 * Apply the {@link Type#assemble} operation across a series of values.
  425   	 *
  426   	 * @param row The values
  427   	 * @param types The value types
  428   	 * @param session The orginating session
  429   	 * @param owner The entity "owning" the values
  430   	 * @return The assembled state
  431   	 */
  432   	public static Object[] assemble(
  433   			final Serializable[] row,
  434   			final Type[] types,
  435   			final SessionImplementor session,
  436   			final Object owner) {
  437   		Object[] assembled = new Object[row.length];
  438   		for ( int i = 0; i < types.length; i++ ) {
  439   			if ( row[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY || row[i] == BackrefPropertyAccessor.UNKNOWN ) {
  440   				assembled[i] = row[i];
  441   			}
  442   			else {
  443   				assembled[i] = types[i].assemble( row[i], session, owner );
  444   			}
  445   		}
  446   		return assembled;
  447   	}
  448   
  449   	/**
  450   	 * Apply the {@link Type#disassemble} operation across a series of values.
  451   	 *
  452   	 * @param row The values
  453   	 * @param types The value types
  454   	 * @param nonCacheable An array indicating which values to include in the disassemled state
  455   	 * @param session The orginating session
  456   	 * @param owner The entity "owning" the values
  457   	 * @return The disassembled state
  458   	 */
  459   	public static Serializable[] disassemble(
  460   			final Object[] row,
  461   			final Type[] types,
  462   			final boolean[] nonCacheable,
  463   			final SessionImplementor session,
  464   			final Object owner) {
  465   		Serializable[] disassembled = new Serializable[row.length];
  466   		for ( int i = 0; i < row.length; i++ ) {
  467   			if ( nonCacheable!=null && nonCacheable[i] ) {
  468   				disassembled[i] = LazyPropertyInitializer.UNFETCHED_PROPERTY;
  469   			}
  470   			else if ( row[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY || row[i] == BackrefPropertyAccessor.UNKNOWN ) {
  471   				disassembled[i] = (Serializable) row[i];
  472   			}
  473   			else {
  474   				disassembled[i] = types[i].disassemble( row[i], session, owner );
  475   			}
  476   		}
  477   		return disassembled;
  478   	}
  479   
  480   	/**
  481   	 * Apply the {@link Type#replace} operation across a series of values.
  482   	 *
  483   	 * @param original The source of the state
  484   	 * @param target The target into which to replace the source values.
  485   	 * @param types The value types
  486   	 * @param session The orginating session
  487   	 * @param owner The entity "owning" the values
  488   	 * @param copyCache A map representing a cache of already replaced state
  489   	 * @return The replaced state
  490   	 */
  491   	public static Object[] replace(
  492   			final Object[] original,
  493   			final Object[] target,
  494   			final Type[] types,
  495   			final SessionImplementor session,
  496   			final Object owner,
  497   			final Map copyCache) {
  498   		Object[] copied = new Object[original.length];
  499   		for ( int i = 0; i < types.length; i++ ) {
  500   			if ( original[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY
  501   				|| original[i] == BackrefPropertyAccessor.UNKNOWN ) {
  502   				copied[i] = target[i];
  503   			}
  504   			else {
  505   				copied[i] = types[i].replace( original[i], target[i], session, owner, copyCache );
  506   			}
  507   		}
  508   		return copied;
  509   	}
  510   
  511   	/**
  512   	 * Apply the {@link Type#replace} operation across a series of values.
  513   	 *
  514   	 * @param original The source of the state
  515   	 * @param target The target into which to replace the source values.
  516   	 * @param types The value types
  517   	 * @param session The orginating session
  518   	 * @param owner The entity "owning" the values
  519   	 * @param copyCache A map representing a cache of already replaced state
  520   	 * @param foreignKeyDirection FK directionality to be applied to the replacement
  521   	 * @return The replaced state
  522   	 */
  523   	public static Object[] replace(
  524   			final Object[] original,
  525   			final Object[] target,
  526   			final Type[] types,
  527   			final SessionImplementor session,
  528   			final Object owner,
  529   			final Map copyCache,
  530   			final ForeignKeyDirection foreignKeyDirection) {
  531   		Object[] copied = new Object[original.length];
  532   		for ( int i = 0; i < types.length; i++ ) {
  533   			if ( original[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY
  534   				|| original[i] == BackrefPropertyAccessor.UNKNOWN ) {
  535   				copied[i] = target[i];
  536   			}
  537   			else {
  538   				copied[i] = types[i].replace( original[i], target[i], session, owner, copyCache, foreignKeyDirection );
  539   			}
  540   		}
  541   		return copied;
  542   	}
  543   
  544   	/**
  545   	 * Apply the {@link Type#replace} operation across a series of values, as
  546   	 * long as the corresponding {@link Type} is an association.
  547   	 * <p/>
  548   	 * If the corresponding type is a component type, then apply {@link #replaceAssociations}
  549   	 * accross the component subtypes but do not replace the component value itself.
  550   	 *
  551   	 * @param original The source of the state
  552   	 * @param target The target into which to replace the source values.
  553   	 * @param types The value types
  554   	 * @param session The orginating session
  555   	 * @param owner The entity "owning" the values
  556   	 * @param copyCache A map representing a cache of already replaced state
  557   	 * @param foreignKeyDirection FK directionality to be applied to the replacement
  558   	 * @return The replaced state
  559   	 */
  560   	public static Object[] replaceAssociations(
  561   			final Object[] original,
  562   			final Object[] target,
  563   			final Type[] types,
  564   			final SessionImplementor session,
  565   			final Object owner,
  566   			final Map copyCache,
  567   			final ForeignKeyDirection foreignKeyDirection) {
  568   		Object[] copied = new Object[original.length];
  569   		for ( int i = 0; i < types.length; i++ ) {
  570   			if ( original[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY
  571   					|| original[i] == BackrefPropertyAccessor.UNKNOWN ) {
  572   				copied[i] = target[i];
  573   			}
  574   			else if ( types[i].isComponentType() ) {
  575   				// need to extract the component values and check for subtype replacements...
  576   				AbstractComponentType componentType = ( AbstractComponentType ) types[i];
  577   				Type[] subtypes = componentType.getSubtypes();
  578   				Object[] origComponentValues = original[i] == null ? new Object[subtypes.length] : componentType.getPropertyValues( original[i], session );
  579   				Object[] targetComponentValues = target[i] == null ? new Object[subtypes.length] : componentType.getPropertyValues( target[i], session );
  580   				replaceAssociations( origComponentValues, targetComponentValues, subtypes, session, null, copyCache, foreignKeyDirection );
  581   				copied[i] = target[i];
  582   			}
  583   			else if ( !types[i].isAssociationType() ) {
  584   				copied[i] = target[i];
  585   			}
  586   			else {
  587   				copied[i] = types[i].replace( original[i], target[i], session, owner, copyCache, foreignKeyDirection );
  588   			}
  589   		}
  590   		return copied;
  591   	}
  592   
  593   	/**
  594   	 * Determine if any of the given field values are dirty, returning an array containing
  595   	 * indices of the dirty fields.
  596   	 * <p/>
  597   	 * If it is determined that no fields are dirty, null is returned.
  598   	 *
  599   	 * @param properties The property definitions
  600   	 * @param currentState The current state of the entity
  601   	 * @param previousState The baseline state of the entity
  602   	 * @param includeColumns Columns to be included in the dirty checking, per property
  603   	 * @param anyUninitializedProperties Does the entity currently hold any uninitialized property values?
  604   	 * @param session The session from which the dirty check request originated.
  605   	 * @return Array containing indices of the dirty properties, or null if no properties considered dirty.
  606   	 */
  607   	public static int[] findDirty(
  608   			final StandardProperty[] properties,
  609   			final Object[] currentState,
  610   			final Object[] previousState,
  611   			final boolean[][] includeColumns,
  612   			final boolean anyUninitializedProperties,
  613   			final SessionImplementor session) {
  614   		int[] results = null;
  615   		int count = 0;
  616   		int span = properties.length;
  617   
  618   		for ( int i = 0; i < span; i++ ) {
  619   			final boolean dirty = currentState[i] != LazyPropertyInitializer.UNFETCHED_PROPERTY
  620   					&& properties[i].isDirtyCheckable( anyUninitializedProperties )
  621   					&& properties[i].getType().isDirty( previousState[i], currentState[i], includeColumns[i], session );
  622   			if ( dirty ) {
  623   				if ( results == null ) {
  624   					results = new int[span];
  625   				}
  626   				results[count++] = i;
  627   			}
  628   		}
  629   
  630   		if ( count == 0 ) {
  631   			return null;
  632   		}
  633   		else {
  634   			int[] trimmed = new int[count];
  635   			System.arraycopy( results, 0, trimmed, 0, count );
  636   			return trimmed;
  637   		}
  638   	}
  639   
  640   	/**
  641   	 * Determine if any of the given field values are modified, returning an array containing
  642   	 * indices of the modified fields.
  643   	 * <p/>
  644   	 * If it is determined that no fields are dirty, null is returned.
  645   	 *
  646   	 * @param properties The property definitions
  647   	 * @param currentState The current state of the entity
  648   	 * @param previousState The baseline state of the entity
  649   	 * @param includeColumns Columns to be included in the mod checking, per property
  650   	 * @param anyUninitializedProperties Does the entity currently hold any uninitialized property values?
  651   	 * @param session The session from which the dirty check request originated.
  652   	 * @return Array containing indices of the modified properties, or null if no properties considered modified.
  653   	 */
  654   	public static int[] findModified(
  655   			final StandardProperty[] properties, 
  656   			final Object[] currentState,
  657   			final Object[] previousState,
  658   			final boolean[][] includeColumns,
  659   			final boolean anyUninitializedProperties,
  660   			final SessionImplementor session) {
  661   		int[] results = null;
  662   		int count = 0;
  663   		int span = properties.length;
  664   
  665   		for ( int i = 0; i < span; i++ ) {
  666   			final boolean modified = currentState[i]!=LazyPropertyInitializer.UNFETCHED_PROPERTY
  667   					&& properties[i].isDirtyCheckable(anyUninitializedProperties)
  668   					&& properties[i].getType().isModified( previousState[i], currentState[i], includeColumns[i], session );
  669   
  670   			if ( modified ) {
  671   				if ( results == null ) {
  672   					results = new int[span];
  673   				}
  674   				results[count++] = i;
  675   			}
  676   		}
  677   
  678   		if ( count == 0 ) {
  679   			return null;
  680   		}
  681   		else {
  682   			int[] trimmed = new int[count];
  683   			System.arraycopy( results, 0, trimmed, 0, count );
  684   			return trimmed;
  685   		}
  686   	}
  687   
  688   }

Save This Page
Home » hibernate-distribution-3.3.1.GA-dist » org.hibernate » type » [javadoc | source]