/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.type;
import java.io.Serializable;
import java.lang.InstantiationException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import org.hibernate.HibernateException;
import org.hibernate.type.descriptor.sql.BlobTypeDescriptor;
import org.hibernate.type.descriptor.sql.ClobTypeDescriptor;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
/**
* Provides alternative types for binding LOB values.
*
* @author Gail Badner
*/
public abstract class AlternativeLobTypes<S, T extends LobType<S>> implements Serializable {
private final T defaultType;
private final T streamBindingType;
private final T lobBindingType;
private AlternativeLobTypes(Class<? extends T> clazz,
SqlTypeDescriptor defaultDescriptor,
SqlTypeDescriptor streamBindingDescriptor,
SqlTypeDescriptor lobBindingDescriptor) {
Constructor constructor = getConstructor( clazz );
defaultType = createLobType( clazz, constructor, defaultDescriptor );
streamBindingType = createLobType( clazz, constructor, streamBindingDescriptor );
lobBindingType = createLobType( clazz, constructor, lobBindingDescriptor );
}
/**
* Returns the type that uses the default binding LOB values.
* @return type that uses the default binding
* @see BlobTypeDescriptor#DEFAULT
* @see ClobTypeDescriptor#DEFAULT
*/
public final T getDefaultType() {
return defaultType;
}
/**
* Returns the type that binds LOB values using streams.
*
* @return type that binds using a stream
*
* @see BlobTypeDescriptor#STREAM_BINDING
* @see ClobTypeDescriptor#STREAM_BINDING
*/
public final T getStreamBindingType() {
return streamBindingType;
}
/**
* Returns the type that explicitly binds the LOB value,
* @return type that binds the LOB
* @see BlobTypeDescriptor#BLOB_BINDING
* @see ClobTypeDescriptor#CLOB_BINDING
*/
public final T getLobBindingType() {
return lobBindingType;
}
protected Constructor getConstructor(Class<? extends T> clazz) {
try {
return clazz.getDeclaredConstructor( SqlTypeDescriptor.class, this.getClass() );
}
catch (NoSuchMethodException e) {
throw new HibernateException(
"Could not get constructor for " +
clazz.getClass().getName() +
" with argument types: [" +
SqlTypeDescriptor.class.getName() + ", " + this.getClass().getName() +
"]", e
);
}
}
protected T createLobType(Class<? extends T> lobTypeClass,
Constructor constructor,
SqlTypeDescriptor sqlTypeDescriptor) {
try {
return lobTypeClass.cast( constructor.newInstance( sqlTypeDescriptor, this ) );
}
catch ( InstantiationException e ) {
throw new HibernateException( "Cannot instantiate type: " + lobTypeClass.getName() );
}
catch ( IllegalAccessException e ) {
throw new HibernateException( "IllegalAccessException trying to instantiate: " + lobTypeClass.getName() );
}
catch (InvocationTargetException e) {
throw new HibernateException( "Could not create type: " + lobTypeClass.getName(), e.getCause() );
}
}
/**
* Provides alternative types for binding {@link java.sql.Types#CLOB CLOB} values.
*/
public static class ClobTypes<S, T extends LobType<S>> extends AlternativeLobTypes<S,T> {
/* package-protected */
ClobTypes(Class<? extends T> clobTypeClass) {
super(
clobTypeClass,
ClobTypeDescriptor.DEFAULT,
ClobTypeDescriptor.STREAM_BINDING,
ClobTypeDescriptor.CLOB_BINDING
);
}
}
/**
* Provides alternative types for binding {@link java.sql.Types#BLOB BLOB} values.
*/
public static class BlobTypes<S, T extends LobType<S>> extends AlternativeLobTypes<S,T> {
private final T primitiveArrayBindingType;
/* package-protected */
BlobTypes(Class<? extends T> blobTypeClass) {
super(
blobTypeClass,
BlobTypeDescriptor.DEFAULT,
BlobTypeDescriptor.STREAM_BINDING,
BlobTypeDescriptor.BLOB_BINDING
);
Constructor constructor = getConstructor( blobTypeClass );
primitiveArrayBindingType = createLobType(
blobTypeClass, constructor, BlobTypeDescriptor.PRIMITIVE_ARRAY_BINDING
);
}
/**
* Returns the type that explicitly binds the {@link java.sql.Types#BLOB BLOB} value,
* @return type that binds the {@link java.sql.Types#BLOB BLOB}
* @see BlobTypeDescriptor#PRIMITIVE_ARRAY_BINDING
*/
public final T getPrimitiveArrayBindingType() {
return primitiveArrayBindingType;
}
}
}