Author: steve.ebersole(a)jboss.com
Date: 2010-06-02 01:15:54 -0400 (Wed, 02 Jun 2010)
New Revision: 19649
Modified:
core/trunk/core/src/main/java/org/hibernate/cfg/Configuration.java
core/trunk/core/src/main/java/org/hibernate/type/BasicTypeRegistry.java
core/trunk/core/src/main/java/org/hibernate/type/CompositeCustomType.java
core/trunk/core/src/main/java/org/hibernate/type/CustomType.java
core/trunk/core/src/main/java/org/hibernate/type/TypeResolver.java
core/trunk/core/src/test/java/org/hibernate/type/BasicTypeRegistryTest.java
Log:
HHH-5262 - Allow UserType and CompositeUserType to be registered with BasicTypeRegistry
Modified: core/trunk/core/src/main/java/org/hibernate/cfg/Configuration.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/Configuration.java 2010-06-01 23:23:40
UTC (rev 19648)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/Configuration.java 2010-06-02 05:15:54
UTC (rev 19649)
@@ -58,6 +58,7 @@
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
+import org.hibernate.DuplicateMappingException;
import org.hibernate.EmptyInterceptor;
import org.hibernate.HibernateException;
import org.hibernate.Interceptor;
@@ -66,9 +67,6 @@
import org.hibernate.MappingNotFoundException;
import org.hibernate.SessionFactory;
import org.hibernate.SessionFactoryObserver;
-import org.hibernate.DuplicateMappingException;
-import org.hibernate.id.IdentifierGeneratorAggregator;
-import org.hibernate.tuple.entity.EntityTuplizerFactory;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.MySQLDialect;
import org.hibernate.dialect.function.SQLFunction;
@@ -107,36 +105,39 @@
import org.hibernate.event.ReplicateEventListener;
import org.hibernate.event.SaveOrUpdateEventListener;
import org.hibernate.id.IdentifierGenerator;
+import org.hibernate.id.IdentifierGeneratorAggregator;
import org.hibernate.id.PersistentIdentifierGenerator;
+import org.hibernate.id.factory.DefaultIdentifierGeneratorFactory;
import org.hibernate.id.factory.IdentifierGeneratorFactory;
-import org.hibernate.id.factory.DefaultIdentifierGeneratorFactory;
import org.hibernate.impl.SessionFactoryImpl;
import org.hibernate.mapping.AuxiliaryDatabaseObject;
import org.hibernate.mapping.Collection;
+import org.hibernate.mapping.Column;
+import org.hibernate.mapping.DenormalizedTable;
+import org.hibernate.mapping.FetchProfile;
import org.hibernate.mapping.ForeignKey;
import org.hibernate.mapping.IdentifierCollection;
import org.hibernate.mapping.Index;
+import org.hibernate.mapping.MappedSuperclass;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.RootClass;
import org.hibernate.mapping.SimpleValue;
import org.hibernate.mapping.Table;
+import org.hibernate.mapping.TypeDef;
import org.hibernate.mapping.UniqueKey;
-import org.hibernate.mapping.FetchProfile;
-import org.hibernate.mapping.DenormalizedTable;
-import org.hibernate.mapping.TypeDef;
-import org.hibernate.mapping.Column;
-import org.hibernate.mapping.MappedSuperclass;
import org.hibernate.proxy.EntityNotFoundDelegate;
import org.hibernate.secure.JACCConfiguration;
import org.hibernate.tool.hbm2ddl.DatabaseMetadata;
+import org.hibernate.tool.hbm2ddl.IndexMetadata;
import org.hibernate.tool.hbm2ddl.TableMetadata;
-import org.hibernate.tool.hbm2ddl.IndexMetadata;
+import org.hibernate.tuple.entity.EntityTuplizerFactory;
import org.hibernate.type.BasicType;
-import org.hibernate.type.BasicTypeRegistry;
import org.hibernate.type.SerializationException;
import org.hibernate.type.Type;
import org.hibernate.type.TypeResolver;
+import org.hibernate.usertype.CompositeUserType;
+import org.hibernate.usertype.UserType;
import org.hibernate.util.ArrayHelper;
import org.hibernate.util.CollectionHelper;
import org.hibernate.util.ConfigHelper;
@@ -2287,10 +2288,25 @@
return typeResolver;
}
+ /**
+ * Allows registration of a type into the type regsitry. The phrase 'override'
in the method name simply
+ * reminds that registration *potentially* replaces a previously registered type .
+ *
+ * @param type The type to register.
+ */
public void registerTypeOverride(BasicType type) {
getTypeResolver().registerTypeOverride( type );
}
+
+ public void registerTypeOverride(UserType type, String[] keys) {
+ getTypeResolver().registerTypeOverride( type, keys );
+ }
+
+ public void registerTypeOverride(CompositeUserType type, String[] keys) {
+ getTypeResolver().registerTypeOverride( type, keys );
+ }
+
public SessionFactoryObserver getSessionFactoryObserver() {
return sessionFactoryObserver;
}
Modified: core/trunk/core/src/main/java/org/hibernate/type/BasicTypeRegistry.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/BasicTypeRegistry.java 2010-06-01
23:23:40 UTC (rev 19648)
+++ core/trunk/core/src/main/java/org/hibernate/type/BasicTypeRegistry.java 2010-06-02
05:15:54 UTC (rev 19649)
@@ -31,6 +31,8 @@
import org.slf4j.LoggerFactory;
import org.hibernate.HibernateException;
+import org.hibernate.usertype.CompositeUserType;
+import org.hibernate.usertype.UserType;
/**
* A registry of {@link BasicType} instances
@@ -146,6 +148,14 @@
}
}
+ public void register(UserType type, String[] keys) {
+ register( new CustomType( type, keys ) );
+ }
+
+ public void register(CompositeUserType type, String[] keys) {
+ register( new CompositeCustomType( type, keys ) );
+ }
+
public BasicType getRegisteredType(String key) {
return registry.get( key );
}
Modified: core/trunk/core/src/main/java/org/hibernate/type/CompositeCustomType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/CompositeCustomType.java 2010-06-01
23:23:40 UTC (rev 19648)
+++ core/trunk/core/src/main/java/org/hibernate/type/CompositeCustomType.java 2010-06-02
05:15:54 UTC (rev 19649)
@@ -29,10 +29,10 @@
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;
-import java.util.Properties;
import org.dom4j.Element;
import org.dom4j.Node;
+
import org.hibernate.EntityMode;
import org.hibernate.FetchMode;
import org.hibernate.HibernateException;
@@ -42,20 +42,40 @@
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.usertype.CompositeUserType;
+import org.hibernate.usertype.LoggableUserType;
+import org.hibernate.util.ArrayHelper;
/**
- * Adapts <tt>CompositeUserType</tt> to <tt>Type</tt> interface
+ * Adapts {@link CompositeUserType} to the {@link Type} interface
+ *
* @author Gavin King
+ * @author Steve Ebersole
*/
-public class CompositeCustomType extends AbstractType implements CompositeType {
+public class CompositeCustomType extends AbstractType implements CompositeType, BasicType
{
private final CompositeUserType userType;
+ private final String[] registrationKeys;
private final String name;
+ private final boolean customLogging;
public CompositeCustomType(CompositeUserType userType) {
+ this( userType, ArrayHelper.EMPTY_STRING_ARRAY );
+ }
+
+ public CompositeCustomType(CompositeUserType userType, String[] registrationKeys) {
this.userType = userType;
this.name = userType.getClass().getName();
+ this.customLogging = LoggableUserType.class.isInstance( userType );
+ this.registrationKeys = registrationKeys;
}
-
+
+ public String[] getRegistrationKeys() {
+ return registrationKeys;
+ }
+
+ public CompositeUserType getUserType() {
+ return userType;
+ }
+
public boolean isMethodOf(Method method) {
return false;
}
@@ -155,8 +175,8 @@
public int getColumnSpan(Mapping mapping) throws MappingException {
Type[] types = userType.getPropertyTypes();
int n=0;
- for (int i=0; i<types.length; i++) {
- n+=types[i].getColumnSpan(mapping);
+ for ( Type type : types ) {
+ n += type.getColumnSpan( mapping );
}
return n;
}
@@ -217,20 +237,26 @@
}
public int[] sqlTypes(Mapping mapping) throws MappingException {
- Type[] types = userType.getPropertyTypes();
int[] result = new int[ getColumnSpan(mapping) ];
int n=0;
- for (int i=0; i<types.length; i++) {
- int[] sqlTypes = types[i].sqlTypes(mapping);
- for ( int k=0; k<sqlTypes.length; k++ ) result[n++] = sqlTypes[k];
+ for ( Type type : userType.getPropertyTypes() ) {
+ for ( int sqlType : type.sqlTypes( mapping ) ) {
+ result[n++] = sqlType;
+ }
}
return result;
}
- public String toLoggableString(Object value, SessionFactoryImplementor factory)
- throws HibernateException {
-
- return value==null ? "null" : value.toString();
+ public String toLoggableString(Object value, SessionFactoryImplementor factory) throws
HibernateException {
+ if ( value == null ) {
+ return "null";
+ }
+ else if ( customLogging ) {
+ return ( (LoggableUserType) userType ).toLoggableString( value, factory );
+ }
+ else {
+ return value.toString();
+ }
}
public boolean[] getPropertyNullability() {
Modified: core/trunk/core/src/main/java/org/hibernate/type/CustomType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/CustomType.java 2010-06-01 23:23:40
UTC (rev 19648)
+++ core/trunk/core/src/main/java/org/hibernate/type/CustomType.java 2010-06-02 05:15:54
UTC (rev 19649)
@@ -44,32 +44,42 @@
import org.hibernate.usertype.LoggableUserType;
import org.hibernate.usertype.UserType;
import org.hibernate.usertype.UserVersionType;
+import org.hibernate.util.ArrayHelper;
/**
* Adapts {@link UserType} to the generic {@link Type} interface, in order
* to isolate user code from changes in the internal Type contracts.
*
- * @see org.hibernate.usertype.UserType
* @author Gavin King
+ * @author Steve Ebersole
*/
-public class CustomType extends AbstractType implements IdentifierType,
DiscriminatorType, VersionType {
-
+public class CustomType extends AbstractType implements IdentifierType,
DiscriminatorType, VersionType, BasicType {
private final UserType userType;
private final String name;
private final int[] types;
private final boolean customLogging;
+ private final String[] registrationKeys;
public CustomType(UserType userType) throws MappingException {
+ this( userType, ArrayHelper.EMPTY_STRING_ARRAY );
+ }
+
+ public CustomType(UserType userType, String[] registrationKeys) throws MappingException
{
this.userType = userType;
this.name = userType.getClass().getName();
this.types = userType.sqlTypes();
this.customLogging = LoggableUserType.class.isInstance( userType );
+ this.registrationKeys = registrationKeys;
}
public UserType getUserType() {
return userType;
}
+ public String[] getRegistrationKeys() {
+ return registrationKeys;
+ }
+
public int[] sqlTypes(Mapping pi) {
return types;
}
@@ -86,8 +96,7 @@
return userType.equals(x, y);
}
- public boolean isEqual(Object x, Object y, EntityMode entityMode)
- throws HibernateException {
+ public boolean isEqual(Object x, Object y, EntityMode entityMode) throws
HibernateException {
return isEqual(x, y);
}
@@ -95,33 +104,24 @@
return userType.hashCode(x);
}
- public Object nullSafeGet(
- ResultSet rs,
- String[] names,
- SessionImplementor session,
- Object owner
- ) throws HibernateException, SQLException {
-
+ public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session,
Object owner)
+ throws HibernateException, SQLException {
return userType.nullSafeGet(rs, names, owner);
}
- public Object nullSafeGet(
- ResultSet rs,
- String columnName,
- SessionImplementor session,
- Object owner
- ) throws HibernateException, SQLException {
+ public Object nullSafeGet(ResultSet rs, String columnName, SessionImplementor session,
Object owner)
+ throws HibernateException, SQLException {
return nullSafeGet(rs, new String[] { columnName }, session, owner);
}
public Object assemble(Serializable cached, SessionImplementor session, Object owner)
- throws HibernateException {
+ throws HibernateException {
return userType.assemble(cached, owner);
}
public Serializable disassemble(Object value, SessionImplementor session, Object owner)
- throws HibernateException {
+ throws HibernateException {
return userType.disassemble(value);
}
@@ -130,42 +130,36 @@
Object target,
SessionImplementor session,
Object owner,
- Map copyCache)
- throws HibernateException {
+ Map copyCache) throws HibernateException {
return userType.replace(original, target, owner);
}
- public void nullSafeSet(
- PreparedStatement st,
- Object value,
- int index,
- boolean[] settable,
- SessionImplementor session
- ) throws HibernateException, SQLException {
-
- if ( settable[0] ) userType.nullSafeSet(st, value, index);
+ public void nullSafeSet(PreparedStatement st, Object value, int index, boolean[]
settable, SessionImplementor session)
+ throws HibernateException, SQLException {
+ if ( settable[0] ) {
+ userType.nullSafeSet( st, value, index );
+ }
}
- public void nullSafeSet(
- PreparedStatement st,
- Object value,
- int index,
- SessionImplementor session
- ) throws HibernateException, SQLException {
-
- userType.nullSafeSet(st, value, index);
+ public void nullSafeSet(PreparedStatement st, Object value, int index,
SessionImplementor session)
+ throws HibernateException, SQLException {
+ userType.nullSafeSet( st, value, index );
}
+ @SuppressWarnings({ "UnusedDeclaration" })
public String toXMLString(Object value, SessionFactoryImplementor factory) {
- if (value==null) return null;
- if (userType instanceof EnhancedUserType) {
- return ( (EnhancedUserType) userType ).toXMLString(value);
+ if ( value == null ) {
+ return null;
}
+ if ( userType instanceof EnhancedUserType ) {
+ return ( (EnhancedUserType) userType ).toXMLString( value );
+ }
else {
return value.toString();
}
}
+ @SuppressWarnings({ "UnusedDeclaration" })
public Object fromXMLString(String xml, Mapping factory) {
return ( (EnhancedUserType) userType ).fromXMLString(xml);
}
@@ -175,7 +169,7 @@
}
public Object deepCopy(Object value, EntityMode entityMode, SessionFactoryImplementor
factory)
- throws HibernateException {
+ throws HibernateException {
return userType.deepCopy(value);
}
@@ -208,12 +202,12 @@
}
public void setToXMLNode(Node node, Object value, SessionFactoryImplementor factory)
- throws HibernateException {
+ throws HibernateException {
node.setText( toXMLString(value, factory) );
}
public String toLoggableString(Object value, SessionFactoryImplementor factory)
- throws HibernateException {
+ throws HibernateException {
if ( value == null ) {
return "null";
}
@@ -227,12 +221,14 @@
public boolean[] toColumnNullness(Object value, Mapping mapping) {
boolean[] result = new boolean[ getColumnSpan(mapping) ];
- if (value!=null) Arrays.fill(result, true);
+ if ( value != null ) {
+ Arrays.fill(result, true);
+ }
return result;
}
- public boolean isDirty(Object old, Object current, boolean[] checkable,
SessionImplementor session) throws HibernateException {
+ public boolean isDirty(Object old, Object current, boolean[] checkable,
SessionImplementor session)
+ throws HibernateException {
return checkable[0] && isDirty(old, current, session);
}
-
}
Modified: core/trunk/core/src/main/java/org/hibernate/type/TypeResolver.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/TypeResolver.java 2010-06-01 23:23:40
UTC (rev 19648)
+++ core/trunk/core/src/main/java/org/hibernate/type/TypeResolver.java 2010-06-02 05:15:54
UTC (rev 19649)
@@ -60,6 +60,14 @@
basicTypeRegistry.register( type );
}
+ public void registerTypeOverride(UserType type, String[] keys) {
+ basicTypeRegistry.register( type, keys );
+ }
+
+ public void registerTypeOverride(CompositeUserType type, String[] keys) {
+ basicTypeRegistry.register( type, keys );
+ }
+
public TypeFactory getTypeFactory() {
return typeFactory;
}
Modified: core/trunk/core/src/test/java/org/hibernate/type/BasicTypeRegistryTest.java
===================================================================
--- core/trunk/core/src/test/java/org/hibernate/type/BasicTypeRegistryTest.java 2010-06-01
23:23:40 UTC (rev 19648)
+++ core/trunk/core/src/test/java/org/hibernate/type/BasicTypeRegistryTest.java 2010-06-02
05:15:54 UTC (rev 19649)
@@ -23,13 +23,21 @@
*/
package org.hibernate.type;
+import java.io.Serializable;
import java.net.URL;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
import java.util.UUID;
import junit.framework.TestCase;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionImplementor;
import org.hibernate.type.descriptor.java.UrlTypeDescriptor;
import org.hibernate.type.descriptor.sql.VarcharTypeDescriptor;
+import org.hibernate.usertype.CompositeUserType;
+import org.hibernate.usertype.UserType;
/**
* TODO : javadoc
@@ -67,6 +75,27 @@
assertSame( UrlType.INSTANCE, type );
}
+ public void testRegisteringUserTypes() {
+ registry.register( new TotallyIrrelevantUserType(), new String[] { "key" }
);
+ BasicType type = registry.getRegisteredType( "key" );
+ assertNotNull( type );
+ assertEquals( CustomType.class, type.getClass() );
+ assertEquals( TotallyIrrelevantUserType.class, ( (CustomType) type
).getUserType().getClass() );
+
+ registry.register( new TotallyIrrelevantCompositeUserType(), new String[] {
"key" } );
+ type = registry.getRegisteredType( "key" );
+ assertNotNull( type );
+ assertEquals( CompositeCustomType.class, type.getClass() );
+ assertEquals( TotallyIrrelevantCompositeUserType.class, ( (CompositeCustomType) type
).getUserType().getClass() );
+
+ type = registry.getRegisteredType( UUID.class.getName() );
+ assertSame( UUIDBinaryType.INSTANCE, type );
+ registry.register( new TotallyIrrelevantUserType(), new String[] { UUID.class.getName()
} );
+ type = registry.getRegisteredType( UUID.class.getName() );
+ assertNotSame( UUIDBinaryType.INSTANCE, type );
+ assertEquals( CustomType.class, type.getClass() );
+ }
+
public static class UrlType extends AbstractSingleColumnStandardBasicType<URL> {
public static final UrlType INSTANCE = new UrlType();
@@ -83,4 +112,111 @@
return true;
}
}
+
+ public static class TotallyIrrelevantUserType implements UserType {
+
+ public int[] sqlTypes() {
+ return new int[0];
+ }
+
+ public Class returnedClass() {
+ return null;
+ }
+
+ public boolean equals(Object x, Object y) throws HibernateException {
+ return false;
+ }
+
+ public int hashCode(Object x) throws HibernateException {
+ return 0;
+ }
+
+ public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws
HibernateException, SQLException {
+ return null;
+ }
+
+ public void nullSafeSet(PreparedStatement st, Object value, int index) throws
HibernateException, SQLException {
+ }
+
+ public Object deepCopy(Object value) throws HibernateException {
+ return null;
+ }
+
+ public boolean isMutable() {
+ return false;
+ }
+
+ public Serializable disassemble(Object value) throws HibernateException {
+ return null;
+ }
+
+ public Object assemble(Serializable cached, Object owner) throws HibernateException {
+ return null;
+ }
+
+ public Object replace(Object original, Object target, Object owner) throws
HibernateException {
+ return null;
+ }
+ }
+
+ public static class TotallyIrrelevantCompositeUserType implements CompositeUserType {
+
+ public String[] getPropertyNames() {
+ return new String[0];
+ }
+
+ public Type[] getPropertyTypes() {
+ return new Type[0];
+ }
+
+ public Object getPropertyValue(Object component, int property) throws
HibernateException {
+ return null;
+ }
+
+ public void setPropertyValue(Object component, int property, Object value) throws
HibernateException {
+ }
+
+ public Class returnedClass() {
+ return null;
+ }
+
+ public boolean equals(Object x, Object y) throws HibernateException {
+ return false;
+ }
+
+ public int hashCode(Object x) throws HibernateException {
+ return 0;
+ }
+
+ public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session,
Object owner)
+ throws HibernateException, SQLException {
+ return null;
+ }
+
+ public void nullSafeSet(PreparedStatement st, Object value, int index,
SessionImplementor session)
+ throws HibernateException, SQLException {
+ }
+
+ public Object deepCopy(Object value) throws HibernateException {
+ return null;
+ }
+
+ public boolean isMutable() {
+ return false;
+ }
+
+ public Serializable disassemble(Object value, SessionImplementor session) throws
HibernateException {
+ return null;
+ }
+
+ public Object assemble(Serializable cached, SessionImplementor session, Object owner)
+ throws HibernateException {
+ return null;
+ }
+
+ public Object replace(Object original, Object target, SessionImplementor session,
Object owner)
+ throws HibernateException {
+ return null;
+ }
+ }
}