package acube.framework.technical.jdbc;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Vector;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import org.apache.commons.dbcp.ConnectionFactory;
import org.apache.commons.dbcp.DriverManagerConnectionFactory;
import org.apache.commons.dbcp.PoolableConnectionFactory;
import org.apache.commons.dbcp.PoolingDataSource;
import org.apache.commons.pool.ObjectPool;
import org.apache.commons.pool.impl.GenericObjectPool;
import org.apache.log4j.Logger;
import acube.framework.exception.ConfigurationException;
import acube.framework.exception.JDBCWrapperException;
import acube.framework.technical.Configuration;
import acube.framework.technical.ConfigurationManager;
import acube.framework.technical.log.BuildLogger;
import acube.framework.technical.log.Chrono;
import acube.framework.technical.log.level.Performance;
/**
* Classe d'encapsulation des accès à la base de données via l'API JDBC Drivers
* recommandés :
*
* - Pour Oracle 8 : classes12.jar et nls_charset12.jar est utilisé pour les
* STRUCT et COLLECTION
*
- Pour Oracle 9 et 10 : ojdbc14.jar et nls_charset12.jar est utilisé pour
* les STRUCT et COLLECTION
*
- Pour MSSQL : jtds-1.2.jar
*
*
* @author AUBAY
* @version 1.0
*/
public class JDBCWrapper {
/** m_logger
: Definition du logger */
protected static Logger logger = BuildLogger
.getLogger();
/**
* THIS_CLASS
: Définition de la classe utilisée par le
* logger
*/
private static final String THIS_CLASS = "[acube.framework.technical.JDBCWrapper]";
/**
* Clé à utiliser en cas de base unique (compatibilité avec anciennes
* version)
*/
protected static final String BASE_UNIQUE = "baseUnique";
/**
* configuration
: gestionnaire de la configuration chargée
*/
protected static java.util.Hashtable dataSources = null;
/**
* Configuration : Donnees specifiques au serveur.
*/
protected static Configuration _configServer;
/**
* Recordset contenant les données récupérées par la requête
*/
private ResultSet _rset;
/**
* Statement
*/
private PreparedStatement _prep;
/**
* CallableStatement
*/
private CallableStatement _call;
/**
* Connexion à la base de données
*/
private Connection _connection;
/**
* Valeur de l'autocommit
*/
private boolean _autoCommit = true;
/**
* Si true alors JDBCWrapper a déjà une connexion vers la base ouverte
*/
private boolean _isConnected = false;
/**
* Nom Jndi de la DataSource à utiliser
*/
protected String _dataSourceName;
/**
* variable indiquant l'état de la transaction
*/
protected boolean inTransaction;
/**
* TYPE_REQUETE_QUERY
appel d'une methode executeQuery() sur
* le statement qui valorise un ResultSet qui sera accede par la suite via
* une methode du JDBCWrapper : en consequence cette fonctionnalite renvoie
* toujours un int de valeur 0 pour signifier que tout c'est bien deroule.
*/
public static final int TYPE_REQUETE_QUERY = 0;
/**
* TYPE_REQUETE_UPDATE
appel d'une methode executeUpdate()
* sur le statement qui renvoie un int correspondant au nombre de lignes
* impactees par la requete : il s'agit de requetes de type update, delete
* ou insert.
*/
public static final int TYPE_REQUETE_UPDATE = 1;
/**
* TYPE_REQUETE_EXECUTE
appel d'une methode execute() sur le
* statement qui renvoie un boolean : celui-ci est converti pour le retour
* de la façon suivante : true -> 1 et false -> 0.
*/
public static final int TYPE_REQUETE_EXECUTE = 2;
/**
* TYPE_LOB_CLOB
selectionne la mise en base d'un CLOB pour
* la méthode saveOracleLob
*/
public static final int TYPE_LOB_CLOB = 1;
/**
* TYPE_LOB_BLOB
selectionne la mise en base d'un BLOB pour
* la méthode saveOracleLob
*/
public static final int TYPE_LOB_BLOB = 2;
/**
* TYPE_DATE_DATE
selectionne le format Date comme retour de
* getDate()
*/
public static final String TYPE_DATE_DATE = "date";
/**
* TYPE_DATE_TIMESTAMP
selectionne le format Timestamp comme
* retour de getDate()
*/
public static final String TYPE_DATE_TIMESTAMP = "timestamp";
/**
* outParamProc
Vecteur en retour contenant les elements de
* type OUT et IN_OUT passes en parametre des procedure stockees.
*/
private Vector outParamProc = null;
/**
* hTypes
Table de hashage contenant les identifiants des
* différents types.
*/
private static java.util.Hashtable hTypes = null;
private ArrayList outCursorList = null;
/**
* Initialisation des datasources non standard
*/
public void initOtherDataSource() {
}
/**
* @param dataSourceName
*/
public void initDataSource(String dataSourceName) {
// Initialisation de la Hashtable contenant les pools de connexion
if (dataSources == null) {
dataSources = new java.util.Hashtable();
}
this.initOtherDataSource();
if (hTypes == null) {
initTypes();
}
// Définition du non JNDI de la ressource à utiliser
if (dataSourceName != null && dataSourceName.compareTo("") != 0) {
_dataSourceName = dataSourceName;
} else {
_dataSourceName = BASE_UNIQUE;
}
// Récupération des fichiers de propriétés.
_configServer = ConfigurationManager.getInstance("server");
}
/**
* Constructeur par defaut de l'objet JDBCWrapper
.
*/
public JDBCWrapper() {
initDataSource(null);
}
/**
* Constructeur de l'objet JDBCWrapper
.
*/
public JDBCWrapper(String dataSourceName) {
initDataSource(dataSourceName);
}
/**
* @param outCursorList outCursorList à définir.
*/
void setOutCursorList(ArrayList outCursorList) {
this.outCursorList = outCursorList;
}
/**
* @return Renvoie outCursorList.
*/
ArrayList getOutCursorList() {
return outCursorList;
}
/**
* @return Renvoie dataSources.
*/
static java.util.Hashtable getDataSources() {
return dataSources;
}
/**
* @param dataSources dataSources à définir.
*/
static void setDataSources(java.util.Hashtable dataSources) {
JDBCWrapper.dataSources = dataSources;
}
/**
* @return Renvoie _call.
*/
protected CallableStatement get_call() {
return _call;
}
/**
* @param _call _call à définir.
*/
protected void set_call(CallableStatement _call) {
this._call = _call;
}
/**
* @return Renvoie _prep.
*/
protected PreparedStatement get_prep() {
return _prep;
}
/**
* @param _prep _prep à définir.
*/
protected void set_prep(PreparedStatement _prep) {
this._prep = _prep;
}
/**
* @return Renvoie _rset.
*/
protected ResultSet get_rset() {
return _rset;
}
/**
* @param _rset _rset à définir.
*/
protected void set_rset(ResultSet _rset) {
this._rset = _rset;
}
/**
* @return Renvoie inTransaction.
*/
protected boolean isInTransaction() {
return inTransaction;
}
/**
* @param inTransaction inTransaction à définir.
*/
protected void setInTransaction(boolean inTransaction) {
this.inTransaction = inTransaction;
}
/**
* @return Renvoie _isConnected.
*/
protected boolean is_isConnected() {
return _isConnected;
}
/**
* @param connected _isConnected à définir.
*/
protected void set_isConnected(boolean connected) {
_isConnected = connected;
}
/**
* @return Renvoie _dataSourceName.
*/
protected String get_dataSourceName() {
return _dataSourceName;
}
/**
* @return Renvoie _configServer.
*/
protected static Configuration get_configServer() {
return _configServer;
}
/**
* @return Renvoie logger.
*/
protected static Logger getLogger() {
return logger;
}
/**
* @param outParamProc outParamProc à définir.
*/
void setOutParamProc(Vector outParamProc) {
this.outParamProc = outParamProc;
}
/**
* Cette méthode permet de préparer l'exécution d'une requête en fermant
* éventuellement le PreparedStatement et/ou le RecordSet préalablement
* ouverts.
*
* @exception JDBCWrapperException
*/
private void beforeExecute() throws JDBCWrapperException {
try {
// Fermeture du RecordSet.
if (_rset != null) {
_rset.close();
_rset = null;
}
// Fermeture du PreparedStatement
closePreparedStatement();
// Fermeture du CallableStatement.
closeCallableStatement();
} catch (Exception e) {
throw new JDBCWrapperException(
"Erreur.JDBCWrapper.beforeExecute : " + e.getMessage(), e);
}
}
/**
* Cloture des connextions non standard.
*/
public void closeOtherCnx() throws SQLException {
}
/**
* Ferme la connexion à la base de données ainsi que les éventuels objets
* afférents (ResultSet et PreparedStatement). Ici nous avons des actions
* spécifiques dans le cas d'une transaction.
*
* @exception JDBCWrapperException Si problème à la fermeture de la
* connection
*/
public void close() throws JDBCWrapperException {
try {
// Fermeture du ResultSet.
if (_rset != null) {
_rset.close();
_rset = null;
}
// Fermeture du PreparedStatement
closePreparedStatement();
// Fermeture du CallableStatement.
closeCallableStatement();
// Fermeture de la connexion.
// gestion de transaction
// attention : ne pas appeler de méthode sur le TransactionManger
// ici, en particulier inTransaction()
// car le close() est aussi appelé par le thread du Garbage
// Collector lors de la finalisation du JDBCWrapper
if (inTransaction) {
// dans une transaction applicative, la connection est fermée en
// fin de transaction
} else {
if (_connection != null) {
_connection.close();
_connection = null;
} else {
//
}
}
this.closeOtherCnx();
} catch (Exception e) {
throw new JDBCWrapperException("Erreur.JDBCWrapper.close : "
+ e.getMessage(), e);
}
}
/**
* Ferme le PreparedStatement
*
* @exception JDBCWrapperException Si problème à la fermeture du
* PreparedStatement
* @version 2.3
* @date 14/11/2006
*/
private void closePreparedStatement() throws JDBCWrapperException {
try {
// Fermeture du preparedStatement.
if (_prep != null) {
_prep.close();
_prep = null;
}
} catch (Exception e) {
throw new JDBCWrapperException(
"Erreur.JDBCWrapper.closePreparedStatement : "
+ e.getMessage(), e);
}
}
/**
* Ferme le CallableStatement
*
* @param call CallableStatement à fermer.
* @exception JDBCWrapperException Si problème à la fermeture du
* CallableStatement
*/
private void closeCallableStatement() throws JDBCWrapperException {
try {
ResultSet rsFromCursor = null;
if (outCursorList != null) {
for (int i = 0; i < outCursorList.size(); i++) {
rsFromCursor = (ResultSet) outCursorList.get(i);
if (rsFromCursor != null)
rsFromCursor.close();
rsFromCursor = null;
}
}
outCursorList = null;
// Fermeture du CallableStatement.
if (_call != null) {
_call.close();
_call = null;
}
} catch (Exception e) {
throw new JDBCWrapperException(
"Erreur.JDBCWrapper.closeCallableStatement : "
+ e.getMessage(), e);
}
}
/**
* Commit manuel. Dans le cas d'un transaction rien n'est fait.
*
* @exception JDBCWrapperException dans le cas d'erreur lors de l'éxécution
* de la requête (erreur SQL par ex.).
*/
public void commit() throws JDBCWrapperException {
logger.info(THIS_CLASS + "commit");
try {
// gestion des transactions
if (inTransaction) {
// dans une transaction applicative, le commit doit être
// effectué au niveau de la transaction
} else {
getConnection().commit();
}
} catch (JDBCWrapperException e) {
throw e;
} catch (Exception e) {
throw new JDBCWrapperException("Erreur.JDBCWrapper.commit : "
+ e.getMessage(), e);
}
}
/**
* Réalise un Rollback. Dans le cas d'une transaction rien n'est fait.
*
* @exception JDBCWrapperException dans le cas d'erreur lors de l'éxécution
* de la requête (erreur SQL par ex.).
*/
public void rollback() throws JDBCWrapperException {
logger.info(THIS_CLASS + "rollback");
try {
// gestion des transactions
if (inTransaction) {
// dans une transaction applicative, le rollback doit être
// effectué au niveau de la transaction
} else {
getConnection().rollback();
}
} catch (JDBCWrapperException e) {
throw e;
} catch (Exception e) {
throw new JDBCWrapperException("Erreur.JDBCWrapper.rollback : "
+ e.getMessage(), e);
}
}
/**
* Execute une requete
*
* @param sql la requete SQL a executer
* @param type le type de requete : TYPE_REQUETE_QUERY ou
* TYPE_REQUETE_UPDATE ou TYPE_REQUETE_EXECUTE
* @return int resultat depend du type
*
* - TYPE_REQUETE_EXECUTE : retour 0 ou 1
*
- TYPE_REQUETE_UPDATE : retourne le nombre de ligne impactées
*
- TYPE_REQUETE_QUERY : retourne 0 + renseignement de _rset
*
* @throws JDBCWrapperException dans le cas d'erreur lors de l'éxécution de
* la requête (erreur SQL par ex.).
*/
public int execute(String sql, int type) throws JDBCWrapperException {
logger.info(THIS_CLASS + "execute(String sql, int type)");
return execute(sql, type, new Vector());
}
/**
* Execute une requete avec un paramètre en type String Remet le paramètre
* dans un vecteur.
*
* @param sql la requete SQL a executer
* @param type le type de requete : TYPE_REQUETE_QUERY ou
* TYPE_REQUETE_UPDATE ou TYPE_REQUETE_EXECUTE
* @param param un parametre de type String
* @return int resultat depend du type de la requête.
*
* - TYPE_REQUETE_EXECUTE : retour 0 ou 1
*
- TYPE_REQUETE_UPDATE : retourne le nombre de ligne impactées
*
- TYPE_REQUETE_QUERY : retourne 0 + renseignement de _rset
*
* @throws JDBCWrapperException dans le cas d'erreur lors de l'éxécution de
* la requête (erreur SQL par ex.).
*/
public int execute(String sql, int type, String param)
throws JDBCWrapperException {
logger.info(THIS_CLASS + "execute(String sql, int type, String param)");
Vector params = new Vector();
params.addElement(param);
return execute(sql, type, params);
}
/**
* Verification du type de base et renvoie une exception en cas de MSSQL
*
* @throws JDBCWrapperException
*/
void verifBaseMSSQL() throws JDBCWrapperException {
try {
// Verifie le type de base, dans le cas de MSSQL on envoie un
// exception
java.sql.DatabaseMetaData md = _connection.getMetaData();
if (md.getDatabaseProductName().indexOf("SQL Server") != 0) {
throw new JDBCWrapperException(
"Timestamp pas géré dans le Wrapper pour MSSQL");
}
} catch (SQLException e) {
throw new JDBCWrapperException(
"Problème de récupération des infos sur la base");
} catch (JDBCWrapperException ex) {
throw new JDBCWrapperException(ex.getMessage());
}
}
/**
* Execute une requete avec un vecteur de paramètres
*
* @param sql la requete SQL a executer
* @param type le type de requete : TYPE_REQUETE_QUERY ou
* TYPE_REQUETE_UPDATE ou TYPE_REQUETE_EXECUTE
* @param params une liste de parametres sous forme de Vector
*
* |
* ORACLE |
* SQL SERVER |
*
*
* setLong |
* O |
* O |
*
*
* ByteArrayOutputStream |
* O |
* O (BLOB) |
*
*
* setBoolean |
* O |
* O |
*
*
* setString |
* O |
* O |
*
*
* setBigDecimal |
* O |
* O |
*
*
* setDouble |
* O |
* O |
*
*
* setInt |
* O |
* O |
*
*
* setBigDecimal |
* O |
* O |
*
*
* setFloat |
* O |
* O |
*
*
* setShort |
* O |
* O |
*
*
* setTimestamp |
* O |
* voir setDate |
*
*
* setDate |
* O |
* O |
*
*
* setString |
* O |
* O |
*
*
* @return int resultat depend du type de la requête.
*
* - TYPE_REQUETE_EXECUTE : retour 0 ou 1
*
- TYPE_REQUETE_UPDATE : retourne le nombre de ligne impactées
*
- TYPE_REQUETE_QUERY : retourne 0 + renseignement de _rset
*
* @throws JDBCWrapperException dans le cas d'erreur lors de l'éxécution de
* la requête (erreur SQL par ex.).
*/
public int execute(String sql, int type, Vector params)
throws JDBCWrapperException {
// Demarrage du Timer pour la mesure de PERF
Chrono chrono = new Chrono();
chrono.start();
logger.info(THIS_CLASS + "execute(String sql, Vector params)");
int resultat = 0;
try {
beforeExecute();
// récupération du preparedStatement
_prep = getConnection().prepareStatement(sql);
for (int i = 0; i < params.size(); i++) {
// traitement des parametres nuls
if (params.elementAt(i) == null) {
// si le parametre courant est nul, on fixe le champ sql à
// nul
// _prep.setNull(i + 1, Types.NULL);
_prep.setNull(i + 1, _prep.getParameterMetaData()
.getParameterType(i + 1));
} else {
String className = params.elementAt(i).getClass().getName();
if (className.equals("java.lang.String")) {
_prep.setString(i + 1, (String) params.elementAt(i));
} else if (className.equals("java.lang.Integer")) {
_prep.setInt(i + 1, ((Integer) params.elementAt(i))
.intValue());
} else if (className.equals("java.lang.Long")) {
_prep.setLong(i + 1, ((Long) params.elementAt(i))
.longValue());
} else if (className.equals("java.lang.Double")) {
_prep.setDouble(i + 1, ((Double) params.elementAt(i))
.doubleValue());
} else if (className.equals("java.util.Date")
|| className.equals("java.sql.Date")) {
// _prep.setDate ne met que la partie Date de la valeur
// fournie
// en paramètre dans la base de données
// _prep.setDate(i+1, new
// java.sql.Date(((java.util.Date)
// params.elementAt(i)).getTime()));
_prep.setTimestamp(i + 1, new java.sql.Timestamp(
((java.util.Date) params.elementAt(i))
.getTime()));
} else if (className.equals("java.sql.Time")) {
_prep.setTime(i + 1, (java.sql.Time) params
.elementAt(i));
} else if (className.equals("java.sql.Timestamp")) {
// Verifie le type de base, dans le cas de MSSQL on
// envoie un exception
// verifBaseMSSQL();
_prep.setTimestamp(i + 1, (java.sql.Timestamp) params
.elementAt(i));
} else if (className
.equals("java.io.ByteArrayOutputStream")) {
// recuperation du parametre courant
ByteArrayOutputStream baos = (ByteArrayOutputStream) params
.elementAt(i);
// creation d'un input stream
ByteArrayInputStream bais = new ByteArrayInputStream(
baos.toByteArray());
_prep.setBinaryStream(i + 1, bais, baos.size());
} else if (className.equals("java.lang.Boolean")) {
_prep.setBoolean(i + 1, ((Boolean) params.elementAt(i))
.booleanValue());
} else if (className.equals("java.math.BigDecimal")) {
_prep.setBigDecimal(i + 1, (BigDecimal) params
.elementAt(i));
} else if (className.equals("java.lang.Float")) {
_prep.setFloat(i + 1, ((Float) params.elementAt(i))
.floatValue());
} else if (className.equals("java.lang.Short")) {
_prep.setShort(i + 1, ((Short) params.elementAt(i))
.shortValue());
} else if (className.equals("java.lang.Short")) {
_prep.setShort(i + 1, ((Short) params.elementAt(i))
.shortValue());
} else {
chrono.stop();
if (logger.isEnabledFor(Performance.TRACE)) {
logger.log(Performance.TRACE, THIS_CLASS
+ "Temps d'exécution: " + chrono.time()
+ " ms");
}
// La classe d'un des paramètres n'est pas traitée ici
throw new JDBCWrapperException(
"Erreur.JDBCWrapper.execute.unknownParameterClass");
}
}
}
// Envoi des traces au logger si il est actif
if (logger.isDebugEnabled()) {
StringBuffer sb = new StringBuffer("([Requête = " + sql + "]");
for (int i = 0; i < params.size(); i++) {
sb.append(", [P");
sb.append(i);
sb.append("= ");
if (params.elementAt(i) == null)
sb.append("null");
else
sb.append(params.elementAt(i).toString().trim());
sb.append("]");
}
sb.append(").");
logger.info(THIS_CLASS + "requête SQL : " + sb);
}
// retour suivant le type de requête
if (type == TYPE_REQUETE_EXECUTE) {
if (_prep.execute())
resultat = 1;
} else if (type == TYPE_REQUETE_UPDATE) {
resultat = _prep.executeUpdate();
} else if (type == TYPE_REQUETE_QUERY) {
_rset = _prep.executeQuery();
} else {
chrono.stop();
if (logger.isEnabledFor(Performance.TRACE)) {
logger.log(Performance.TRACE, THIS_CLASS
+ "Temps d'exécution: " + chrono.time() + " ms");
}
// Le type de requete n'est pas connu
throw new JDBCWrapperException(
"Erreur.JDBCWrapper.execute.unknownTypeRequete");
}
} catch (SQLException se) {
chrono.stop();
if (logger.isEnabledFor(Performance.TRACE)) {
logger.log(Performance.TRACE, THIS_CLASS
+ "Temps d'exécution: " + chrono.time() + " ms");
}
// En cas de perte de connexion à la base, il faut forcer la
// reconstitution du pool de connexion
dataSources.remove(_dataSourceName);
throw new JDBCWrapperException("Erreur.JDBCWrapper.execute = "
+ se.getMessage(), se);
} catch (Exception e) {
chrono.stop();
if (logger.isEnabledFor(Performance.TRACE)) {
logger.log(Performance.TRACE, THIS_CLASS
+ "Temps d'exécution: " + chrono.time() + " ms");
}
throw new JDBCWrapperException("Erreur.JDBCWrapper.execute = "
+ e.getMessage(), e);
}
chrono.stop();
if (logger.isEnabledFor(Performance.TRACE)) {
logger.log(Performance.TRACE, THIS_CLASS + "Temps d'exécution: "
+ chrono.time() + " ms");
}
return resultat;
}
/**
* Traitement des parametres non standard dans l'execute procedure
*
* @param _call
* @param paramProc
* @param i
* @return
* @throws SQLException
* @throws Exception
*/
public int traitementParamNonStandard(CallableStatement _call,
ProcedureParameter paramProc, int i) throws SQLException, Exception {
return 0;
}
/**
* Traitement des retours non standard
*
* @param paramProc
* @param outParamProc
* @param i
* @return
* @throws SQLException
* @throws Exception
*/
public int traitementRetourNonStandard(ProcedureParameter paramProc,
Vector outParamProc, int i) throws SQLException, Exception {
return 0;
}
/**
* Execute une procedure
*
* @param sql la requete SQL a executer
* @param type le type de requete : TYPE_REQUETE_QUERY ou
* TYPE_REQUETE_UPDATE ou TYPE_REQUETE_EXECUTE
* @param params une liste de parametres sous forme de Vector
*
* |
* ORACLE |
* SQL SERVER |
*
*
* setLong |
* O |
* O |
*
*
* setBinaryStream |
* O |
* O |
*
*
* setBoolean |
* O |
* O |
*
*
* setString |
* O |
* O |
*
*
* setBigDecimal |
* O |
* O |
*
*
* setDouble |
* O |
* O |
*
*
* setInt |
* O |
* O |
*
*
* setBigDecimal |
* O |
* O |
*
*
* setFloat |
* O |
* O |
*
*
* setShort |
* O |
* O |
*
*
* setTimestamp |
* O |
* x |
*
*
* setString |
* O |
* O |
*
*
* STRUCT |
* O |
* x |
*
*
* COLLECTION |
* O |
* x |
*
*
* @return int resultat depend du type de requête.
*
* - TYPE_REQUETE_EXECUTE : retour 0 ou 1
*
- TYPE_REQUETE_UPDATE : retourne le nombre de ligne impactées
*
- TYPE_REQUETE_QUERY : retourne 0 + renseignement de _rset
*
* @throws JDBCWrapperException dans le cas d'erreur lors de l'éxécution de
* la requête (erreur SQL par ex.).
*/
public int executeProcedure(String sql, int type, Vector params)
throws JDBCWrapperException {
// Demarrage du Timer pour la mesure de PERF
Chrono chrono = new Chrono();
chrono.start();
logger.info(THIS_CLASS
+ "executeProcedure(String sql, int type, Vector params)");
int resultat = 0;
ProcedureParameter paramProc = null;
String className = null;
outParamProc = new Vector();
try {
beforeExecute();
_call = getConnection().prepareCall(sql);
for (int i = 0; i < params.size(); i++) {
paramProc = (ProcedureParameter) params.elementAt(i);
// traitement des parametres nuls.
if (paramProc.getParam() == null
&& paramProc.getTypeSQL() == ProcedureParameter.TYPE_SQL_STANDARD) {
// si le parametre courant est nul, on fixe le champ sql à
// nul
if (paramProc.getType() == ProcedureParameter.TYPE_IN) {
_call.setNull(i + 1, decodeClassName(paramProc
.getClassName()));
} else if (paramProc.getType() == ProcedureParameter.TYPE_OUT) {
_call.registerOutParameter(i + 1,
decodeClassName(paramProc.getClassName()));
} else if (paramProc.getType() == ProcedureParameter.TYPE_IN_OUT) {
_call.setNull(i + 1, decodeClassName(paramProc
.getClassName()));
_call.registerOutParameter(i + 1,
decodeClassName(paramProc.getClassName()));
} else {
chrono.stop();
if (logger.isEnabledFor(Performance.TRACE)) {
logger.log(Performance.TRACE, THIS_CLASS
+ "Temps d'exécution: " + chrono.time()
+ " ms");
}
throw new JDBCWrapperException(
"Erreur.JDBCWrapper.executeProcedure.unknownParameterType, usage : IN, OUT or IN_OUT");
}
} else if (traitementParamNonStandard(_call, paramProc, i) == 1) {
// traitement des types de paramètres standards.
} else {
className = paramProc.getParam().getClass().getName();
if (className.equals("java.lang.String")) {
if (paramProc.getType() == ProcedureParameter.TYPE_IN) {
_call.setString(i + 1, (String) paramProc
.getParam());
} else if (paramProc.getType() == ProcedureParameter.TYPE_OUT) {
_call.registerOutParameter(i + 1, Types.VARCHAR);
} else if (paramProc.getType() == ProcedureParameter.TYPE_IN_OUT) {
_call.setString(i + 1, (String) paramProc
.getParam());
_call.registerOutParameter(i + 1, Types.VARCHAR);
} else {
chrono.stop();
if (logger.isEnabledFor(Performance.TRACE)) {
logger.log(Performance.TRACE, THIS_CLASS
+ "Temps d'exécution: " + chrono.time()
+ " ms");
}
throw new JDBCWrapperException(
"Erreur.JDBCWrapper.executeProcedure.unknownParameterType, usage : IN, OUT or IN_OUT");
}
} else if (className.equals("java.lang.Integer")) {
if (paramProc.getType() == ProcedureParameter.TYPE_IN) {
_call
.setInt(i + 1, ((Integer) paramProc
.getParam()).intValue());
} else if (paramProc.getType() == ProcedureParameter.TYPE_OUT) {
_call.registerOutParameter(i + 1, Types.INTEGER);
} else if (paramProc.getType() == ProcedureParameter.TYPE_IN_OUT) {
_call
.setInt(i + 1, ((Integer) paramProc
.getParam()).intValue());
_call.registerOutParameter(i + 1, Types.INTEGER);
} else {
throw new JDBCWrapperException(
"Erreur.JDBCWrapper.executeProcedure.unknownParameterType, usage : IN, OUT or IN_OUT");
}
} else if (className.equals("java.lang.Long")) {
if (paramProc.getType() == ProcedureParameter.TYPE_IN) {
_call.setLong(i + 1, ((Long) paramProc.getParam())
.longValue());
} else if (paramProc.getType() == ProcedureParameter.TYPE_OUT) {
_call.registerOutParameter(i + 1, Types.NUMERIC);
} else if (paramProc.getType() == ProcedureParameter.TYPE_IN_OUT) {
_call.setLong(i + 1, ((Long) paramProc.getParam())
.longValue());
_call.registerOutParameter(i + 1, Types.NUMERIC);
} else {
chrono.stop();
if (logger.isEnabledFor(Performance.TRACE)) {
logger.log(Performance.TRACE, THIS_CLASS
+ "Temps d'exécution: " + chrono.time()
+ " ms");
}
throw new JDBCWrapperException(
"Erreur.JDBCWrapper.executeProcedure.unknownParameterType, usage : IN, OUT or IN_OUT");
}
} else if (className.equals("java.lang.Double")) {
if (paramProc.getType() == ProcedureParameter.TYPE_IN) {
_call.setDouble(i + 1, ((Double) paramProc
.getParam()).doubleValue());
} else if (paramProc.getType() == ProcedureParameter.TYPE_OUT) {
_call.registerOutParameter(i + 1, Types.DOUBLE);
} else if (paramProc.getType() == ProcedureParameter.TYPE_IN_OUT) {
_call.setDouble(i + 1, ((Double) paramProc
.getParam()).doubleValue());
_call.registerOutParameter(i + 1, Types.DOUBLE);
} else {
throw new JDBCWrapperException(
"Erreur.JDBCWrapper.executeProcedure.unknownParameterType, usage : IN, OUT or IN_OUT");
}
} else if (className.equals("java.util.Date")
|| className.equals("java.sql.Date")) {
if (paramProc.getType() == ProcedureParameter.TYPE_IN) {
_call.setTimestamp(i + 1, new java.sql.Timestamp(
((java.util.Date) paramProc.getParam())
.getTime()));
} else if (paramProc.getType() == ProcedureParameter.TYPE_OUT) {
_call.registerOutParameter(i + 1, Types.TIMESTAMP);
} else if (paramProc.getType() == ProcedureParameter.TYPE_IN_OUT) {
_call.setTimestamp(i + 1, new java.sql.Timestamp(
((java.util.Date) paramProc.getParam())
.getTime()));
_call.registerOutParameter(i + 1, Types.TIMESTAMP);
} else {
throw new JDBCWrapperException(
"Erreur.JDBCWrapper.executeProcedure.unknownParameterType, usage : IN, OUT or IN_OUT");
}
} else if (className.equals("java.sql.Time")) {
if (paramProc.getType() == ProcedureParameter.TYPE_IN) {
_call.setTime(i + 1, (java.sql.Time) paramProc
.getParam());
} else if (paramProc.getType() == ProcedureParameter.TYPE_OUT) {
_call.registerOutParameter(i + 1, Types.TIME);
} else if (paramProc.getType() == ProcedureParameter.TYPE_IN_OUT) {
_call.setTime(i + 1, (java.sql.Time) paramProc
.getParam());
_call.registerOutParameter(i + 1, Types.TIME);
} else {
chrono.stop();
if (logger.isEnabledFor(Performance.TRACE)) {
logger.log(Performance.TRACE, THIS_CLASS
+ "Temps d'exécution: " + chrono.time()
+ " ms");
}
throw new JDBCWrapperException(
"Erreur.JDBCWrapper.executeProcedure.unknownParameterType, usage : IN, OUT or IN_OUT");
}
} else if (className.equals("java.sql.Timestamp")) {
// Verifie le type de base, dans le cas de MSSQL on
// envoie un exception
// verifBaseMSSQL();
if (paramProc.getType() == ProcedureParameter.TYPE_IN) {
_call.setTimestamp(i + 1,
(java.sql.Timestamp) paramProc.getParam());
} else if (paramProc.getType() == ProcedureParameter.TYPE_OUT) {
_call.registerOutParameter(i + 1, Types.TIMESTAMP);
} else if (paramProc.getType() == ProcedureParameter.TYPE_IN_OUT) {
_call.setTimestamp(i + 1,
(java.sql.Timestamp) paramProc.getParam());
_call.registerOutParameter(i + 1, Types.TIMESTAMP);
} else {
chrono.stop();
if (logger.isEnabledFor(Performance.TRACE)) {
logger.log(Performance.TRACE, THIS_CLASS
+ "Temps d'exécution: " + chrono.time()
+ " ms");
}
throw new JDBCWrapperException(
"Erreur.JDBCWrapper.executeProcedure.unknownParameterType, usage : IN, OUT or IN_OUT");
}
} else if (className
.equals("java.io.ByteArrayOutputStream")) {
// recuperation du parametre courant
ByteArrayOutputStream baos = (ByteArrayOutputStream) paramProc
.getParam();
// creation d'un input stream
ByteArrayInputStream bais = new ByteArrayInputStream(
baos.toByteArray());
if (paramProc.getType() == ProcedureParameter.TYPE_IN) {
_call.setBinaryStream(i + 1, bais, baos.size());
} else if (paramProc.getType() == ProcedureParameter.TYPE_OUT) {
_call.registerOutParameter(i + 1, Types.VARBINARY);
} else if (paramProc.getType() == ProcedureParameter.TYPE_IN_OUT) {
_call.setBinaryStream(i + 1, bais, baos.size());
_call.registerOutParameter(i + 1, Types.VARBINARY);
} else {
chrono.stop();
if (logger.isEnabledFor(Performance.TRACE)) {
logger.log(Performance.TRACE, THIS_CLASS
+ "Temps d'exécution: " + chrono.time()
+ " ms");
}
throw new JDBCWrapperException(
"Erreur.JDBCWrapper.executeProcedure.unknownParameterType, usage : IN, OUT or IN_OUT");
}
} else if (className.equals("java.lang.Boolean")) {
if (paramProc.getType() == ProcedureParameter.TYPE_IN) {
_call.setBoolean(i + 1, ((Boolean) paramProc
.getParam()).booleanValue());
} else if (paramProc.getType() == ProcedureParameter.TYPE_OUT) {
_call.registerOutParameter(i + 1, Types.BOOLEAN);
} else if (paramProc.getType() == ProcedureParameter.TYPE_IN_OUT) {
_call.setBoolean(i + 1, ((Boolean) paramProc
.getParam()).booleanValue());
_call.registerOutParameter(i + 1, Types.BOOLEAN);
} else {
throw new JDBCWrapperException(
"Erreur.JDBCWrapper.executeProcedure.unknownParameterType, usage : IN, OUT or IN_OUT");
}
} else if (className.equals("java.math.BigDecimal")) {
if (paramProc.getType() == ProcedureParameter.TYPE_IN) {
_call.setBigDecimal(i + 1, (BigDecimal) paramProc
.getParam());
} else if (paramProc.getType() == ProcedureParameter.TYPE_OUT) {
_call.registerOutParameter(i + 1, Types.DECIMAL);
} else if (paramProc.getType() == ProcedureParameter.TYPE_IN_OUT) {
_call.setBigDecimal(i + 1, (BigDecimal) paramProc
.getParam());
_call.registerOutParameter(i + 1, Types.DECIMAL);
} else {
chrono.stop();
if (logger.isEnabledFor(Performance.TRACE)) {
logger.log(Performance.TRACE, THIS_CLASS
+ "Temps d'exécution: " + chrono.time()
+ " ms");
}
throw new JDBCWrapperException(
"Erreur.JDBCWrapper.executeProcedure.unknownParameterType, usage : IN, OUT or IN_OUT");
}
} else if (className.equals("java.lang.Float")) {
if (paramProc.getType() == ProcedureParameter.TYPE_IN) {
_call
.setFloat(i + 1, ((Float) paramProc
.getParam()).floatValue());
} else if (paramProc.getType() == ProcedureParameter.TYPE_OUT) {
_call.registerOutParameter(i + 1, Types.FLOAT);
} else if (paramProc.getType() == ProcedureParameter.TYPE_IN_OUT) {
_call
.setFloat(i + 1, ((Float) paramProc
.getParam()).floatValue());
_call.registerOutParameter(i + 1, Types.FLOAT);
} else {
chrono.stop();
if (logger.isEnabledFor(Performance.TRACE)) {
logger.log(Performance.TRACE, THIS_CLASS
+ "Temps d'exécution: " + chrono.time()
+ " ms");
}
throw new JDBCWrapperException(
"Erreur.JDBCWrapper.executeProcedure.unknownParameterType, usage : IN, OUT or IN_OUT");
}
} else if (className.equals("java.lang.Short")) {
if (paramProc.getType() == ProcedureParameter.TYPE_IN) {
_call
.setShort(i + 1, ((Short) paramProc
.getParam()).shortValue());
} else if (paramProc.getType() == ProcedureParameter.TYPE_OUT) {
_call.registerOutParameter(i + 1, Types.SMALLINT);
} else if (paramProc.getType() == ProcedureParameter.TYPE_IN_OUT) {
_call
.setShort(i + 1, ((Short) paramProc
.getParam()).shortValue());
_call.registerOutParameter(i + 1, Types.SMALLINT);
} else {
chrono.stop();
if (logger.isEnabledFor(Performance.TRACE)) {
logger.log(Performance.TRACE, THIS_CLASS
+ "Temps d'exécution: " + chrono.time()
+ " ms");
}
throw new JDBCWrapperException(
"Erreur.JDBCWrapper.executeProcedure.unknownParameterType, usage : IN, OUT or IN_OUT");
}
} else {
// La classe d'un des paramètres n'est pas traitée ici
chrono.stop();
if (logger.isEnabledFor(Performance.TRACE)) {
logger.log(Performance.TRACE, THIS_CLASS
+ "Temps d'exécution: " + chrono.time()
+ " ms");
}
throw new JDBCWrapperException(
"Erreur.JDBCWrapper.executeProcedure.unknownParameterClass");
}
}
}
if (logger.isDebugEnabled()) {
StringBuffer sb = new StringBuffer("([Requête = " + sql + "]");
for (int i = 0; i < params.size(); i++) {
sb.append(", [P");
sb.append(i);
sb.append("= ");
if (((ProcedureParameter) params.elementAt(i)).getParam() == null)
sb.append("null");
else
sb.append(((ProcedureParameter) params.elementAt(i))
.getParam().toString());
sb.append("]");
}
sb.append(").");
logger.info(THIS_CLASS + "requête SQL : " + sb);
}
// préparation du retour suivant le type de requête
if (type == TYPE_REQUETE_EXECUTE) {
if (_call.execute())
resultat = 1;
} else if (type == TYPE_REQUETE_UPDATE) {
resultat = _call.executeUpdate();
} else if (type == TYPE_REQUETE_QUERY) {
_rset = _call.executeQuery();
} else {
// Le type de requete n'est pas connu
chrono.stop();
if (logger.isEnabledFor(Performance.TRACE)) {
logger.log(Performance.TRACE, THIS_CLASS
+ "Temps d'exécution: " + chrono.time() + " ms");
}
throw new JDBCWrapperException(
"Erreur.JDBCWrapper.executeProcedure.unknownTypeRequete");
}
className = null;
for (int i = 0; i < params.size(); i++) {
paramProc = (ProcedureParameter) params.elementAt(i);
if (logger.isDebugEnabled()) {
StringBuffer sb = new StringBuffer(
"paramProc - élément numéro " + i
+ ", paramProc.getType() = "
+ paramProc.getType()
+ ", paramProc.getTypeSQL() = "
+ paramProc.getTypeSQL()
+ ", paramProc.getClassName() = "
+ paramProc.getClassName()
+ ", paramProc.getStructName() = "
+ paramProc.getStructName());
if (paramProc.getParam() == null) {
sb.append(", paramProc.getParam() = " + null);
} else {
sb
.append(", paramProc.getParam().getClass().getName() = "
+ paramProc.getParam().getClass()
.getName());
}
logger.info(THIS_CLASS + sb);
}
// Ce paramètre est forcément de type OUT
if (paramProc.getTypeSQL() == ProcedureParameter.TYPE_SQL_CURSOR) {
ResultSet rsFromCursor = null;
try {
rsFromCursor = (ResultSet) getObject(i + 1);
} catch (Exception e) {
// gestion du cas où le curseur n'a pas été ouvert dans
// la procédure
// ou bien fermé prématurément : l'erreur générée est
// REF cursor non valide
rsFromCursor = getConnection().prepareStatement(
"select * from DUAL").executeQuery();
logger.info(THIS_CLASS
+ "rsFromCursor.getFetchSize() = "
+ rsFromCursor.getFetchSize());
while (rsFromCursor.next())
logger.info(THIS_CLASS + "rsFromCursor.next()");
}
if (outCursorList == null)
outCursorList = new ArrayList();
outCursorList.add(rsFromCursor);
outParamProc.addElement(rsFromCursor);
} else if (paramProc.getType() == ProcedureParameter.TYPE_OUT
|| paramProc.getType() == ProcedureParameter.TYPE_IN_OUT) {
if (paramProc.getParam() == null) {
className = paramProc.getClassName();
} else {
className = paramProc.getParam().getClass().getName();
}
if (traitementRetourNonStandard(paramProc, outParamProc, i) == 1) {
// traitement des types de paramètres standards.
} else if (className.equals("java.lang.String")) {
outParamProc.addElement(getString(i + 1));
} else if (className.equals("java.lang.Integer")) {
outParamProc.addElement(new Integer(getInt(i + 1)));
} else if (className.equals("java.lang.Long")) {
outParamProc.addElement(new Long(getLong(i + 1)));
} else if (className.equals("java.lang.Double")) {
outParamProc.addElement(new Double(getDouble(i + 1)));
} else if (className.equals("java.util.Date")) {
outParamProc.addElement(getDate(i + 1));
} else if (className.equals("java.sql.Time")) {
outParamProc.addElement(getDate(i + 1));
} else if (className.equals("java.sql.Timestamp")) {
outParamProc.addElement(getDate(i + 1));
} else if (className
.equals("java.io.ByteArrayOutputStream")) {
outParamProc
.addElement((ByteArrayOutputStream) getObject(i + 1));
} else if (className.equals("java.lang.Boolean")) {
outParamProc.addElement(getObject(i + 1));
} else if (className.equals("java.math.BigDecimal")) {
outParamProc.addElement(getBigDecimal(i + 1));
} else if (className.equals("java.lang.Float")) {
outParamProc.addElement(new Float(getFloat(i + 1)));
} else if (className.equals("java.lang.Short")) {
outParamProc.addElement(new Short(getShort(i + 1)));
} else {
// La classe d'un des paramètres n'est pas traitée ici
chrono.stop();
if (logger.isEnabledFor(Performance.TRACE)) {
logger.log(Performance.TRACE, THIS_CLASS
+ "Temps d'exécution: " + chrono.time()
+ " ms");
}
throw new JDBCWrapperException(
"Erreur.JDBCWrapper.executeProcedure.unknownParameterClass");
}
}
}
} catch (SQLException se) {
chrono.stop();
if (logger.isEnabledFor(Performance.TRACE)) {
logger.log(Performance.TRACE, THIS_CLASS
+ "Temps d'exécution: " + chrono.time() + " ms");
}
// En cas de perte de connexion à la base, il faut forcer la
// reconstitution du pool de connexion
dataSources.remove(_dataSourceName);
throw new JDBCWrapperException(
"Erreur.JDBCWrapper.executeProcedure : " + se.getMessage()
+ " ", se);
} catch (Exception e) {
chrono.stop();
if (logger.isEnabledFor(Performance.TRACE)) {
logger.log(Performance.TRACE, THIS_CLASS
+ "Temps d'exécution: " + chrono.time() + " ms");
}
throw new JDBCWrapperException(
"Erreur.JDBCWrapper.executeProcedure : " + e.getMessage(),
e);
}
chrono.stop();
if (logger.isEnabledFor(Performance.TRACE)) {
logger.log(Performance.TRACE, THIS_CLASS + "Temps d'exécution: "
+ chrono.time() + " ms");
}
return resultat;
}
/**
* Retourne le type dépendant du nom d'une class contenu dans la table da
* hashage
*
* @param className Nom de la class
* @return Type de la class
* @throws JDBCWrapperException
*/
protected int decodeClassName(String className) throws JDBCWrapperException {
Object objectClassName = hTypes.get(className);
if (objectClassName != null) {
return ((Integer) objectClassName).intValue();
} else {
throw new JDBCWrapperException(
"Erreur.JDBCWrapper.decodeClassName.unknownParameterClass");
}
}
/**
* Initialisation de la table de hashage faisant la correspondance entre le
* nom d'une classe et sont type.
*/
protected void initTypes() {
hTypes = new java.util.Hashtable();
hTypes.put("java.lang.String", new Integer(Types.VARCHAR));
hTypes.put("java.lang.Integer", new Integer(Types.INTEGER));
hTypes.put("java.lang.Long", new Integer(Types.NUMERIC));
hTypes.put("java.lang.Double", new Integer(Types.DOUBLE));
hTypes.put("java.util.Date", new Integer(Types.TIMESTAMP));
hTypes.put("java.sql.Time", new Integer(Types.TIME));
hTypes.put("java.sql.Timestamp", new Integer(Types.TIMESTAMP));
hTypes.put("java.io.ByteArrayOutputStream",
new Integer(Types.VARBINARY));
hTypes.put("java.lang.Boolean", new Integer(Types.BOOLEAN));
hTypes.put("java.math.BigDecimal", new Integer(Types.DECIMAL));
hTypes.put("java.lang.Float", new Integer(Types.FLOAT));
hTypes.put("java.lang.Short", new Integer(Types.SMALLINT));
}
/**
* Methode exécutée avant de décharger l'objet JDBCWrapper de la mémoire.
* Ferme la connection à la BD si ce n'est pas déjà fait. La méthode
* finalize n'etant pas contrôlée, il ne faut pas compter dessus pour fermer
* la connexion à la BD et libérer cette ressource. Aussi la méthode close
* doit être appelée explicitement sur les objets JDBCWrapper dans la clause
* finally.
*/
protected void finalize() throws JDBCWrapperException {
if ((!inTransaction) && (_connection != null)) {
logger.warn(THIS_CLASS
+ "finalize() : la connexion n'a pas été libérée");
}
close();
}
/**
* Récupération d'une connexion à la base de données. Ici nous avons des
* actions spécifiques dans le cas d'une transaction.
*
* @return une connexion à la base de données
*/
Connection getConnection() throws Exception {
if (logger.isDebugEnabled()) {
logger.info(THIS_CLASS + "getConnection() - _connection = "
+ _connection);
}
if (_connection == null) {
try {
// gestion de transaction
if (TransactionManager.getInstance().inTransaction()) {
// on est à l'intérieur d'une transaction
// on initialise un boolean car on ne pas appeler la méthode
// inTransaction() partout,
// notamment dans la méthode close() car cette dernière est
// aussi appelée par le thread du Garbage Collector lors de
// la finalisation du JDBCWrapper
inTransaction = true;
// une connexion a t-elle eté établie?
_connection = TransactionManager.getInstance()
.getConnection();
if (_connection == null) {
// non, on la récupère
_connection = getDataSource().getConnection();
// on l'attache au thread courant
TransactionManager.getInstance().attacheConnection(
_connection);// on attache la connextion au
// thread
}
} else {
// le wrapper n'est pas appelé dans une transaction
// applicative
inTransaction = false;
_connection = getDataSource().getConnection();
_connection.setAutoCommit(_autoCommit);
}
_isConnected = true;
} catch (Exception e) {
throw new JDBCWrapperException(
"Erreur.JDBCWrapper.getConnection : " + e.getMessage(),
e);
}
}
return _connection;
}
/**
* Récupération d'une des sources de données mises en cache
* pour améliorer les performances.
*
* @return objet DataSource correspondant au dataSourceName
*/
protected DataSource getDataSource() throws JDBCWrapperException {
DataSource ds = (DataSource) dataSources.get(_dataSourceName);
if (logger.isDebugEnabled()) {
logger.info(THIS_CLASS + "getDataSource() - _dataSourceName = "
+ _dataSourceName);
}
if (ds == null) {
// Plusieurs threads peuvent accéder à cette fonction simultanément
synchronized (this) {
try {
if (BASE_UNIQUE.equals(_dataSourceName)) {
// Pour garder la compatibilité avec les anciennes versions
//Définition de la dataSource
String dataSource = _configServer
.getString("JDBCWrapper.jdbc.dataSourceName");
//Si une datasource est déclarée
if (dataSource!=null && dataSource.compareTo("")!=0){
this.initDataSource(dataSource);
ds = recupereDataSource();
} else {
// Définition du driver JDBC
String driver = _configServer
.getString("JDBCWrapper.jdbc.driver");
// Utilisateur de la base de données
String user = _configServer
.getString("JDBCWrapper.jdbc.user");
// Son password
String pw = _configServer
.getString("JDBCWrapper.jdbc.password");
// URL JDBC de connexion
String connectURI = _configServer
.getString("JDBCWrapper.jdbc.URL");
// Définition du nombre max de connexion simultané
Integer maxPoolSize = new Integer(_configServer
.getString("JDBCWrapper.jdbc.maxpoolsize"));
// Définition du temps maximum d'attente
Long maxWait = new Long(_configServer
.getString("JDBCWrapper.jdbc.maxwait"));
if (logger.isDebugEnabled()) {
logger
.info(THIS_CLASS
+ "getDataSource() - JDBCWrapper.jdbc.driver = "
+ driver);
logger
.info(THIS_CLASS
+ "getDataSource() - JDBCWrapper.jdbc.user = "
+ user);
logger
.info(THIS_CLASS
+ "getDataSource() - JDBCWrapper.jdbc.password = "
+ pw);
logger
.info(THIS_CLASS
+ "getDataSource() - JDBCWrapper.jdbc.URL = "
+ connectURI);
logger
.info(THIS_CLASS
+ "getDataSource() - JDBCWrapper.jdbc.maxpoolsize = "
+ maxPoolSize);
logger
.info(THIS_CLASS
+ "getDataSource() - JDBCWrapper.jdbc.maxwait = "
+ maxWait);
}
// Positionnement du driver
//Class.forName(driver, true, DriverManagerConnectionFactory.class.getClassLoader());
Class.forName(driver);
if (logger.isDebugEnabled()) {
logger
.info(THIS_CLASS
+ "getDataSource() - Chargement du driver OK");
}
//Création du pool de connexion DBCP avec pour nombre de connexions simultanées
// paramétré à maxPoolSize
ObjectPool connexionPool = new GenericObjectPool(
null,
maxPoolSize.intValue(),
GenericObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION,
maxWait.longValue());
ConnectionFactory connexionFactory = new DriverManagerConnectionFactory(
connectURI, user, pw);
new PoolableConnectionFactory(connexionFactory, connexionPool, null, null, false, true);
// Récupération de la source de données à travers le pool de connexion
ds = new PoolingDataSource(connexionPool);
}
} else {
ds = recupereDataSource();
}
} catch (Exception e) {
throw new JDBCWrapperException(
"Erreur.JDBCWrapper.getDataSource : "
+ e.getMessage(), e);
}
// Ajout du pool de connexion dans la table des DataSources
dataSources.put(_dataSourceName, ds);
}
}
return ds;
}
private DataSource recupereDataSource() throws NamingException {
DataSource ds;
// récupération de la source de donnée
Context initCtx = new InitialContext();
if (logger.isDebugEnabled()) {
logger.info(THIS_CLASS
+ "getDataSource() - initCtx = " + initCtx);
}
ds = (DataSource) initCtx.lookup(_dataSourceName);
return ds;
}
/**
* Récupération de la valeur d'un champ de type Date, resultant d'une
* requête SQL
*
* @param champ nom du champ en String
* @return valeur du champ en objet Date
* @exception JDBCWrapperException Si erreur lors de la lecture du
* resultset, résultat de la requête SQL
*/
public java.util.Date getDate(String champ) throws JDBCWrapperException {
String dateFormat = null;
try {
dateFormat = _configServer.getString("JDBCWrapper.date.type");
} catch (ConfigurationException e) {
dateFormat = JDBCWrapper.TYPE_DATE_TIMESTAMP;
}
try {
// TODO --- A Revoir pour être globaliser sur les datasource;
java.util.Date timestamp = _rset.getTimestamp(champ);
if ((timestamp == null)
|| (JDBCWrapper.TYPE_DATE_TIMESTAMP.equals(dateFormat)))
return timestamp;
else
return new java.util.Date(timestamp.getTime());
} catch (Exception e) {
String message = MessageFormat.format(
"Erreur.JDBCWrapper.LectureChamp", new Object[] { champ });
throw new JDBCWrapperException(message, e);
}
}
/**
* Récupération de la valeur d'un champ de type Date, resultant d'une
* requête SQL
*
* @param index index du champ
* @return valeur du champ
* @exception JDBCWrapperException Si erreur lors de la lecture du
* resultset, résultat de la requête SQL
*/
public java.util.Date getDate(int index) throws JDBCWrapperException {
String dateFormat = null;
try {
dateFormat = _configServer.getString("JDBCWrapper.date.type");
} catch (ConfigurationException e) {
dateFormat = JDBCWrapper.TYPE_DATE_TIMESTAMP;
}
try {
// TODO --- A Revoir pour être globaliser sur les datasource;
java.util.Date timestamp = _rset.getTimestamp(index);
if ((timestamp == null)
|| (JDBCWrapper.TYPE_DATE_TIMESTAMP.equals(dateFormat)))
return timestamp;
else
return new java.util.Date(timestamp.getTime());
} catch (Exception e) {
String message = MessageFormat.format(
"Erreur.JDBCWrapper.LectureChamp",
new Object[] { new Integer(index) });
throw new JDBCWrapperException(message, e);
}
}
/**
* Récupération de la valeur d'un champ de type double, résultant d'une
* requête SQL
*
* @param champ nom du champ
* @return valeur du champ
* @exception JDBCWrapperException Si erreur lors de la lecture du
* resultset, résultat de la requête SQL
*/
public double getDouble(String champ) throws JDBCWrapperException {
try {
return _rset.getDouble(champ);
} catch (Exception e) {
String message = MessageFormat.format(
"Erreur.JDBCWrapper.LectureChamp", new Object[] { champ });
throw new JDBCWrapperException(message, e);
}
}
/**
* Récupération de la valeur d'un champ de type double, resultant d'une
* requête SQL
*
* @param index index du champ
* @return valeur du champ
* @exception JDBCWrapperException Si erreur lors de la lecture du
* resultset, résultat de la requête SQL
*/
public double getDouble(int index) throws JDBCWrapperException {
try {
return _call.getDouble(index);
} catch (Exception e) {
String message = MessageFormat.format(
"Erreur.JDBCWrapper.LectureChamp",
new Object[] { new Integer(index) });
throw new JDBCWrapperException(message, e);
}
}
/**
* Récupération de la valeur d'un champ de type int, résultant d'une requête
* SQL
*
* @param champ nom du champ
* @return valeur du champ
* @exception JDBCWrapperException Si erreur lors de la lecture du
* resultset, résultat de la requête SQL
*/
public int getInt(String champ) throws JDBCWrapperException {
try {
return _rset.getInt(champ);
} catch (Exception e) {
String message = MessageFormat.format(
"Erreur.JDBCWrapper.LectureChamp", new Object[] { champ });
throw new JDBCWrapperException(message, e);
}
}
/**
* Récupération de la valeur d'un champ de type int, resultant d'une requête
* SQL
*
* @param index index du champ
* @return valeur du champ
* @exception JDBCWrapperException Si erreur lors de la lecture du
* resultset, résultat de la requête SQL
*/
public int getInt(int index) throws JDBCWrapperException {
try {
return _call.getInt(index);
} catch (Exception e) {
String message = MessageFormat.format(
"Erreur.JDBCWrapper.LectureChamp",
new Object[] { new Integer(index) });
throw new JDBCWrapperException(message, e);
}
}
/**
* Récupération de la valeur d'un champ de type long, résultant d'une
* requête SQL
*
* @param champ nom du champ
* @return valeur du champ
* @exception JDBCWrapperException Si erreur lors de la lecture du
* resultset, résultat de la requête SQL
*/
public long getLong(String champ) throws JDBCWrapperException {
try {
return _rset.getLong(champ);
} catch (Exception e) {
String message = MessageFormat.format(
"Erreur.JDBCWrapper.LectureChamp", new Object[] { champ });
throw new JDBCWrapperException(message, e);
}
}
/**
* Récupération de la valeur d'un champ de type long, resultant d'une
* requête SQL
*
* @param index index du champ
* @return valeur du champ
* @exception JDBCWrapperException Si erreur lors de la lecture du
* resultset, résultat de la requête SQL
*/
public long getLong(int index) throws JDBCWrapperException {
try {
return _call.getLong(index);
} catch (Exception e) {
String message = MessageFormat.format(
"Erreur.JDBCWrapper.LectureChamp",
new Object[] { new Integer(index) });
throw new JDBCWrapperException(message, e);
}
}
/**
* Récupération de la valeur d'un champ de type Object (par exemple Objet
* Oracle), résultant d'une requête SQL
*
* @param champ nom du champ
* @return valeur du champ
* @exception JDBCWrapperException Si erreur lors de la lecture du
* resultset, résultat de la requête SQL
*/
public Object getObject(String champ) throws JDBCWrapperException {
try {
return _rset.getObject(champ);
} catch (Exception e) {
String message = MessageFormat.format(
"Erreur.JDBCWrapper.LectureChamp", new Object[] { champ });
throw new JDBCWrapperException(message, e);
}
}
/**
* Récupération de la valeur d'un champ de type Object (par exemple Objet
* Oracle), resultant d'une requête SQL
*
* @param index index du champ
* @return valeur du champ
* @exception JDBCWrapperException Si erreur lors de la lecture du
* resultset, résultat de la requête SQL
*/
public Object getObject(int index) throws JDBCWrapperException {
try {
return _call.getObject(index);
} catch (Exception e) {
String message = MessageFormat.format(
"Erreur.JDBCWrapper.LectureChamp",
new Object[] { new Integer(index) });
throw new JDBCWrapperException(message + e.getMessage(), e);
}
}
/**
* Récupération de la valeur d'un champ de type String, résultant d'une
* requête SQL
*
* @param champ nom du champ
* @return valeur du champ
* @exception JDBCWrapperException Si erreur lors de la lecture du
* resultset, résultat de la requête SQL
*/
public String getString(String champ) throws JDBCWrapperException {
try {
return _rset.getString(champ);
} catch (Exception e) {
String message = MessageFormat.format(
"Erreur.JDBCWrapper.LectureChamp", new Object[] { champ });
throw new JDBCWrapperException(message, e);
}
}
/**
* Récupération de la valeur d'un champ de type String, resultant d'une
* requête SQL
*
* @param index index du champ
* @return valeur du champ
* @exception JDBCWrapperException Si erreur lors de la lecture du
* resultset, résultat de la requête SQL
*/
public String getString(int index) throws JDBCWrapperException {
try {
return _call.getString(index);
} catch (Exception e) {
String message = MessageFormat.format(
"Erreur.JDBCWrapper.LectureChamp",
new Object[] { new Integer(index) });
throw new JDBCWrapperException(message, e);
}
}
/**
* Récupération de la valeur d'un champ de type String, résultant d'une
* requête SQL
*
* @param champ nom du champ
* @return valeur du champ
* @exception JDBCWrapperException Si erreur lors de la lecture du
* resultset, résultat de la requête SQL
*/
public String getStringNotNull(String champ) throws JDBCWrapperException {
try {
String stVal = _rset.getString(champ);
if (stVal == null) {
stVal = "";
}
return stVal;
} catch (Exception e) {
String message = MessageFormat.format(
"Erreur.JDBCWrapper.LectureChamp", new Object[] { champ });
throw new JDBCWrapperException(message, e);
}
}
/**
* Récupération de la valeur d'un champ de type String, resultant d'une
* requête SQL
*
* @param index index du champ
* @return valeur du champ
* @exception JDBCWrapperException Si erreur lors de la lecture du
* resultset, résultat de la requête SQL
*/
public String getStringNotNull(int index) throws JDBCWrapperException {
try {
String stVal = _call.getString(index);
if (stVal == null) {
stVal = "";
}
return stVal;
} catch (Exception e) {
String message = MessageFormat.format(
"Erreur.JDBCWrapper.LectureChamp",
new Object[] { new Integer(index) });
throw new JDBCWrapperException(message, e);
}
}
/**
* Récupération d'un flux de données binaires (utilisé pour récupérer les
* images stockées en base)
*
* @param champ nom du champ
* @return valeur du champ
* @exception JDBCWrapperException Si erreur lors de la lecture du
* resultset, résultat de la requête SQL
*/
public InputStream getBinaryStream(String champ)
throws JDBCWrapperException {
try {
return _rset.getBinaryStream(champ);
} catch (Exception e) {
String message = MessageFormat.format(
"Erreur.JDBCWrapper.LectureChamp", new Object[] { champ });
throw new JDBCWrapperException(message, e);
}
}
/**
* Récupération d'un flux de données binaires (utilisé pour récupérer les
* images stockées en base)
*
* @param champ nom du champ
* @return valeur du champ
* @exception JDBCWrapperException Si erreur lors de la lecture du
* resultset, résultat de la requête SQL
*/
public InputStream getBlob(String champ) throws JDBCWrapperException {
try {
return _rset.getBinaryStream(champ);
} catch (Exception e) {
String message = MessageFormat.format(
"Erreur.JDBCWrapper.LectureChamp", new Object[] { champ });
throw new JDBCWrapperException(message, e);
}
}
/**
* Récupération de la valeur d'un champ de type boolean, résultant d'une
* requête SQL
*
* @param champ nom du champ
* @return valeur du champ
* @exception JDBCWrapperException Si erreur lors de la lecture du
* resultset, résultat de la requête SQL
*/
public boolean getBoolean(String champ) throws JDBCWrapperException {
try {
return _rset.getBoolean(champ);
} catch (Exception e) {
String message = MessageFormat.format(
"Erreur.JDBCWrapper.LectureChamp", new Object[] { champ });
throw new JDBCWrapperException(message, e);
}
}
/**
* Récupération de la valeur d'un champ de type boolean, resultant d'une
* requête SQL
*
* @param index index du champ
* @return valeur du champ
* @exception JDBCWrapperException Si erreur lors de la lecture du
* resultset, résultat de la requête SQL
*/
public boolean getBoolean(int index) throws JDBCWrapperException {
try {
return _call.getBoolean(index);
} catch (Exception e) {
String message = MessageFormat.format(
"Erreur.JDBCWrapper.LectureChamp",
new Object[] { new Integer(index) });
throw new JDBCWrapperException(message, e);
}
}
/**
* Récupération de la valeur d'un champ de type BigDecimal, résultant d'une
* requête SQL
*
* @param champ nom du champ
* @return valeur du champ
* @exception JDBCWrapperException Si erreur lors de la lecture du
* resultset, résultat de la requête SQL
*/
public BigDecimal getBigDecimal(String champ) throws JDBCWrapperException {
try {
return _rset.getBigDecimal(champ);
} catch (Exception e) {
String message = MessageFormat.format(
"Erreur.JDBCWrapper.LectureChamp", new Object[] { champ });
throw new JDBCWrapperException(message, e);
}
}
/**
* Récupération de la valeur d'un champ de type BigDecimal, resultant d'une
* requête SQL
*
* @param index index du champ
* @return valeur du champ
* @exception JDBCWrapperException Si erreur lors de la lecture du
* resultset, résultat de la requête SQL
*/
public BigDecimal getBigDecimal(int index) throws JDBCWrapperException {
try {
return _call.getBigDecimal(index);
} catch (Exception e) {
String message = MessageFormat.format(
"Erreur.JDBCWrapper.LectureChamp",
new Object[] { new Integer(index) });
throw new JDBCWrapperException(message, e);
}
}
/**
* Récupération de la valeur d'un champ de type float, résultant d'une
* requête SQL
*
* @param champ nom du champ
* @return valeur du champ
* @exception JDBCWrapperException Si erreur lors de la lecture du
* resultset, résultat de la requête SQL
*/
public float getFloat(String champ) throws JDBCWrapperException {
try {
return _rset.getFloat(champ);
} catch (Exception e) {
String message = MessageFormat.format(
"Erreur.JDBCWrapper.LectureChamp", new Object[] { champ });
throw new JDBCWrapperException(message, e);
}
}
/**
* Récupération de la valeur d'un champ de type float, resultant d'une
* requête SQL
*
* @param index index du champ
* @return valeur du champ
* @exception JDBCWrapperException Si erreur lors de la lecture du
* resultset, résultat de la requête SQL
*/
public float getFloat(int index) throws JDBCWrapperException {
try {
return _call.getFloat(index);
} catch (Exception e) {
String message = MessageFormat.format(
"Erreur.JDBCWrapper.LectureChamp",
new Object[] { new Integer(index) });
throw new JDBCWrapperException(message, e);
}
}
/**
* Récupération de la valeur d'un champ de type short, résultant d'une
* requête SQL
*
* @param champ nom du champ
* @return valeur du champ
* @exception JDBCWrapperException Si erreur lors de la lecture du
* resultset, résultat de la requête SQL
*/
public short getShort(String champ) throws JDBCWrapperException {
try {
return _rset.getShort(champ);
} catch (Exception e) {
String message = MessageFormat.format(
"Erreur.JDBCWrapper.LectureChamp", new Object[] { champ });
throw new JDBCWrapperException(message, e);
}
}
/**
* Récupération de la valeur d'un champ de type short, resultant d'une
* requête SQL
*
* @param index index du champ
* @return valeur du champ
* @exception JDBCWrapperException Si erreur lors de la lecture du
* resultset, résultat de la requête SQL
*/
public short getShort(int index) throws JDBCWrapperException {
try {
return _call.getShort(index);
} catch (Exception e) {
String message = MessageFormat.format(
"Erreur.JDBCWrapper.LectureChamp",
new Object[] { new Integer(index) });
throw new JDBCWrapperException(message, e);
}
}
/**
* Envoie une trace au logger si il est actif
*
* @param sql Requête SQL à envoyer au Logger si il est actif
*/
protected void lobLogger(String sql) {
if (logger.isDebugEnabled()) {
StringBuffer sb = new StringBuffer("([Requête = " + sql + "]");
logger.info(THIS_CLASS + "requête SQL : " + sb);
}
}
/**
* Charge un LOB dans la base MSSQL. Les deux vecteurs d'entrée doivent
* avoir exactement le même nombre d'objet. Ces Objet sont essentiellement
* des String.
*
* @param table nom de la table
* @param cle Vecteur de String contenant l'ensemble des champs nécéssaire a
* la selection de la bonne ligne
* @param valCle Vecteur de String contrnant les valeurs des champs pour la
* selection de la ligne
* @param champ nom du champs LOB
* @param tableau de byte contenant le LOB.
* @param bInsert boolean autorisant ou non l'insert de la ligne contenant
* le blob. Permet d'updater un blob en positionnant sur false.
* @param iTypeLob indique le type du LOB à insérer : TYPE_LOB_CLOB ou
* TYPE_LOB_BLOB
* @return succes ou échec
* @exception JDBCWrapperException Si erreur sur Vector, lors de la lecture
* du resultset, résultat de la requête SQL
*/
public boolean saveMSSQLLob(String table, Vector cle, Vector valCle,
String champ, byte[] data, boolean bInsert, int iTypeLob)
throws JDBCWrapperException {
int ret;
String cle1 = new String("");
String val1 = new String("");
String cleVal = new String("");
Object o;
boolean etatAutoCommit = false;
String empty = new String();
logger
.info(THIS_CLASS
+ "saveMSSQLLob(String ,Vector ,Vector ,String ,byte [],boolean ,int )");
// Vérification de la taille des deux vecteurs
if (cle.size() != valCle.size()) {
String message = MessageFormat
.format(
"Erreur.JDBCWrapper.saveMSSQLLob : Vector de taille différente",
new Object[] { cle, valCle });
throw new JDBCWrapperException(message);
}
// Construction des requêtes avec vérification des paramètres
for (int i = 0; i < cle.size(); i++) {
o = cle.get(i);
if (o.getClass().getName().equals("java.lang.String") == false) {
String message = MessageFormat
.format(
"Erreur.JDBCWrapper.saveMSSQLLob : Vector clé contenant un Objet non String",
new Object[] { o });
throw new JDBCWrapperException(message);
}
cle1 = cle1 + (String) o + ",";
o = valCle.get(i);
if (o.getClass().getName().equals("java.lang.String") == false) {
String message = MessageFormat
.format(
"Erreur.JDBCWrapper.saveMSSQLLob : Vector valeur de clé contenant un Objet non String",
new Object[] { o });
throw new JDBCWrapperException(message);
}
val1 = val1 + (String) o + ",";
cleVal = cleVal + (String) cle.get(i) + "="
+ (String) valCle.get(i);
if (i < cle.size() - 1)
cleVal = cleVal + " AND ";
}
try {
// sauvegarde de l'état de l'autocommit
if (!inTransaction) {
etatAutoCommit = this.is_autoCommit();
this.set_autoCommit(false);
}
if (bInsert) {
// insert de la ligne contenant le blob
String sql1 = new String("INSERT INTO " + table + " (" + cle1
+ champ + ") VALUES (" + val1 + champ + ")");
// Envoie des traces au logger
lobLogger(sql1);
_prep = getConnection().prepareStatement(sql1);
InputStream is = new ByteArrayInputStream(data);
_prep.setBinaryStream(1, is, data.length);
ret = this.execute(sql1, TYPE_REQUETE_UPDATE);
if (ret == 0) {
String message = MessageFormat
.format(
"Erreur.JDBCWrapper.saveMSSQLLob : Impossible d'inserer de la ligne contenant le LOB",
new Object[] { cle, valCle });
throw new JDBCWrapperException(message);
}
} else {
// On reinit le blob avant d'écrire dedans
String sql3 = new String("UPDATE " + table + " SET " + champ
+ "=" + empty + " WHERE " + cleVal);
// Envoie des traces au logger
lobLogger(sql3);
ret = this.execute(sql3, TYPE_REQUETE_UPDATE);
if (ret == 0) {
String message = MessageFormat
.format(
"Erreur.JDBCWrapper.saveMSSQLLob : Impossible d'initialiser le LOB à EMPTY",
new Object[] { cle, valCle });
throw new JDBCWrapperException(message);
}
}
if (!inTransaction) {
this.commit();
// replace l'autocommit dans son état initial
this.set_autoCommit(etatAutoCommit);
}
return true;
} catch (Exception e) {
if (!inTransaction) {
this.rollback();
}
String message = MessageFormat
.format(e.getMessage() + e.getCause()
+ "Erreur.JDBCWrapper.saveMSSQLLob",
new Object[] { champ });
throw new JDBCWrapperException(message, e);
}
}
/**
* Renvoie le Vecteur contenant la liste des parametres OUT et IN_OUT d'une
* procedure stockee.
*
* @return outParamProc Vector liste des parametres OUT et IN_OUT
*/
public Vector getOutParamProc() {
return outParamProc;
}
/**
* Parcours du resultset (résultat d'une requête SQL). Passe à l'élément
* suivant.
*
* @return True s'il y a un élément suivant, false sinon
* @exception JDBCWrapperException Si erreur dans la lecture du resultset,
* résultat de la requête SQL
*/
public boolean next() throws JDBCWrapperException {
try {
return _rset.next();
} catch (Exception e) {
throw new JDBCWrapperException("Erreur.JDBCWrapper.next : "
+ e.getMessage(), e);
}
}
/**
* @return Return the _autoCommit.
*/
public boolean is_autoCommit() {
return _autoCommit;
}
/**
* Contrôle de l'autocommit. Verification si nous somme en transaction. Si
* oui désactivation de cette fonction.
*
* @param commit The _autoCommit to set.
*/
public void set_autoCommit(boolean commit) {
// c'est une transaction?
if (!inTransaction) {
_autoCommit = commit;
}
}
/**
* Controle si le critère formatté est un paramètre à passer à JDBC
*
* @param sCritereFormateSql Critère formatté par la méthode
* @see formaterCritereSQL(String, String)
* @return Indicateur de paramètre
*/
public static boolean isValidCriteria(String sCritereFormateSql) {
boolean bRetour = false;
if (sCritereFormateSql != null && !sCritereFormateSql.equals("")) {
if (sCritereFormateSql.indexOf("=?") != -1) {
bRetour = true;
}
}
return bRetour;
}
/**
* Ajouter un critère à la requête en construction
*
* @param sSql Requête en construction
* @param sSqlCritere Critère formatté à ajouter
* @return Requête mise à jour
*/
public static String addCriteria(String sSql, String sSqlCritere) {
String sRetour = sSql;
if (sSql != null && !sSql.equals("") && sSqlCritere != null
&& !sSqlCritere.equals("")) {
String sMotCle = "WHERE ";
if (sSql.toUpperCase().indexOf(sMotCle) != -1) {
sMotCle = "AND ";
}
sRetour = sSql + " " + sMotCle + sSqlCritere;
}
return sRetour;
}
/**
* Formate un critère pour les requêtes SQL
*
* @param sNomCritere Nom du critère
* @param sValeurCritere Valeur du critère
* @return Element SQL à placer dans le requête
*/
public static String formatCriteria(String sNomCritere,
String sValeurCritere) {
String sCritereFormate = "";
if (sNomCritere != null) {
if (sValeurCritere != null && !sValeurCritere.equals("")) {
// Potitionne le nom du critère
sCritereFormate = " " + sNomCritere;
// Formate le selecteur de valeur
if (sValeurCritere.indexOf("*") != -1) {
sCritereFormate += " like '"
+ sValeurCritere.replace('*', '%') + "'";
} else {
sCritereFormate += " =?";
}
}
}
return sCritereFormate;
}
}