/**
* Copyright (C) 2008-2010, Squale Project - http://www.squale.org
*
* This file is part of Squale.
*
* Squale is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or any later version.
*
* Squale 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 General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Squale. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Created on 18 ao�t 06
*
*/
package org.squale.jraf.provider.persistence.hibernate;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.sql.Blob;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.usertype.UserType;
import org.squale.jraf.commons.exception.JrafEnterpriseException;
import org.squale.jraf.helper.PersistenceHelper;
/**
* @author M401540
*
* Nouveau type Hibernate pour un Blob -> byte[]
*/
public class BinaryBlobType implements UserType {
/** (non-Javadoc)
* @see org.hibernate.usertype.UserType#sqlTypes()
*/
public int[] sqlTypes() {
return new int[] { Types.BLOB };
}
/** (non-Javadoc)
* @see org.hibernate.usertype.UserType#returnedClass()
*/
public Class returnedClass() {
return byte[].class;
}
/** (non-Javadoc)
* @see org.hibernate.usertype.UserType#equals(java.lang.Object, java.lang.Object)
*/
public boolean equals(Object x, Object y) throws HibernateException {
return (x == y)
|| (x != null
&& y != null
&& java.util.Arrays.equals((byte[]) x, (byte[]) y));
}
/** (non-Javadoc)
* @see org.hibernate.usertype.UserType#hashCode(java.lang.Object)
*/
public int hashCode(Object arg0) throws HibernateException {
return arg0.hashCode();
}
/** (non-Javadoc)
* @see org.hibernate.usertype.UserType#nullSafeGet(java.sql.ResultSet, java.lang.String[], java.lang.Object)
*/
public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
throws HibernateException, SQLException {
Blob fromBlob = rs.getBlob(names[0]);
if(fromBlob == null) {
return null;
}
// un appel � blob.getBytes(1, (int) blob.length());
// ne marche pas sous Oracle, d'o� l'utilisation du Stream
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
return toByteArrayImpl(fromBlob, baos);
} catch (IOException e) {
// lever un exception
throw new HibernateException(e);
} finally {
if (baos != null) {
try {
//fermeture du flux
baos.close();
} catch (IOException ex) {
// ne rien faire dans le finally !
}
}
}
}
/**
* Utilitaire de conversion Blob -> byte[]. <br />
* Obligatoire pour Oracle !
* @param fromBlob Blob � lire
* @param baos Byte array pour l'ecriture
* @return byte[] correspondand au Blob
* @throws SQLException en cas de pb sur le blob
* @throws IOException en cas de pb d'ecriture deans le Stream
*
*/
private static byte[] toByteArrayImpl(Blob fromBlob, ByteArrayOutputStream baos) throws SQLException, IOException {
final int MAXSIZE = 4000;
byte[] buf = new byte[MAXSIZE];
InputStream is = fromBlob.getBinaryStream();
try {
int dataSize;
do {
//lecture du flux
dataSize = is.read(buf);
if (dataSize != -1) {
//ecriture
baos.write(buf, 0, dataSize);
}
} while (dataSize != -1);
} finally {
if (is != null) {
try {
//fermeture du flux
is.close();
} catch (IOException ex) {
// ne rien faire dans le finally !
}
}
}
return baos.toByteArray();
}
/** (non-Javadoc)
* @see org.hibernate.usertype.UserType#nullSafeSet(java.sql.PreparedStatement, java.lang.Object, int)
*/
public void nullSafeSet(PreparedStatement st, Object value, int index)
throws HibernateException, SQLException {
if (value==null) {
st.setNull(index, Types.BLOB);
} else {
if (((SessionFactoryImplementor) ((PersistenceProviderImpl) PersistenceHelper.getPersistenceProvider()).getSessions()).getDialect().useInputStreamToInsertBlob()) {
st.setBinaryStream( index, new ByteArrayInputStream((byte[]) value), ((byte [])value).length );
} else {
st.setBlob(index, (Blob) Hibernate.createBlob((byte[]) value));
}
}
}
/** (non-Javadoc)
* @see org.hibernate.usertype.UserType#deepCopy(java.lang.Object)
*/
public Object deepCopy(Object value) {
if (value == null) {
return null;
}
byte[] bytes = (byte[]) value;
byte[] result = new byte[bytes.length];
System.arraycopy(bytes, 0, result, 0, bytes.length);
return result;
}
/** (non-Javadoc)
* @see org.hibernate.usertype.UserType#isMutable()
*/
public boolean isMutable() {
return true;
}
/**
* @see org.hibernate.usertype.UserType#assemble(java.io.Serializable, java.lang.Object)
*/
public Object assemble(Serializable cached, Object owner) {
return deepCopy(cached);
}
/**
* @see org.hibernate.usertype.UserType#disassemble(java.lang.Object)
*/
public Serializable disassemble(Object value) {
return (Serializable) deepCopy(value);
}
/**
* @see org.hibernate.usertype.UserType#replace(java.lang.Object, java.lang.Object, java.lang.Object)
*/
public Object replace(Object original, Object target, Object owner) {
return deepCopy(original);
}
/**
* Utilitaire pour transformer des fichiers en byte(]
* @param file Fichier a lire
* @return fichier sous forme de byte[]
* @throws JrafEnterpriseException dans le cas ou le fichier est trop gros ou fichier manquant.
*/
static public byte[] fileToByte(File file) throws JrafEnterpriseException {
byte[] buffer = null;
long fSize = file.length();
// cas tres gros fichier
if (fSize > Integer.MAX_VALUE) {
throw new JrafEnterpriseException("File too long");
} else {
buffer = new byte[(int) fSize];
}
try {
(new FileInputStream(file)).read(buffer);
} catch (FileNotFoundException e) {
throw new JrafEnterpriseException(e);
} catch (IOException e) {
throw new JrafEnterpriseException(e);
}
return buffer;
}
}