vendredi 4 décembre 2009

oracle dump: import /export BDD

Voici une commande simple pour faire un dump d'une base Oracle ...

Tout d'abord, il faut un sqlplus (PLSQL, TOAD, etc...) installé sur votre PC.

Puis dan sune console sous DOS (ou autre), lancer les commandes suivantes :

Pour un export (Full) :
exp dbapreinteg/bovalo2 file=expBoValo2_091203.dmp log=dump.log full=y consistent=y statistics=none

L'export est full (full=y), les logs se trouvent dasn dump.log, le dump crée est expBoValo2_091203.dmp

Pour un import :
imp dbapreinteg/bovalo2 file=expBoValo2_091203.dmp log=dump.log full=y consistent=y statistics=none

vendredi 20 novembre 2009

oracle PLSQL : creer une procedure stockee avec dbms

voici un petit exemple de procedure stockée sans arguments utilisant dmbs_output ... Attention, il est à noter que le buffer dbms_output a une taille par défaut de 20000 et une taille maximum de 1000000 bytes ...

pour le lancer, se connecter sur le serveur, uploader le script sql, et taper :
sqlplus login/password @extractionDbms.sql >> monExtraction.csv

ou sinon, se connecter en sqlplus, et appeler directement la procédure stockée ... attention à ne pas oublié le backslash \ en fin de procédure ou sous sqlplus ...


rem ****************************************************
rem MISE A JOUR DU SCHEMA
rem script : maj_donnees_test_curseur.sql
rem auteur : Capgemini
rem societe : Capgemini
rem ****************************************************

set serveroutput on
spool extraction_test_curseur.csv

declare
CURSOR ListeWagon (pNumeroCmdBoc number,pVersBoc number) IS
select mat.NO_MAT
from tableWagon mat
where mat.no_cmd_boc = pNumeroCmdBoc
and mat.vers_boc = pVersBoc
and rownum <= 5;

/** declaration du curseur*/
CURSOR ListeResultat IS
SELECT
cbov.no_cmd_boc,
cbov.vers_boc,
cbov.etat,
cbov.no_cmd_def,
(SELECT def.etat FROM tableVersionCommande def WHERE def.no_cmd_def = cbov.no_cmd_def and def.vers_def = cbov.vers_def and def.ind_vcour = 1 and cbov.ind_vcour = 1) as etatDef,
cbov.cmc_lv,
cbov.dh_accept,
cbov.dep_ets_ori,
(select LR2_ETS_FER
FROM vueRef referentiel
WHERE referentiel.ETS_FER = cbov.DEP_ETS_ORI
AND referentiel.RES_FER = cbov.DEP_RES_ORI
AND referentiel.D_DEB_ETS_FER <= (TO_DATE(cbov.DH_ACCEPT, 'DD/MM/YY') + 1)
AND ((referentiel.D_FIN_ETS_FER + 1) >=
(TO_DATE(cbov.DH_ACCEPT, 'DD/MM/YY') + 1)
OR referentiel.D_FIN_ETS_FER IS NULL)
AND ROWNUM = 1) as libelleOri,
cbov.dep_ets_dest,
(select LR2_ETS_FER
FROM vueRef referentiel
WHERE referentiel.ETS_FER = cbov.DEP_ETS_DEST
AND referentiel.RES_FER = cbov.DEP_RES_DEST
AND referentiel.D_DEB_ETS_FER <= (TO_DATE(cbov.DH_ACCEPT, 'DD/MM/YY') + 1)
AND ((referentiel.D_FIN_ETS_FER + 1) >=
(TO_DATE(cbov.DH_ACCEPT, 'DD/MM/YY') + 1)
OR referentiel.D_FIN_ETS_FER IS NULL)
AND ROWNUM = 1) as libelleDest,
cbov.ccl_ref_cli,
cbov.aff_cli_pay_fa,
(SELECT cli.l_cli FROM tableClient cli WHERE cli.cli = cbov.aff_cli_pay_fa AND D_FIN_CLI IS NULL) as libelleFA,
cbov.aff_cli_pay_fna,
(SELECT cli.l_cli FROM tableClient cli WHERE cli.cli = cbov.aff_cli_pay_fna AND D_FIN_CLI IS NULL) as libelleFNA,
(SELECT m.lib_mot_valo FROM tableMoteur m WHERE cbov.mot_valo = m.code_mot_valo) as mot_valo,
cbov.cmc_tarif_app
from tableOrcVersion cbov
where cbov.dh_accept >= TO_DATE('01/01/2009')
and cbov.dh_accept <= TO_DATE(sysdate, 'dd/MM/yy')
and cbov.cmc_lv <= 10000
UNION
SELECT
cbov.no_cmd_boc,
cbov.vers_boc,
cbov.etat,
cbov.no_cmd_def,
NULL,
cbov.cmc_lv,
cbov.dh_accept,
cbov.dep_ets_ori,
(select LR2_ETS_FER
FROM vueRef referentiel
WHERE referentiel.ETS_FER = cbov.DEP_ETS_ORI
AND referentiel.RES_FER = cbov.DEP_RES_ORI
AND referentiel.D_DEB_ETS_FER <= (TO_DATE(cbov.DH_ACCEPT, 'DD/MM/YY') + 1)
AND ((referentiel.D_FIN_ETS_FER + 1) >=
(TO_DATE(cbov.DH_ACCEPT, 'DD/MM/YY') + 1)
OR referentiel.D_FIN_ETS_FER IS NULL)
AND ROWNUM = 1) as libelleOri,
cbov.dep_ets_dest,
(select LR2_ETS_FER
FROM vueRef referentiel
WHERE referentiel.ETS_FER = cbov.DEP_ETS_DEST
AND referentiel.RES_FER = cbov.DEP_RES_DEST
AND referentiel.D_DEB_ETS_FER <= (TO_DATE(cbov.DH_ACCEPT, 'DD/MM/YY') + 1)
AND ((referentiel.D_FIN_ETS_FER + 1) >=
(TO_DATE(cbov.DH_ACCEPT, 'DD/MM/YY') + 1)
OR referentiel.D_FIN_ETS_FER IS NULL)
AND ROWNUM = 1) as libelleDest,
cbov.ccl_ref_cli,
cbov.aff_cli_pay_fa,
(SELECT cli.l_cli FROM tableClient cli WHERE cli.cli = cbov.aff_cli_pay_fa AND D_FIN_CLI IS NULL) as libelleFA,
cbov.aff_cli_pay_fna,
(SELECT cli.l_cli FROM tableClient cli WHERE cli.cli = cbov.aff_cli_pay_fna AND D_FIN_CLI IS NULL) as libelleFNA,
(SELECT m.lib_mot_valo FROM tableMoteur m WHERE cbov.mot_valo = m.code_mot_valo) as mot_valo,
cbov.cmc_tarif_app
from tableHC cbov
where cbov.dh_accept >= TO_DATE('01/01/2009')
and cbov.dh_accept <= TO_DATE(sysdate, 'dd/MM/yy')
and cbov.cmc_lv <= 10000;

/** declaration des variables */
numeroCmdBoc number(8);
versBoc number(2);
etatCmdBoc number(4);
numeroCmdDef number(8);
etatCmdDef number(4);
numeroExpedition number(6);
dateAcceptation date;
etsOri number(6);
libEtsOri varchar2(12);
etsDest number(6);
libEtsDest varchar2(12);
referenceClient varchar2(35);
codePayeurFA number(7);
libellePayeurFA varchar2(32);
codePayeurFNA number(7);
libellePayeurFNA varchar2(32);
numeroMateriel number(12);
moteurValorisation varchar(25);
tarifApplique number(7);

/** liste des wagons */
buffer VARCHAR2(255);
begin
DBMS_OUTPUT.ENABLE(1000000);
dbms_output.put_line('debut extraction');
/** creer des libelles de colonnes */
buffer := 'cmdBOC' || ';' || 'etat' || ';' || 'cmdDEF' || ';' || 'etatCmdDef' || ';' || 'numExp' || ';' || 'dateAccept' || ';' || 'codeEtsOri' || ';' || 'libEtsOri' || ';' || 'codeEtsDest' || ';' || 'libEtsDest' || ';' || 'refClient' || ';' || 'codeCliPFA' || ';' || 'libCliPFA' || ';' || 'codeCliPNFA' || ';' || 'libCliPNFA' || ';' || 'numMat' || ';' || 'motValo' || ';' || 'tarApp' || ';';
dbms_output.put_line(buffer);
/** ouverture du curseur */
Open ListeResultat;

Loop
-- Pour chaque jour sélectionné
Fetch ListeResultat Into numeroCmdBoc,versBoc,etatCmdBoc,numeroCmdDef,etatCmdDef,numeroExpedition,dateAcceptation,etsOri,libEtsOri,etsDest,libEtsDest,referenceClient,codePayeurFA,libellePayeurFA,codePayeurFNA,libellePayeurFNA,moteurValorisation,tarifApplique;
Exit When ListeResultat%NOTFOUND;
-- creer les lignes
Open ListeWagon (numeroCmdBoc,versBoc);
Loop
Fetch ListeWagon Into numeroMateriel;
Exit When ListeWagon%NOTFOUND;
buffer := numeroCmdBoc || ';' || etatCmdBoc || ';' || numeroCmdDef || ';' || etatCmdDef || ';' || numeroExpedition || ';' || dateAcceptation || ';' || etsOri || ';' || libEtsOri || ';' || etsDest || ';' || libEtsDest || ';' || referenceClient || ';' || codePayeurFA || ';' || libellePayeurFA || ';' || codePayeurFNA || ';' || libellePayeurFNA || ';' || numeroMateriel || ';' || moteurValorisation || ';' || tarifApplique || ';';
dbms_output.put_line(buffer);
End Loop;
Close ListeWagon;
End loop ;

/** liberation ressources */
Close ListeResultat ;
dbms_output.put_line('fin extraction');
end;
/
spool off;
/





Un second exemple utilisant une ecriture directe dans un fichier ... Attention, il faut noter qu'il est nécessaire de disposer d'un "directory oracle" configuré par le DBA ... Le fichier se trouvera dans le directory ... (ici nommé EXTRACT et correspond à un chemin sur le filesystem du serveur).


SET SERVEROUTPUT ON;

/** declaration methode extraction */
create or replace procedure extraction is
/** declaration du curseur*/
CURSOR ListeResultat IS
select
vcmd.no_cmd_boc,
vcmd.etat,
vcmd.no_cmd_def,
vcmd.cmc_lv,
vcmd.dh_accept,
vcmd.aff_cli_pay_fa,
(SELECT L_CLI
FROM CLIENT client
where client.cli = vcmd.aff_cli_pay_fa
and client.d_deb_cli <= TO_DATE(sysdate, 'dd/MM/yy')
and (client.d_fin_cli is null or client.d_fin_cli >= TO_DATE(sysdate, 'dd/MM/yy')
) and rownum=1
) as libelleFA,
vcmd.aff_cli_pay_fna,
(SELECT L_CLI
FROM CLIENT client
where client.cli = vcmd.aff_cli_pay_fna
and client.d_deb_cli <= TO_DATE(sysdate, 'dd/MM/yy')
and (client.d_fin_cli is null or client.d_fin_cli >= TO_DATE(sysdate, 'dd/MM/yy')
) and rownum=1
) as libelleFNA,
vcmd.ccl_ref_cli,
wagons.no_mat,
vcmd.mot_valo,
vcmd.cmc_tarif_app,
vcmd.cmc_typ_valo_tarif
from VERSIONCMD vcmd, WAGON wagons
where vcmd.dh_accept >= TO_DATE('01/01/2009')
and vcmd.dh_accept <= TO_DATE(sysdate, 'dd/MM/yy')
and vcmd.cmc_lv <= 10000
and wagons.no_cmd_boc = vcmd.no_cmd_boc and wagons.vers_boc = vcmd.vers_boc;

/** declaration des variables */
numeroCmdBoc number(8);
etatCmdBoc number(4);
numeroCmdDef number(8);
numeroExpedition number(6);
dateAcceptation date;
codePayeurFA number(7);
libellePayeurFA varchar2(32);
codePayeurFNA number(7);
libellePayeurFNA varchar2(32);
referenceClient varchar2(35);
numeroMateriel number(12);
moteurValorisation number(1);
tarifApplique number(7);
typeTarif number(1);

/** fichier de sortie */
file utl_file.file_type;
buffer VARCHAR2(1024);
/** traitement */
begin
/** ouverture fichier dasn le directory */
file := utl_file.fopen('EXTRACT','extraction.csv','W');
/** creer des libelles de colonnes */
buffer := 'n° de commande BOC' || ';' || 'etat de la commande BOC' || ';' || 'n° de commande DEF' || ';' || 'n° d’expédition' || ';' || 'date acceptation' || ';' || 'code client PFA' || ';' || 'libelle client PFA' || ';' || 'code client PNFA' || ';' || 'libelle client PFA' || ';' || 'reference client' || ';' || 'numero materiel' || ';' || 'moteur de valorisation' || ';' || 'tarif applique' || ';' || 'type de tarif';
utl_file.put_line(file,buffer);
/** ouverture du curseur */
Open ListeResultat;

Loop
-- Pour chaque jour sélectionné
Fetch ListeResultat Into numeroCmdBoc,etatCmdBoc,numeroCmdDef,numeroExpedition,dateAcceptation,codePayeurFA,libellePayeurFA,codePayeurFNA,libellePayeurFNA,referenceClient,numeroMateriel,moteurValorisation,tarifApplique,typeTarif;
Exit When ListeResultat%NOTFOUND;
-- creer les lignes

buffer := numeroCmdBoc || ';' || etatCmdBoc || ';' || numeroCmdDef || ';' || numeroExpedition || ';' || dateAcceptation || ';' || codePayeurFA || ';' || libellePayeurFA || ';' || codePayeurFNA || ';' || libellePayeurFNA || ';' || referenceClient || ';' || numeroMateriel || ';' || moteurValorisation || ';' || tarifApplique || ';' || typeTarif;
utl_file.put_line(file,buffer);
End loop ;

/** liberation ressources */
Close ListeResultat ;
utl_file.fclose(file);
end extraction;

vendredi 13 novembre 2009

unix : remplacement de chaine avec sed ou sous vi

Pour remplacer une occurence d'une chaine un peu partout dans un fichier (ici myfile.txt) :

il est possible d'utiliser la commande sed :

ici la première occurence trouvée dans le fichier myfile.txt de 'chaineDepart' sera remplacée par 'nouvelleChaine', et le resultats sera affiché dans stdout...
sed -e 's/chaineDepart/nouvelleChaine/' myfile.txt

ici toute les occurences trouvées dans myfile.txt sont remplacées et le tout est redirigé vers le fichier myfile_new.txt
sed -e 's/chaineDepart/nouvelleChaine/g' myfile.txt > myfile_new.txt

ici, la même chose mais de la ligne 2 à 10 incluses ...
sed -e '2,10s/chaineDepart/nouvelleChaine/g' myfile.txt > myfile_new.txt

ici, un très bonne article ...

il est possible d'utiliser sous vim :
ici toute les occurences trouvées dans le fichier edité sont remplacées :%s/texte_à_trouver/nouveau_texte/g


ici, un très bonne article ...

jeudi 12 novembre 2009

putty : créer un tunnel ...

J'ai besoin d'accéder a un port particulier auquel je n'ai pas accès directement, mais auquel une autre machine a accès ... Dans mon cas, je veux accéder à une console weblogic situé sur mon serveur "cible" sur le port 7001, et je n'ai qu'accès à un autre serveur "dit accessible" (qui lui a accès au serveur de cible et au port 7001) ...

Il faut donc que je crée un tunnel ssh ... avec putty ...
1) configurer putty :



Tout d'abord on se rend sur la rubrique Tunnels de putty ...
ici, on voit que ds source port, je mets mon PC en local 127.0.0.2:11151
et que je mets dans destination port le serveur et le port cible : 10.14.51.139:11151
et ne pas oublier d'appuyer sur "add"

A noter qu'il faut faire attention aux translation d'adresse IP (ici l'adresse IP, il faut mettre l'adresse IP du serveur "cible" vu par le serveur "accèdé"


2) Se connecter au serveur accessible via ssh ... le tunnel est fait ...

3) Le tunnel est fait, maintenant je lance mon browser sur http://localhost:11151/console ... et c'est magique j'obtient le display de la console weblogic !!!

vendredi 6 novembre 2009

linux : afficher l'espace disque utilisé ou la taille de repertoire

La commande df affiche l'ensemble des points de montage et l'espace occupé, et l'option -h permet un affichage "human readable" :

df -h

La commande du affiche l'ensemble des points de montage et l'espace occupé, et l'option -h permet un affichage "human readable" :

du -h --max-depth=1

mardi 3 novembre 2009

linux : trouver un process qui utilise un port

la commande netstat -ap permet d'afficher les port et n° de PID qui utlise le port ... le grep fait un filtre ...
netstat -ap | grep 7670

mercredi 28 octobre 2009

weblogic : installation d'un domain ... via config.sh ...

Voici le configuration wizard en ligne de commande :

Tapez: ./config.sh –mode=console
Ensuite il suffit de répondre aux questions posées par le script ... A noter qu'il est possible de l'utiliser sous Linux/Unix et Windows ...


Il existe le mode silencieux :

./config.sh -mode=silent -silent_script=MonScript.txt

Un exemple de script se trouve dans l'installe de bea ${BEA_HOME}\weblogic81\common\templates\silent_scripts\domain_wls.txt ...

Une syntaxe particulière et relativement simple existe pour ce type de script ...


//This is an example of a Configuration Wizard silent script. This example uses the
// Basic WebLogic Server Domain template to show how to open, modify, and write out
// a domain in silent mode. Please note that many values used in this script are subject
// to change based on your WebLogic installation and the template you are using.
//
// Usage:
// = config.cmd -mode=silent -silent_script=
// = ./config.sh -mode=silent -silent_script=
//
// Where:
// should be the full path to the silent script.
/////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////////
//Read in a domain template.
/////////////////////////////////////////////////////////////////////////////////////////
read template from
"D:\bea\weblogic81/common/templates/domains/wls.jar";

/////////////////////////////////////////////////////////////////////////////////////////
//Find and configure the Admin Server.
/////////////////////////////////////////////////////////////////////////////////////////
find Server "myserver" as s1;
set s1.ListenAddress "";
set s1.ListenPort "7001";
set s1.SSL.Enabled "true";
set s1.SSL.ListenPort "7002";

/////////////////////////////////////////////////////////////////////////////////////////
//Create a JMSQueue.
/////////////////////////////////////////////////////////////////////////////////////////
//A JMSServer has to be created first.
create JMSServer "myJMSServer" as jmsserver;
create JMSQueue "myJMSQueue" as myq;
//required attribute
set myq.JNDIName "jms/myjmsqueue";
//required attribute
set myq.JMSServer "myJMSServer";
//optional attribute
//set myq.StoreEnabled "false";
//target "myJMSServer" to server "myserver"
assign JMSServer "myJMSServer" to target "myserver";

/////////////////////////////////////////////////////////////////////////////////////////
//Create a JDBCConnectionPool.
/////////////////////////////////////////////////////////////////////////////////////////
create JDBCConnectionPool "demoPool" as mypool;
//required attribute
set mypool.DriverName "com.pointbase.jdbc.jdbcUniversalDriver";
//required attribute
set mypool.URL "jdbc:pointbase:server://localhost:9092/demo";
//required attribute
set mypool.Password "PBPUBLIC";
//optional attribute (but it's recommended you set the db user...)
set mypool.Properties "user=PBPUBLIC";
//target all JDBC connection pools to server "myserver"
assign JDBCConnectionPool "*" to target "myserver";

/////////////////////////////////////////////////////////////////////////////////////////
//target existing applications.
/////////////////////////////////////////////////////////////////////////////////////////
//target applications only when they exist in current domain template
//assign application "*" to target "myserver";

/////////////////////////////////////////////////////////////////////////////////////////
//Create the admin user and password.
/////////////////////////////////////////////////////////////////////////////////////////
find User "weblogic" as u1;
set u1.password "weblogic";

/////////////////////////////////////////////////////////////////////////////////////////
//Write out the domain.
/////////////////////////////////////////////////////////////////////////////////////////
set OverwriteDomain "true";
write domain to "D:\bea/user_projects/domains/wls";

/////////////////////////////////////////////////////////////////////////////////////////
//Close domain template to indicate completion of work.
/////////////////////////////////////////////////////////////////////////////////////////
close template;



Un article très complet se trouve ici

unix : lancer des scripts automatique via crontab

Voici, un petit extrait de wikipedia .... Evidemment, il faut les droits unix adequates ...

Rappel des commandes utiles:
crontab -l (liste des commandes crotab)

crontab -e (edition de la crontab via vi)

crontab -r (supprime la crontab via vi)

Imaginons que l'on veuille faire un journal (dans le fichier /tmp/log_df.txt par exemple) automatisé de l'espace disque libre (commande df) à des intervalles de temps précis :

* Tous les jours à 23h30 :

30 23 * * * df >>/tmp/log_df.txt

* Toutes les heures, passées de 5 minutes :

5 * * * * df >>/tmp/log_df.txt

* Tous les premiers du mois à 23h30 :

30 23 1 * * df >>/tmp/log_df.txt

mardi 27 octobre 2009

java : MAJ CLOB oracle

voici un petit exemple crad ... de code pour update un CLOB sous oracle


/**
*
*/
package com.valo.test;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Writer;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import oracle.jdbc.OracleConnection;
import oracle.jdbc.pool.OracleDataSource;
import oracle.sql.CLOB;

public class ClobUpdater {

private static final String DB_ID = "jdbc:oracle:thin:@unServeur:1234:MaBase";
private static final String DB_USER = "TOTO";
private static final String DB_USER_PWD = "TITI";
private static String file1 ="D:/Tmp/ToutManuel.txt" ;
private static int ID1 = 42004618;
private static String file2 ="D:/Tmp/ToutManuel2.txt" ;
private static int ID2 = 42004619;


/**
* @param args
*/
public static void main(String[] args) {
ClobUpdater updater = new ClobUpdater();
updater.updateFromFile(ID1, file1);
updater.updateFromFile(ID2, file2);
}

public void updateFromFile(int ID, String filenameURL){

File fichierALire = new File(filenameURL);
BufferedReader reader = null;
OracleDataSource ods;
OracleConnection c = null;

try {
ods = new OracleDataSource();
ods.setURL(DB_ID);
ods.setUser(DB_USER);
ods.setPassword(DB_USER_PWD);
c = (OracleConnection) ods.getConnection();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}

try {
reader = new BufferedReader(new FileReader(fichierALire));
char [] buffer = new char[1024 * 8];
int lus = 0;
StringBuffer strBuffer = new StringBuffer();
String strLus = null;

while((lus = reader.read(buffer)) != -1)
{
strLus = new String(buffer,0,lus);
System.out.println("lus = " + strLus);
strBuffer.append(strLus);
}

// lecture termine
CLOB tmpCLOB = CLOB.createTemporary(c,true,CLOB.DURATION_SESSION);
Writer w1 = tmpCLOB.getCharacterOutputStream();
String chaineAEcrire = strBuffer.toString();
w1.write(chaineAEcrire);
w1.close();

String sqlUpdate = "UPDATE uneTable SET uneColonne = ? WHERE ID = ?";
PreparedStatement st = c.prepareStatement(sqlUpdate);
st.setClob(1,tmpCLOB);
st.setInt(2,ID);
int nbMaj = st.executeUpdate();
System.out.println("nb MAJ = " + nbMaj);
c.commit();
st.close();
c.close();

} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
if(c!= null)
{
try {
c.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

}

lundi 26 octobre 2009

unix : recherche de fichiers de grande taille

Voici une commande qui peut vous être utile :

Vérifier l’espace disque sur le serveur en vous connectant avec le user associé
Tout d’abord , lancer :
df –k

puis si les point de montage /devel ou /orcle sont proche des 100% … lancer ce type de commande pour les logs :

find /root/bo/ -name "*.log" -size +1000k -ctime +3 -exec rm {} \;

Attention, cette commande nettoie tout les fichiers *.log de plus de 3 jours et de taille > 1000k … dans le répertoire /root/bo/

java : export excel et flux a telecharger

Voici un petit code permettant de realiser un export Excel et de le recevoir par une servlet ... Cet exemple s'appuie sur la librairie POI d'apache :


public void exportExcelCsa(ArrayList pTitreColonne, ArrayList pIndiceColonne, ArrayList pListe,
HttpServletResponse pReponseHttp, final boolean pTest, final String pNomFichier) throws FretOrchestreException {

// creation d'un classeur
final HSSFWorkbook vClasseurExcel = new HSSFWorkbook();
// creation des styles
// police des titres
final HSSFFont vFontHeader = vClasseurExcel.createFont();
vFontHeader.setFontHeightInPoints((short) 10);
vFontHeader.setFontName("Times New Roman");
vFontHeader.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
vFontHeader.setColor(HSSFColor.WHITE.index);
// style des cellules de titres
final HSSFCellStyle vStyleTitreColonne = vClasseurExcel.createCellStyle();
vStyleTitreColonne.setFillForegroundColor(HSSFColor.SEA_GREEN.index);
vStyleTitreColonne.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
vStyleTitreColonne.setFont(vFontHeader);
vStyleTitreColonne.setBorderBottom(HSSFCellStyle.BORDER_THIN);
vStyleTitreColonne.setBottomBorderColor(HSSFColor.BLACK.index);
vStyleTitreColonne.setBorderLeft(HSSFCellStyle.BORDER_THIN);
vStyleTitreColonne.setLeftBorderColor(HSSFColor.BLACK.index);
vStyleTitreColonne.setBorderRight(HSSFCellStyle.BORDER_THIN);
vStyleTitreColonne.setRightBorderColor(HSSFColor.BLACK.index);
vStyleTitreColonne.setBorderTop(HSSFCellStyle.BORDER_THIN);
vStyleTitreColonne.setTopBorderColor(HSSFColor.BLACK.index);
vStyleTitreColonne.setAlignment(HSSFCellStyle.ALIGN_CENTER);
vStyleTitreColonne.setWrapText(true);
// police des données
final HSSFFont vFont = vClasseurExcel.createFont();
vFont.setFontHeightInPoints((short) 10);
vFont.setFontName("Times New Roman");
// style des cellules de données
final HSSFCellStyle vStyleDonnees = vClasseurExcel.createCellStyle();
vStyleDonnees.setBorderBottom(HSSFCellStyle.BORDER_THIN);
vStyleDonnees.setBottomBorderColor(HSSFColor.BLACK.index);
vStyleDonnees.setBorderLeft(HSSFCellStyle.BORDER_THIN);
vStyleDonnees.setLeftBorderColor(HSSFColor.BLACK.index);
vStyleDonnees.setBorderRight(HSSFCellStyle.BORDER_THIN);
vStyleDonnees.setRightBorderColor(HSSFColor.BLACK.index);
vStyleDonnees.setBorderTop(HSSFCellStyle.BORDER_THIN);
vStyleDonnees.setTopBorderColor(HSSFColor.BLACK.index);
vStyleDonnees.setFont(vFont);
vStyleDonnees.setAlignment(HSSFCellStyle.ALIGN_LEFT);

/* creation de l'onglet Recherche */
final String vTitre = "Recherche";
final HSSFSheet vOnglet = vClasseurExcel.createSheet(vTitre);
//genererEnTeteEtPiedDePage(vTitre, vOnglet, true);

/* Titre des colonnes. */
creerLigneTitre(vOnglet, pTitreColonne, vStyleTitreColonne);

/* Contenu de la liste pour la version retraitée. */
creerContenuFretListe(vOnglet, pListe, pIndiceColonne, vStyleDonnees);

/* Génération en tete et pied de page. */
final HSSFHeader vEnTete = vOnglet.getHeader();
vEnTete.setLeft("Commandes en saisie");

final HSSFFooter vPiedDePage = vOnglet.getFooter();
final SimpleDateFormat vSimpleDateFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm");
vPiedDePage.setLeft(vSimpleDateFormat.format(new Date()));
vPiedDePage.setRight(HSSFFooter.page() + " / " + HSSFFooter.numPages());

OutputStream vOutput = null;
try {
// flux de sortie
if (pTest) {
final FileOutputStream vFileOut = new FileOutputStream("c:\\" + pNomFichier + ".xls");
vClasseurExcel.write(vFileOut);
vFileOut.close();
} else {
vOutput = pReponseHttp.getOutputStream();
pReponseHttp.setContentType("application/vnd.ms-excel");
pReponseHttp.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
pReponseHttp.setHeader("Pragma", "public");
pReponseHttp.setDateHeader("Expires", 0);
pReponseHttp.setHeader("Content-disposition", "attachment;filename=\"" + pNomFichier + ".xls\"");
pReponseHttp.setStatus(HttpServletResponse.SC_OK);

vClasseurExcel.write(vOutput);
}
} catch (Exception vExc) {
sLog.error("Echec d'enregistrement du fichier généré (échec d'écriture, répértoire inconnu,...)" + vExc.getMessage());
} finally {
//fermeture du flux
try {
if (vOutput != null) {
vOutput.close();
}
} catch (IOException vIoExce) {
sLog.error("Echec d'enregistrement du fichier généré (échec d'écriture, répertoire inconnu,...)" + vIoExce.getMessage());
}
}
}

vendredi 23 octobre 2009

putty : exporter et importer rapidement la configuration de putty

Pour l'export de configuration, il suffit d'exporter la clé de registre suivante, via la commande ms-dos :

regedit /e putty.reg HKEY_CURRENT_USER/Software/SimonTatham/PuTTY/Sessions


Pour l'import de configuration, il suffit d'importer la clé de registre suivante, via la commande ms-dos :

regedit /s putty.reg

Il est aussi possible de le faire via l'ihm de regedit

jeudi 8 octobre 2009

oracle : trouver si des tables, vues ou objets divers existent ...


Une question qui se pose souvent est de savoir si un objet, une table, une vue, un synonyme est présent ou non dans une base ...

Voici une petite requête utile :

select * from dba_objects where object_name like 'VBORFMRPA'



et voila ... on peut voir si le synonyme existe par exemple et qui en est le propriétaire ... Voilou ..

lundi 5 octobre 2009

java : générer des daigrammes de séquences avec jtracert

Il s'agit d'un outil qui instrumente la JVM (1.5 ou > ) lors de son fonctionnement. Pour cela, il suffit de télécharger jtracert et installer le GUI. Une fois cette opération terminée, vous n'avez qu'a rajouter les paramètres de lancement suivant à la ligne de commande :

-javaagent:D:\MesDocs\mySoft\jtrace\jTracert.jar=7007

Vous lancer alors le GUI et cliquer sur le noeud package ...



Ceci va vous permettre de visualiser le digramme. Un filtrage sur les classe est possible, ainsi que la sélection du répertoire d'export des diagrammes ...



Ceci fonctionne aussi pour les applications J2EE. il suffit d'ajouter cette ligne à catalinat.bat pour tomcat :

set JAVA_OPTS=-DanalyzerOutput=sdEditRtClient -DsdEditHost=127.0.0.1 -DsdEditPort=60001 -javaagent:"chemin librairie"\jTracert.jar=7007 %JAVA_OPTS%

A noter, que je n'ai pas eu le temps de tester ce programme avec tomcat ... Cet outil semble bien fonctionner et permet une analyse rapide du code ...

jeudi 1 octobre 2009

selenium : les utiliser en junit

Voici un petit exemple, de script enregistrer sous Selenium IDE, puis exporter en junit ...

Après c'est simple, il suffit d'exporter l'ensemble en junit, de créer un projet sous eclipse, en ajoutant une jre > 1.5 et télécharger le serveur selenium Remote Control.

Ce dernier nous fournira le serveur , et un jar client pour lancer les commandes selenium à notre browser (selenium-java-client-driver.jar).

Avant de lancer un test unitaire, il faut avoir lancer le serveur par une commande du type :
"C:\Program Files\Java\jre1.6.0_05\bin\java.exe" -jar selenium-server.jar

Et ensuite voici, la classe obtenue après export ... d'un test enregistrer sous Firefox avec Selenium IDE. A noter que ce dernier sera executé sous IE ...





import com.thoughtworks.selenium.*;
import java.util.regex.Pattern;

public class TestBoc extends SeleneseTestCase {
public void setUp() throws Exception {
// setUp("http://change-this-to-the-site-you-are-testing/", "*chrome");
setUp("http://change-this-to-the-site-you-are-testing/", "*iexplore");
}

public void testBoc() throws Exception {
selenium.open("http://www.yahoo.fr");
selenium.type("login", "toto");
selenium.type("password", "titi");
selenium.select("module", "label=Orchestre");
selenium.click("link=Valider");
selenium.waitForPageToLoad("30000");
selenium.click("brechercher");
selenium.waitForPageToLoad("30000");
for (int second = 0;; second++) {
if (second >= 60) fail("timeout");
try { if ("24903".equals(selenium.getText("//tr[@id='l1']/td[2]"))) break; } catch (Exception e) {}
Thread.sleep(1000);
}

verifyTrue(selenium.isTextPresent("24903"));
selenium.click("link=D\u233connexion");
}
}

java : regexp

Les regexp sont très utile pour les traitements complexes sur les chaines (par ex.: recherche, remplacement).

Voici un petit exemple de regexp qui recherche des mots du type :
\b((Req)*(Int((Min\d+)*)(Max\d+)*))\b

Ce dernier va trouver la chaine en gras .. et pas une autre ... On notera que les \b sont les frontières des mots ... et les * (0 ou plusieurs) sont des indicateurs optionnels ... les + sont 1 ou plus ...

helolo ca marche super ReqIntMin200Max300 eReqIntMin200Max300

voici des regexp utiles (trouve sur cette très bonne page ):

un nom d'utilisateur
/[a-zA-Z0-9_]{3,16}/

trouver un tag XML/XHTML
{<tag[^>]*>(.*?)</tag>}

trouver un tag XML/XHTML avec une valeur particulière
{<tag[^>]*attribute\\s*=\\s*(["'])value\\\\1[^>]*>(.*?)</tag>}

vendredi 25 septembre 2009

javascript : loggin avec blackbird



Blackbird est une librairie très utile permettant de logger sous javascript dans une console externe, et fonctionnant sous IE6 + ... et la plupart des autres navigateurs:

Pour mettre en place, le système il faut télécharger la librairie, et y faire référence dans la page html. Voici, un petit exemple ... A noter, que des raccourcis permette d'afficher ou non la console (F2) , de filtrer les messages, et aussi de profiler les fonctions en utilisant une etiquettes.


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
<script type="text/javascript" src="../js/blackbird.js" ></script>
<link type="text/css" rel="Stylesheet" href="../js/blackbird.css" ></link>
</head>
<body>
<script type="text/javascript" language="javascript">
function testLog()
{
log.profile('testLog');
log.debug(new Date());
log.info(new Date());
log.error('erreur');
log.profile('testLog');
}
</script>
<h3>ceci est un test blackbird</h3>
<a href="javascript:testLog()">testLog</a>
</body>
</html>



et voila .. il est possible de logger simplement et elegamment

java : monitorer une application java avec jconsole


Tout d'abord, il faut une application java 1.5 ou supérieure, et aussi un jdk (qui contient l'utilitaire jconsole).

Ensuite, il faut ajouter les paramètres suivant pour demander à la VM de monitorer l'application avec les interfaces MBeans :



-Dcom.sun.management.jmxremote.port=5555
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false


Voici un exemple de la ligne de lancement :

"C:\Program Files\Java\jre1.6.0_05\bin\javaw.exe" -agentlib:jdwp=transport=dt_socket,suspend=y,address=localhost:3113 -Dcom.sun.management.jmxremote.port=5555 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dfile.encoding=Cp1252 -classpath D:\Projets\workspaceBOC\testsDivers\bin testSimpleDateFormat

ensuite, lancer la jconsole et la paramètrer pour écouter sur le port choisi (ici en local)

JDK_HOME/bin/jconsole

et voilà, c'est fini ... la console vous permet de suivre pas mal de chose (mémoire, thread, gc ... )

jeudi 24 septembre 2009

java / J2EE: diagnostiquer un problème de performance ...

Ceci est un extrait du site http://blog.ippon.fr/tag/introscope



Récemment en mission chez un acteur majeur du marché de l'énergie français, j'ai été confronté à un problème de performance sur l'un de leurs portails Web. Le symptôme était le suivant : lors de montées en charge, sur l'environnement de production, les temps de génération de certaines pages s'accroissaient dramatiquement (jusqu'à 12 secondes). Brièvement, les composants techniques constituant le portail sont les suivants :

* un cluster de trois serveurs Apache,
* un cluster de trois serveurs Weblogic Portal 8.1sp5,
* un cluster .de trois serveurs Weblogic Integration 8.1sp5,
* un connecteur iWay Adapter for SAP 5.5.006.R2, de iWay Software, installé sur chaque instance WLI,
* SAP,
* Oracle 9i.

L'environnement de production était dépourvu d'outil de diagnostic et aucun message d'erreur suspect n'apaisait dans les différents fichiers de traces.

Premiers réflexes :

* Vérifier la charge des processeurs des serveurs Solaris. La charge des CPU était très faible.
* Vérifier les accès aux entrées/sorties. Le volume de données lues et écrites était très faible ainsi que le nombre d'accès aux disques et aux réseaux.
* Vérifier l'activité du ramasse-miettes des différentes JVM depuis les consoles d'administration Weblogic. Rien à signaler.

Nous pouvions exclure les erreurs de programmation entraînant des surconsommations de CPU et d'I/O, les boucles infinies, et les fuites-mémoires de l'ensemble de nos hypothèses. Le ralentissement semblait être lié à un problème d'accès à une ressource critique tels que un pool JDBC, un pool de threads ou un bloc synchronisé.

Deuxièmes réflexes :

* contrôler le nombre et l'activité des threads au travers des consoles Weblogic,
* générer un "Thread Dump" en lançant un signal SIGQUIT ("kill -3" sous Unix ou "Control+Pause" sous Windows) à destination des processus exécutant les JVMs. Pour rappel, cette opération ne termine pas l'exécution des JVMs. Lorsqu'une JVM reçoit ce signal, elle suspend momentanément l'exécution de toutes ses threads, génère une trace d'exécution ("stack trace") pour chacune d'elles, puis les réactivent.

L'outil idéal pour analyser un "Thread Dump" est ... "Thread Dump Analyzer". Il s'agit une application gratuite disponible à l'adresse : http://tda.dev.java.net

Premier constat : près de la moitié des threads des serveurs WLI étaient en attentent sur le même bloc synchronisé. Le point de contention était localisé dans la méthode "debug" appartenant à la classe "LoggerDecorator" du connecteur iWay.

Pour aller plus en avant dans nos investigations, nous avons installé le produit Introscope de CA | Wily Technology sur les serveurs WLI de l'environnement de qualification, puis nous avons généré du trafic afin de reproduire l'anomalie. Introscope est un outil de supervision et de diagnostic permettant de suivre l'activité de tous les composants sollicités durant une transaction, sur plusieurs serveurs. Son faible surcoût en ressource machine permet de le déployer sur des environnements de production.

Deuxième constat : 92% du temps de production des pages du portail était consommé par le mécanisme de trace (log) du connecteur SAP !!

Ne disposant pas des sources du connecteur iWay pour le corriger, un cas a été ouvert auprès de BEA Systems.

En conclusion,

1. TDA nous a permis de cerner la source du problème. Ce petit outil gratuit doit faire parti de votre trousse de secours.
2. Instroscope nous a permis d'identifier la méthode générant les ralentissements et de mesurer leurs importances. Cet outil nous a également permis de corréler les ralentissements avec les accès simultanés à la classe de trace en superposant la courbe des temps de réponse de la méthode incriminée et la courbe du nombre des accès à la méthode. Il s'agit d'un produit évolué permettant de superviser des applications complexes en production et de diagnostiquer rapidement les sources d'une anomalie.

mercredi 16 septembre 2009

java : créer une clé de hashage unique ...

Il est parfois utile de créer une valeur de hash, pour signer un fichier, ou crypter un mot de passe en base ... Pour cela , java propose une classe simple à utiliser, et tout une gamme d'algorithme (SHA1, MD-5, SHA-256,etc...) ...

1-Tout d'abord, on initialise le SecureRandom
SecureRandom prng = SecureRandom.getInstance("SHA1PRNG");

2-on obtient une instance de MessageDigester avec l'algo choisi.

//get its digest
MessageDigest sha = MessageDigest.getInstance("SHA-1");


3-encrypter une chaine quelconque, et récuperer le tableau de byte
byte[] result = sha.digest( randomNum.getBytes() );


4-Voici, un exemple complet (mais jamais testé), qui montre un bel affichage en hexa :


import java.security.SecureRandom;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class GenerateId {

public static void main (String... arguments) {
try {
//Initialize SecureRandom
//This is a lengthy operation, to be done only upon
//initialization of the application
SecureRandom prng = SecureRandom.getInstance("SHA1PRNG");

//generate a random number
String randomNum = new Integer( prng.nextInt() ).toString();

//get its digest
MessageDigest sha = MessageDigest.getInstance("SHA-1");
byte[] result = sha.digest( randomNum.getBytes() );

System.out.println("Random number: " + randomNum);
System.out.println("Message digest: " + hexEncode(result) );
}
catch ( NoSuchAlgorithmException ex ) {
System.err.println(ex);
}
}

/**
* The byte[] returned by MessageDigest does not have a nice
* textual representation, so some form of encoding is usually performed.
*
* This implementation follows the example of David Flanagan's book
* "Java In A Nutshell", and converts a byte array into a String
* of hex characters.
*
* Another popular alternative is to use a "Base64" encoding.
*/
static private String hexEncode( byte[] aInput){
StringBuilder result = new StringBuilder();
char[] digits = {'0', '1', '2', '3', '4','5','6','7','8','9','a','b','c','d','e','f'};
for ( int idx = 0; idx < aInput.length; ++idx) {
byte b = aInput[idx];
result.append( digits[ (b&0xf0) >> 4 ] );
result.append( digits[ b&0x0f] );
}
return result.toString();
}
}

java : générer un UUID

Comment générer simplement un numéro unique ... La classe UUID (à partir de java 1.5) ... Voici un exemple simple :


import java.util.UUID;

public class TestGUID {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(UUID.randomUUID().toString());
System.out.println(UUID.randomUUID().toString());
}

}

lundi 14 septembre 2009

java : faire des transferts ftp

Il est parfois utile de réaliser des transfert de fichiers, d'un serveur à un autre. Notamment pour des exports diverses et variés. Outre le fait de les réaliser en shell script, il est possible de les réaliser en java en utilisant la librairies apache (commons-net).

Etape 1 :Comme c'est assez simple et classique (connexion, login, configuration du mode) je mets directement un extrait du code ...


// on doit se connecter en FTP /users/toto/build/
ftpClient = new FTPClient();

try {
ftpClient.connect(host, Integer.valueOf(port));
ftpClient.login(username, password);
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
// Use passive mode as default because most of us are
// behind firewalls these days.
ftpClient.enterLocalPassiveMode();
ftpClient
.addProtocolCommandListener(new PrintCommandListener(
new PrintWriter(System.out)));

} catch (NumberFormatException e) {
e.printStackTrace();
System.exit(-1);
} catch (SocketException e) {
e.printStackTrace();
System.exit(-1);
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}

Etape 2 :une fonction de copie (un appel a la méthode storeFile):


private static void copyFtpFile(String srcDirValue, String dstDirValue,
String fileName, FTPClient ftpClient) throws IOException {
FileInputStream local = new FileInputStream(srcDirValue + "/"
+ fileName);

String remote = dstDirValue + fileName;
remote = remote.replaceAll("\\\\", "/");

if (ftpClient.storeFile(remote, local)) {
/**
* -s D:\ArchCvs\BC\src -d D:\ArchCvs\V1-9-v1-patch\src -c
* D:\MesDocs\myProjet\listeFichiers.txt -f
* 192.168.161.16:21:dev:dev
*/
System.out.println("copy file [" + local.getFD().toString()
+ "] to [" + remote + "]");
} else {
System.err.println("erreur copy file [" + local + "] to [" + remote
+ "]");
}
local.close();

}



Le transfert est terminé ...

vendredi 11 septembre 2009

java : JNI ....

JNI (Java Native Interface) permet d'appeler des fonctions natives tel que du C/C++. Voici la marche à suivre :

1- tout d'abord, il faut créer une classe java qui comporte des méthodes natives ... et utiliser l'outil de SUN javah qui va générer un header C pour les méthodes natives ...

Voici un exemple de classe :


package com.jni;

public class JNITest {

// chargement de la librairie
static
{
System.loadLibrary("nativeLib");
}

public native String concat(String s2,String s1);

public native long testLong(long valeur);
/**
* @param args
*/
public static void main(String[] args)
{
System.out.println("debut test JNI");
JNITest obj = new JNITest();
String result = obj.concat("abc","def");
System.out.println("valeur retournee = [" + result + "]");

long valeur = -1;
valeur = obj.testLong(0);
System.out.println("long retourne = [" + valeur + "]");
System.out.println("fin test JNI");
}
}


lancer javah et ajouter le chemin vers le fichier .class

C:\Program Files\Java\j2sdk1.4.2_08\bin\javah.exe D:\Projets\workspace_bc\testJNI\bin\com.ldu.JNITest

A noter, que dans cette classe, il faut charger en static la librairie générée (dll ou .so selon la plateforme)


static
{
System.loadLibrary("nativeLib");
}


2-Si tout s'est bien passé alors, un fichier header (*.h) a été généré. Il suffit maintenant d'implémenter les méthodes avec un fichier *.c ou *.cpp (Attention dans le cas du C++, il faut encadred les méthodes par un extern c,car en fait ce sont des fonctions c et les nom ne doivent pas être décorés ...

Voici, l'exemple d'implémentation des méthodes c

/* ========================================================================== */
/* */
/* Filename.c */
/* (c) 2001 Author */
/* */
/* Description */
/* */
/* ========================================================================== */
#include
#include
#include "com_ldu_JNITest.h"

JNIEXPORT jstring JNICALL Java_com_ldu_JNITest_concat
(JNIEnv * env, jobject obj, jstring chaine1, jstring chaine2)
{
char resultat[256];
const char *str1 = (*env)->GetStringUTFChars(env, chaine1, 0);
const char *str2 = (*env)->GetStringUTFChars(env, chaine2, 0);
sprintf(resultat,"%s%s", str1, str2);
(*env)->ReleaseStringUTFChars(env, chaine1, str1);
(*env)->ReleaseStringUTFChars(env, chaine2, str2);
return (*env)->NewStringUTF(env, resultat);
}

JNIEXPORT jlong JNICALL Java_com_ldu_JNITest_testLong
(JNIEnv * env, jobject obj , jlong valeur)
{
return valeur + 1;
}


3-Une fois les méthodes implémentées, il faut maitenant les compiler, par exemple avec mingw (portage de gcc sous windows) ...
Voici un exemple de ligne de commande


D:\tools\bin\gcc.exe -I "C:\Program Files\Java\j2sdk1.4.2_08\include" -I "C:\Program Files\Java\j2sdk1.4.2_08\include\win32" -c "D:\Projets\workspace_bc\testJNI\bin\com_ldu_JNITest.c"


4-Il est ensuite nécessaire de générer la libriarie:
Voici la ligne de comande
D:\tools\bin\gcc.exe -shared -Wl,--kill-at "D:\Projets\workspace_bc\testJNI\bin\com_ldu_JNITest.o" -o nativeLib.dll

5-et surtout de la mettre dans le java.library.path
java com.ldu.JNITest-Djava.library.path="D:\Projets\workspace_bc\testJNI\bin"



lundi 7 septembre 2009

java : template velocity

Voici une manière simple et puissante (boucle possible, conidtion, etc ... ) de générer des mails, ou des fichiers customisés via un système de template et le remplacement "en live" par les valeurs des variables. Voici la librairie apache Velocity :

//1-initialiser velocity
Velocity.init();

//2-initailiser le contexte
VelocityContext context = new VelocityContext();

//3- mettre les donnees dans le contexte
context.put("nom","Enwoo");
context.put("typeAbonnement","Forfait 4 heure");
context.put("dateDuMail",new Date());

//4-choisir un fichier template au format velocity
template = Velocity.getTemplate(templateName);

//5-merger le template
template.merge(context,writer);

//6-ecrire le fichier template
il faut respecter la syntaxe velocity, mais simplment les variable doive avoir un $MaVariable devant


/************************************************/
/* un extrait complet et son fichier template */
/************************************************/
private void genererConfiguration() throws Exception
{
HashMap config = new HashMap();
try {
//1 initialize context
Velocity.init();
} catch (Exception e) {
System.err.println("Erreur a l'initialisation");
}
// retrieve and put data in context
VelocityContext context = new VelocityContext();

String iniFile = "ressources/sidef.ini";
LineNumberReader reader = null;
Pattern pValue = Pattern.compile("=(.)+");
Pattern pKey = Pattern.compile("(.)+=");

try {
reader = new LineNumberReader(new FileReader(iniFile));

String line = null;
String value = null;
String key = null;
Matcher matcherValue = null;
Matcher matcherKey = null;

while((line = reader.readLine()) != null)
{
if(line.length() > 0)
{
System.out.println("lecture de [" + line + "]");
matcherValue = pValue.matcher(line);
matcherKey= pKey.matcher(line);
while(matcherValue.find() && matcherKey.find())
{
key = line.substring(matcherKey.start(),matcherKey.end()-1);
value = line.substring(matcherValue.start()+1,matcherValue.end());
context.put(key,value);
}
}
}
} catch (FileNotFoundException e2) {
System.err.println("Erreur de lectur'e du fichier ini [" + iniFile + "]");
e2.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

// choose template
Template template = null;
String templateName = "src/ressources/prod.vm";
try {
template = Velocity.getTemplate(templateName);
} catch (ResourceNotFoundException e) {
System.err.println("Template non trouve [" + templateName + "]");
} catch (ParseErrorException e) {
System.err.println("Template non conforme [" + templateName + "]");
} catch (Exception e) {
System.err.println("Exception innattendue [" + e.getMessage() + "]");
}

// merge template
FileWriter writer = null;
String fileName = "prod.conf";
try
{
File file = new File(fileName);
if(file.exists())
{
file.delete();
}

writer = new FileWriter(fileName);

try {
template.merge(context,writer);
writer.flush();
writer.close();
} catch (ResourceNotFoundException e) {
System.err.println("Erreur lors du merge du template");
e.printStackTrace();
} catch (ParseErrorException e) {
System.err.println("Erreur lors du merge du template");
} catch (MethodInvocationException e) {
System.err.println("Erreur lors du merge du template");
} catch (IOException e) {
System.err.println("Erreur lors du merge du template");
}
}
catch (IOException e1)
{
System.err.println("Erreur IO lors de l'ecriture du fichier");
}
finally
{
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}


/************************************************/
/* le fichier template associe email.vm */
/************************************************/

Bonjour $nom,

Votre formule d'abonnement est à compté du $dateDuMail, un abonnement du type $typeAbonnement.

Cordialement votre service Client.

jeudi 27 août 2009

java : logger les paamètres d'un preparedStatement

La technique consiste a wrapper et implémenter l'interface PreparedStatement. Le wrapper va construire la chaine au fur et a mesure des setXXX


// $Id$
package com.edf.iece.base.config;

import java.net.URL;

import java.sql.Connection;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import java.util.ArrayList;
import java.util.Date;
import java.util.StringTokenizer;


/**
* A LoggableStatement is a {@link java.sql.PreparedStatement PreparedStatement}
* with added logging capability.
*


* In addition to the methods declared in PreparedStatement,
* LoggableStatement provides a method {@link #getQueryString} which can be
* used to get the query string in a format
* suitable for logging.
*
* @author Jens Wyke (jens.wyke@se.ibm.com)
*
*/
public class LoggableStatement
implements PreparedStatement {
//~ Variables membres //////////////////////////////////////////////////////////////////////////////////////////////

/**
* used for storing parameter values needed for producing log
*/
private ArrayList parameterValues;

/**
*the query string with question marks as parameter placeholders
*/
private String sqlTemplate;

/**
* a statement created from a real database connection
*/
private PreparedStatement wrappedStatement;

//~ Constructeurs //////////////////////////////////////////////////////////////////////////////////////////////////

/**
* Constructs a LoggableStatement.
*
* Creates {@link java.sql.PreparedStatement PreparedStatement}
* with the query string sql using
* the specified connection by calling {@link java.sql.Connection#prepareStatement(String)}.
*


* Whenever a call is made to this LoggableStatement it is forwarded to the prepared
* statment created from
* connection after first saving relevant parameters for use in logging output.
*
* @param connection a JDBC-connection to be used for
* obtaining a "real statement"
* @param sql thw sql to exectute
* @exception SQLException if a PreparedStatement cannot be created
* using the supplied connection and sql
*/
public LoggableStatement (Connection connection, String sql)
throws SQLException {
wrappedStatement = connection.prepareStatement(sql);
sqlTemplate = sql;
parameterValues = new ArrayList();
}

//~ Méthodes ///////////////////////////////////////////////////////////////////////////////////////////////////////

/**
* JDBC 2.0
*
* Adds a set of parameters to the batch.
*
* @exception SQLException if a database access error occurs
* @see Statement#addBatch
*/
public void addBatch ()
throws java.sql.SQLException {
wrappedStatement.addBatch();
}


/**
* JDBC 2.0
*
* Adds a SQL command to the current batch of commmands for the statement.
* This method is optional.
*
* @param sql typically this is a static SQL INSERT or UPDATE statement
* @exception SQLException if a database access error occurs, or the
* driver does not support batch statements
*/
public void addBatch (String sql)
throws java.sql.SQLException {
wrappedStatement.addBatch(sql);
}


/**
* Cancels this Statement object if both the DBMS and
* driver support aborting an SQL statement.
* This method can be used by one thread to cancel a statement that
* is being executed by another thread.
*
* @exception SQLException if a database access error occurs
*/
public void cancel ()
throws SQLException {
wrappedStatement.cancel();
}


/**
* JDBC 2.0
*
* Makes the set of commands in the current batch empty.
* This method is optional.
*
* @exception SQLException if a database access error occurs or the
* driver does not support batch statements
*/
public void clearBatch ()
throws java.sql.SQLException {
wrappedStatement.clearBatch();
}


/**
* Clears the current parameter values immediately.
*

In general, parameter values remain in force for repeated use of a
* Statement. Setting a parameter value automatically clears its
* previous value. However, in some cases it is useful to immediately
* release the resources used by the current parameter values; this can
* be done by calling clearParameters.
*
* @exception SQLException if a database access error occurs
*/
public void clearParameters ()
throws java.sql.SQLException {
wrappedStatement.clearParameters();
}


/**
* Clears all the warnings reported on this Statement
* object. After a call to this method,
* the method getWarnings will return
* null until a new warning is reported for this Statement.
*
* @exception SQLException if a database access error occurs
*/
public void clearWarnings ()
throws java.sql.SQLException {
wrappedStatement.clearWarnings();
}


/**
* Releases this Statement object's database
* and JDBC resources immediately instead of waiting for
* this to happen when it is automatically closed.
* It is generally good practice to release resources as soon as
* you are finished with them to avoid tying up database
* resources.
*

Note: A Statement is automatically closed when it is
* garbage collected. When a Statement is closed, its current
* ResultSet, if one exists, is also closed.
*
* @exception SQLException if a database access error occurs
*/
public void close ()
throws java.sql.SQLException {
wrappedStatement.close();
}


/**
* Executes any kind of SQL statement.
* Some prepared statements return multiple results; the execute
* method handles these complex statements as well as the simpler
* form of statements handled by executeQuery and executeUpdate.
*
* @exception SQLException if a database access error occurs
* @return renvoi le code d'execution
* @see Statement#execute
*/
public boolean execute ()
throws java.sql.SQLException {
return wrappedStatement.execute();
}


/**
* Executes a SQL statement that may return multiple results.
* Under some (uncommon) situations a single SQL statement may return
* multiple result sets and/or update counts. Normally you can ignore
* this unless you are (1) executing a stored procedure that you know may
* return multiple results or (2) you are dynamically executing an
* unknown SQL string. The methods execute,
* getMoreResults, getResultSet,
* and getUpdateCount let you navigate through multiple results.
*
* The execute method executes a SQL statement and indicates the
* form of the first result. You can then use getResultSet or
* getUpdateCount to retrieve the result, and getMoreResults to
* move to any subsequent result(s).
*
* @param sql any SQL statement
* @return true if the next result is a ResultSet; false if it is
* an update count or there are no more results
* @exception SQLException if a database access error occurs
* @see #getResultSet
* @see #getUpdateCount
* @see #getMoreResults
*/
public boolean execute (String sql)
throws java.sql.SQLException {
return wrappedStatement.execute(sql);
}


/**
* JDBC 2.0
*
* Submits a batch of commands to the database for execution.
* This method is optional.
*
* @return an array of update counts containing one element for each
* command in the batch. The array is ordered according
* to the order in which commands were inserted into the batch.
* @exception SQLException if a database access error occurs or the
* driver does not support batch statements
*/
public int[] executeBatch ()
throws java.sql.SQLException {
return wrappedStatement.executeBatch();
}


/**
* Executes the SQL query in this PreparedStatement object
* and returns the result set generated by the query.
*
* @return a ResultSet that contains the data produced by the
* query; never null
* @exception SQLException if a database access error occurs
*/
public java.sql.ResultSet executeQuery ()
throws java.sql.SQLException {
return wrappedStatement.executeQuery();
}


/**
* Executes a SQL statement that returns a single ResultSet.
*
* @param sql typically this is a static SQL SELECT statement
* @return a ResultSet that contains the data produced by the
* query; never null
* @exception SQLException if a database access error occurs
*/
public java.sql.ResultSet executeQuery (String sql)
throws java.sql.SQLException {
return wrappedStatement.executeQuery(sql);
}


/**
* Executes the SQL INSERT, UPDATE or DELETE statement
* in this PreparedStatement object.
* In addition,
* SQL statements that return nothing, such as SQL DDL statements,
* can be executed.
*
* @return either the row count for INSERT, UPDATE or DELETE statements;
* or 0 for SQL statements that return nothing
* @exception SQLException if a database access error occurs
*/
public int executeUpdate ()
throws java.sql.SQLException {
return wrappedStatement.executeUpdate();
}


/**
* Executes an SQL INSERT, UPDATE or DELETE statement. In addition,
* SQL statements that return nothing, such as SQL DDL statements,
* can be executed.
*
* @param sql a SQL INSERT, UPDATE or DELETE statement or a SQL
* statement that returns nothing
* @return either the row count for INSERT, UPDATE or DELETE or 0
* for SQL statements that return nothing
* @exception SQLException if a database access error occurs
*/
public int executeUpdate (String sql)
throws java.sql.SQLException {
return wrappedStatement.executeUpdate(sql);
}


/**
* JDBC 2.0
*
* Returns the Connection object
* that produced this Statement object.
* @return the connection that produced this statement
* @exception SQLException if a database access error occurs
*/
public java.sql.Connection getConnection ()
throws java.sql.SQLException {
return wrappedStatement.getConnection();
}


/**
* JDBC 2.0
*
* Retrieves the direction for fetching rows from
* database tables that is the default for result sets
* generated from this Statement object.
* If this Statement object has not set
* a fetch direction by calling the method setFetchDirection,
* the return value is implementation-specific.
*
* @return the default fetch direction for result sets generated
* from this Statement object
* @exception SQLException if a database access error occurs
*/
public int getFetchDirection ()
throws java.sql.SQLException {
return wrappedStatement.getFetchDirection();
}


/**
* JDBC 2.0
*
* Retrieves the number of result set rows that is the default
* fetch size for result sets
* generated from this Statement object.
* If this Statement object has not set
* a fetch size by calling the method setFetchSize,
* the return value is implementation-specific.
* @return the default fetch size for result sets generated
* from this Statement object
* @exception SQLException if a database access error occurs
*/
public int getFetchSize ()
throws java.sql.SQLException {
return wrappedStatement.getFetchSize();
}


/**
* Returns the maximum number of bytes allowed
* for any column value.
* This limit is the maximum number of bytes that can be
* returned for any column value.
* The limit applies only to BINARY,
* VARBINARY, LONGVARBINARY, CHAR, VARCHAR, and LONGVARCHAR
* columns. If the limit is exceeded, the excess data is silently
* discarded.
*
* @return the current max column size limit; zero means unlimited
* @exception SQLException if a database access error occurs
*/
public int getMaxFieldSize ()
throws java.sql.SQLException {
return wrappedStatement.getMaxFieldSize();
}


/**
* Retrieves the maximum number of rows that a
* ResultSet can contain. If the limit is exceeded, the excess
* rows are silently dropped.
*
* @return the current max row limit; zero means unlimited
* @exception SQLException if a database access error occurs
*/
public int getMaxRows ()
throws java.sql.SQLException {
return wrappedStatement.getMaxRows();
}


/**
* JDBC 2.0
*
* Gets the number, types and properties of a ResultSet's columns.
*
* @return the description of a ResultSet's columns
* @exception SQLException if a database access error occurs
*/
public java.sql.ResultSetMetaData getMetaData ()
throws java.sql.SQLException {
return wrappedStatement.getMetaData();
}


/**
* Moves to a Statement's next result. It returns true if
* this result is a ResultSet. This method also implicitly
* closes any current ResultSet obtained with getResultSet.
*
* There are no more results when (!getMoreResults() &&
* (getUpdateCount() == -1)
*
* @return true if the next result is a ResultSet; false if it is
* an update count or there are no more results
* @exception SQLException if a database access error occurs
* @see #execute
*/
public boolean getMoreResults ()
throws java.sql.SQLException {
return wrappedStatement.getMoreResults();
}


/**
* Retrieves the number of seconds the driver will
* wait for a Statement to execute. If the limit is exceeded, a
* SQLException is thrown.
*
* @return the current query timeout limit in seconds; zero means unlimited
* @exception SQLException if a database access error occurs
*/
public int getQueryTimeout ()
throws java.sql.SQLException {
return wrappedStatement.getQueryTimeout();
}


/**
* Returns the current result as a ResultSet object.
* This method should be called only once per result.
*
* @return the current result as a ResultSet; null if the result
* is an update count or there are no more results
* @exception SQLException if a database access error occurs
* @see #execute
*/
public java.sql.ResultSet getResultSet ()
throws java.sql.SQLException {
return wrappedStatement.getResultSet();
}


/**
* JDBC 2.0
*
* Retrieves the result set concurrency.
* @return le nombre de resultat impacte
* @throws SQLException erreur SQL
*/
public int getResultSetConcurrency ()
throws java.sql.SQLException {
return wrappedStatement.getResultSetConcurrency();
}


/**
* JDBC 2.0
*
* Determine the result set type.
* @return le nombre de resultat impacte
* @throws SQLException erreur SQL
*
*/
public int getResultSetType ()
throws java.sql.SQLException {
return wrappedStatement.getResultSetType();
}


/**
* Returns the current result as an update count;
* if the result is a ResultSet or there are no more results, -1
* is returned.
* This method should be called only once per result.
*
* @return the current result as an update count; -1 if it is a
* ResultSet or there are no more results
* @exception SQLException if a database access error occurs
* @see #execute
*/
public int getUpdateCount ()
throws java.sql.SQLException {
return wrappedStatement.getUpdateCount();
}


/**
* Retrieves the first warning reported by calls on this Statement.
* Subsequent Statement warnings will be chained to this
* SQLWarning.
*
*

The warning chain is automatically cleared each time
* a statement is (re)executed.
*
*

Note: If you are processing a ResultSet, any
* warnings associated with ResultSet reads will be chained on the
* ResultSet object.
*
* @return the first SQLWarning or null
* @exception SQLException if a database access error occurs
*/
public java.sql.SQLWarning getWarnings ()
throws java.sql.SQLException {
return wrappedStatement.getWarnings();
}


/**
* JDBC 2.0
*
* Sets an Array parameter.
*
* @param i the first parameter is 1, the second is 2, ...
* @param x an object representing an SQL array
* @exception SQLException if a database access error occurs
*/
public void setArray (int i, java.sql.Array x)
throws java.sql.SQLException {
wrappedStatement.setArray(i, x);
saveQueryParamValue(i, x);
}


/**
* Sets the designated parameter to the given input stream, which will have
* the specified number of bytes.
* When a very large ASCII value is input to a LONGVARCHAR
* parameter, it may be more practical to send it via a
* java.io.InputStream. JDBC will read the data from the stream
* as needed, until it reaches end-of-file. The JDBC driver will
* do any necessary conversion from ASCII to the database char format.
*
*

Note: This stream object can either be a standard
* Java stream object or your own subclass that implements the
* standard interface.
*
* @param parameterIndex the first parameter is 1, the second is 2, ...
* @param x the Java input stream that contains the ASCII parameter value
* @param length the number of bytes in the stream
* @exception SQLException if a database access error occurs
*/
public void setAsciiStream (int parameterIndex, java.io.InputStream x, int length)
throws java.sql.SQLException {
wrappedStatement.setAsciiStream(parameterIndex, x, length);
saveQueryParamValue(parameterIndex, x);
}


/**
* Sets the designated parameter to a java.lang.BigDecimal value.
* The driver converts this to an SQL NUMERIC value when
* it sends it to the database.
*
* @param parameterIndex the first parameter is 1, the second is 2, ...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public void setBigDecimal (int parameterIndex, java.math.BigDecimal x)
throws java.sql.SQLException {
wrappedStatement.setBigDecimal(parameterIndex, x);
saveQueryParamValue(parameterIndex, x);
}


/**
* Sets the designated parameter to the given input stream, which will have
* the specified number of bytes.
* When a very large binary value is input to a LONGVARBINARY
* parameter, it may be more practical to send it via a
* java.io.InputStream. JDBC will read the data from the stream
* as needed, until it reaches end-of-file.
*
*

Note: This stream object can either be a standard
* Java stream object or your own subclass that implements the
* standard interface.
*
* @param parameterIndex the first parameter is 1, the second is 2, ...
* @param x the java input stream which contains the binary parameter value
* @param length the number of bytes in the stream
* @exception SQLException if a database access error occurs
*/
public void setBinaryStream (int parameterIndex, java.io.InputStream x, int length)
throws java.sql.SQLException {
wrappedStatement.setBinaryStream(parameterIndex, x, length);
saveQueryParamValue(parameterIndex, x);
}


/**
* JDBC 2.0
*
* Sets a BLOB parameter.
*
* @param i the first parameter is 1, the second is 2, ...
* @param x an object representing a BLOB
* @exception SQLException if a database access error occurs
*/
public void setBlob (int i, java.sql.Blob x)
throws java.sql.SQLException {
wrappedStatement.setBlob(i, x);
saveQueryParamValue(i, x);
}


/**
* Sets the designated parameter to a Java boolean value. The driver converts this
* to an SQL BIT value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1, the second is 2, ...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public void setBoolean (int parameterIndex, boolean x)
throws java.sql.SQLException {
wrappedStatement.setBoolean(parameterIndex, x);
saveQueryParamValue(
parameterIndex,
new Boolean(x));
}


/**
* Sets the designated parameter to a Java byte value. The driver converts this
* to an SQL TINYINT value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1, the second is 2, ...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public void setByte (int parameterIndex, byte x)
throws java.sql.SQLException {
wrappedStatement.setByte(parameterIndex, x);
saveQueryParamValue(
parameterIndex,
new Integer(x));
}


/**
* Sets the designated parameter to a Java array of bytes. The driver converts
* this to an SQL VARBINARY or LONGVARBINARY (depending on the
* argument's size relative to the driver's limits on VARBINARYs)
* when it sends it to the database.
*
* @param parameterIndex the first parameter is 1, the second is 2, ...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public void setBytes (int parameterIndex, byte[] x)
throws java.sql.SQLException {
wrappedStatement.setBytes(parameterIndex, x);
saveQueryParamValue(parameterIndex, x);
}


/**
* JDBC 2.0
*
* Sets the designated parameter to the given Reader
* object, which is the given number of characters long.
* When a very large UNICODE value is input to a LONGVARCHAR
* parameter, it may be more practical to send it via a
* java.io.Reader. JDBC will read the data from the stream
* as needed, until it reaches end-of-file. The JDBC driver will
* do any necessary conversion from UNICODE to the database char format.
*
*

Note: This stream object can either be a standard
* Java stream object or your own subclass that implements the
* standard interface.
*
* @param parameterIndex the first parameter is 1, the second is 2, ...
* @param reader the java reader which contains the UNICODE data
* @param length the number of characters in the stream
* @exception SQLException if a database access error occurs
*/
public void setCharacterStream (int parameterIndex, java.io.Reader reader, int length)
throws java.sql.SQLException {
wrappedStatement.setCharacterStream(parameterIndex, reader, length);
saveQueryParamValue(parameterIndex, reader);
}


/**
* JDBC 2.0
*
* Sets a CLOB parameter.
*
* @param i the first parameter is 1, the second is 2, ...
* @param x an object representing a CLOB
* @exception SQLException if a database access error occurs
*/
public void setClob (int i, java.sql.Clob x)
throws java.sql.SQLException {
wrappedStatement.setClob(i, x);
saveQueryParamValue(i, x);
}


/**
* Defines the SQL cursor name that will be used by
* subsequent Statement execute methods. This name can then be
* used in SQL positioned update/delete statements to identify the
* current row in the ResultSet generated by this statement. If
* the database doesn't support positioned update/delete, this
* method is a noop. To insure that a cursor has the proper isolation
* level to support updates, the cursor's SELECT statement should be
* of the form 'select for update ...'. If the 'for update' phrase is
* omitted, positioned updates may fail.
*
*

Note: By definition, positioned update/delete
* execution must be done by a different Statement than the one
* which generated the ResultSet being used for positioning. Also,
* cursor names must be unique within a connection.
*
* @param name the new cursor name, which must be unique within
* a connection
* @exception SQLException if a database access error occurs
*/
public void setCursorName (String name)
throws java.sql.SQLException {
wrappedStatement.setCursorName(name);
}


/**
* Sets the designated parameter to a java.sql.Date value. The driver converts this
* to an SQL DATE value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1, the second is 2, ...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public void setDate (int parameterIndex, java.sql.Date x)
throws java.sql.SQLException {
wrappedStatement.setDate(parameterIndex, x);
saveQueryParamValue(parameterIndex, x);
}


/**
* JDBC 2.0
*
* Sets the designated parameter to a java.sql.Date value,
* using the given Calendar object. The driver uses
* the Calendar object to construct an SQL DATE,
* which the driver then sends to the database. With a
* a Calendar object, the driver can calculate the date
* taking into account a custom timezone and locale. If no
* Calendar object is specified, the driver uses the default
* timezone and locale.
*
* @param parameterIndex the first parameter is 1, the second is 2, ...
* @param x the parameter value
* @param cal the Calendar object the driver will use
* to construct the date
* @exception SQLException if a database access error occurs
*/
public void setDate (int parameterIndex, java.sql.Date x, java.util.Calendar cal)
throws java.sql.SQLException {
wrappedStatement.setDate(parameterIndex, x, cal);
saveQueryParamValue(parameterIndex, x);
}


/**
* Sets the designated parameter to a Java double value. The driver converts this
* to an SQL DOUBLE value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1, the second is 2, ...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public void setDouble (int parameterIndex, double x)
throws java.sql.SQLException {
wrappedStatement.setDouble(parameterIndex, x);
saveQueryParamValue(
parameterIndex,
new Double(x));
}


/**
* Sets escape processing on or off.
* If escape scanning is on (the default), the driver will do
* escape substitution before sending the SQL to the database.
*
* Note: Since prepared statements have usually been parsed prior
* to making this call, disabling escape processing for prepared
* statements will have no effect.
*
* @param enable true to enable; false to disable
* @exception SQLException if a database access error occurs
*/
public void setEscapeProcessing (boolean enable)
throws java.sql.SQLException {
wrappedStatement.setEscapeProcessing(enable);
}


/**
* JDBC 2.0
*
* Gives the driver a hint as to the direction in which
* the rows in a result set
* will be processed. The hint applies only to result sets created
* using this Statement object. The default value is
* ResultSet.FETCH_FORWARD.
*

Note that this method sets the default fetch direction for
* result sets generated by this Statement object.
* Each result set has its own methods for getting and setting
* its own fetch direction.
* @param direction the initial direction for processing rows
* @exception SQLException if a database access error occurs
* or the given direction
* is not one of ResultSet.FETCH_FORWARD, ResultSet.FETCH_REVERSE, or
* ResultSet.FETCH_UNKNOWN
*/
public void setFetchDirection (int direction)
throws java.sql.SQLException {
wrappedStatement.setFetchDirection(direction);
}


/**
* JDBC 2.0
*
* Gives the JDBC driver a hint as to the number of rows that should
* be fetched from the database when more rows are needed. The number
* of rows specified affects only result sets created using this
* statement. If the value specified is zero, then the hint is ignored.
* The default value is zero.
*
* @param rows the number of rows to fetch
* @exception SQLException if a database access error occurs, or the
* condition 0 <= rows <= this.getMaxRows() is not satisfied.
*/
public void setFetchSize (int rows)
throws java.sql.SQLException {
wrappedStatement.setFetchSize(rows);
}


/**
* Sets the designated parameter to a Java float value. The driver converts this
* to an SQL FLOAT value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1, the second is 2, ...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public void setFloat (int parameterIndex, float x)
throws java.sql.SQLException {
wrappedStatement.setFloat(parameterIndex, x);
saveQueryParamValue(
parameterIndex,
new Float(x));
}


/**
* Sets the designated parameter to a Java int value. The driver converts this
* to an SQL INTEGER value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1, the second is 2, ...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public void setInt (int parameterIndex, int x)
throws java.sql.SQLException {
wrappedStatement.setInt(parameterIndex, x);
saveQueryParamValue(
parameterIndex,
new Integer(x));
}


/**
* Sets the designated parameter to a Java long value. The driver converts this
* to an SQL BIGINT value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1, the second is 2, ...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public void setLong (int parameterIndex, long x)
throws java.sql.SQLException {
wrappedStatement.setLong(parameterIndex, x);
saveQueryParamValue(
parameterIndex,
new Long(x));
}


/**
* Sets the limit for the maximum number of bytes in a column to
* the given number of bytes. This is the maximum number of bytes
* that can be returned for any column value. This limit applies
* only to BINARY, VARBINARY, LONGVARBINARY, CHAR, VARCHAR, and
* LONGVARCHAR fields. If the limit is exceeded, the excess data
* is silently discarded. For maximum portability, use values
* greater than 256.
*
* @param max the new max column size limit; zero means unlimited
* @exception SQLException if a database access error occurs
*/
public void setMaxFieldSize (int max)
throws java.sql.SQLException {
wrappedStatement.setMaxFieldSize(max);
}


/**
* Sets the limit for the maximum number of rows that any
* ResultSet can contain to the given number.
* If the limit is exceeded, the excess
* rows are silently dropped.
*
* @param max the new max rows limit; zero means unlimited
* @exception SQLException if a database access error occurs
*/
public void setMaxRows (int max)
throws java.sql.SQLException {
wrappedStatement.setMaxRows(max);
}


/**
* Sets the designated parameter to SQL NULL.
*
*

Note: You must specify the parameter's SQL type.
*
* @param parameterIndex the first parameter is 1, the second is 2, ...
* @param sqlType the SQL type code defined in java.sql.Types
* @exception SQLException if a database access error occurs
*/
public void setNull (int parameterIndex, int sqlType)
throws java.sql.SQLException {
wrappedStatement.setNull(parameterIndex, sqlType);
saveQueryParamValue(parameterIndex, null);
}


/**
* JDBC 2.0
*
* Sets the designated parameter to SQL NULL. This version of setNull should
* be used for user-named types and REF type parameters. Examples
* of user-named types include: STRUCT, DISTINCT, JAVA_OBJECT, and
* named array types.
*
*

Note: To be portable, applications must give the
* SQL type code and the fully-qualified SQL type name when specifying
* a NULL user-defined or REF parameter. In the case of a user-named type
* the name is the type name of the parameter itself. For a REF
* parameter the name is the type name of the referenced type. If
* a JDBC driver does not need the type code or type name information,
* it may ignore it.
*
* Although it is intended for user-named and Ref parameters,
* this method may be used to set a null parameter of any JDBC type.
* If the parameter does not have a user-named or REF type, the given
* typeName is ignored.
*
*
* @param paramIndex the first parameter is 1, the second is 2, ...
* @param sqlType a value from java.sql.Types
* @param typeName the fully-qualified name of an SQL user-named type,
* ignored if the parameter is not a user-named type or REF
* @exception SQLException if a database access error occurs
*/
public void setNull (int paramIndex, int sqlType, String typeName)
throws java.sql.SQLException {
wrappedStatement.setNull(paramIndex, sqlType, typeName);
saveQueryParamValue(paramIndex, null);
}


/**
*

Sets the value of a parameter using an object; use the
* java.lang equivalent objects for integral values.
*
*

The JDBC specification specifies a standard mapping from
* Java Object types to SQL types. The given argument java object
* will be converted to the corresponding SQL type before being
* sent to the database.
*
*

Note that this method may be used to pass datatabase-
* specific abstract data types, by using a Driver-specific Java
* type.
*
* If the object is of a class implementing SQLData,
* the JDBC driver should call its method writeSQL to write it
* to the SQL data stream.
* If, on the other hand, the object is of a class implementing
* Ref, Blob, Clob, Struct,
* or Array, then the driver should pass it to the database as a value of the
* corresponding SQL type.
*
* This method throws an exception if there is an ambiguity, for example, if the
* object is of a class implementing more than one of those interfaces.
*
* @param parameterIndex the first parameter is 1, the second is 2, ...
* @param x the object containing the input parameter value
* @exception SQLException if a database access error occurs
*/
public void setObject (int parameterIndex, Object x)
throws java.sql.SQLException {
wrappedStatement.setObject(parameterIndex, x);
saveQueryParamValue(parameterIndex, x);
}


/**
* Sets the value of the designated parameter with the given object.
* This method is like setObject above, except that it assumes a scale of zero.
*
* @param parameterIndex the first parameter is 1, the second is 2, ...
* @param x the object containing the input parameter value
* @param targetSqlType the SQL type (as defined in java.sql.Types) to be
* sent to the database
* @exception SQLException if a database access error occurs
*/
public void setObject (int parameterIndex, Object x, int targetSqlType)
throws java.sql.SQLException {
wrappedStatement.setObject(parameterIndex, x, targetSqlType);
saveQueryParamValue(parameterIndex, x);
}


/**
*

Sets the value of a parameter using an object. The second
* argument must be an object type; for integral values, the
* java.lang equivalent objects should be used.
*
*

The given Java object will be converted to the targetSqlType
* before being sent to the database.
*
* If the object has a custom mapping (is of a class implementing SQLData),
* the JDBC driver should call its method writeSQL to write it
* to the SQL data stream.
* If, on the other hand, the object is of a class implementing
* Ref, Blob, Clob, Struct,
* or Array, the driver should pass it to the database as a value of the
* corresponding SQL type.
*
*

Note that this method may be used to pass datatabase-
* specific abstract data types.
*
* @param parameterIndex the first parameter is 1, the second is 2, ...
* @param x the object containing the input parameter value
* @param targetSqlType the SQL type (as defined in java.sql.Types) to be
* sent to the database. The scale argument may further qualify this type.
* @param scale for java.sql.Types.DECIMAL or java.sql.Types.NUMERIC types,
* this is the number of digits after the decimal point. For all other
* types, this value will be ignored.
* @exception SQLException if a database access error occurs
* @see Types
*/
public void setObject (int parameterIndex, Object x, int targetSqlType, int scale)
throws java.sql.SQLException {
wrappedStatement.setObject(parameterIndex, x, targetSqlType, scale);
saveQueryParamValue(parameterIndex, x);
}


/**
* Sets the number of seconds the driver will
* wait for a Statement to execute to the given number of seconds.
* If the limit is exceeded, a SQLException is thrown.
*
* @param seconds the new query timeout limit in seconds; zero means
* unlimited
* @exception SQLException if a database access error occurs
*/
public void setQueryTimeout (int seconds)
throws java.sql.SQLException {
wrappedStatement.setQueryTimeout(seconds);
}


/**
* JDBC 2.0
*
* Sets a REF(<structured-type>) parameter.
*
* @param i the first parameter is 1, the second is 2, ...
* @param x an object representing data of an SQL REF Type
* @exception SQLException if a database access error occurs
*/
public void setRef (int i, java.sql.Ref x)
throws java.sql.SQLException {
wrappedStatement.setRef(i, x);
saveQueryParamValue(i, x);
}


/**
* Sets the designated parameter to a Java short value. The driver converts this
* to an SQL SMALLINT value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1, the second is 2, ...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public void setShort (int parameterIndex, short x)
throws java.sql.SQLException {
wrappedStatement.setShort(parameterIndex, x);
saveQueryParamValue(
parameterIndex,
new Integer(x));
}


/**
* Sets the designated parameter to a Java String value. The driver converts this
* to an SQL VARCHAR or LONGVARCHAR value (depending on the argument's
* size relative to the driver's limits on VARCHARs) when it sends
* it to the database.
*
* @param parameterIndex the first parameter is 1, the second is 2, ...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public void setString (int parameterIndex, String x)
throws java.sql.SQLException {
wrappedStatement.setString(parameterIndex, x);
saveQueryParamValue(parameterIndex, x);
}


/**
* Sets the designated parameter to a java.sql.Time value. The driver converts this
* to an SQL TIME value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1, the second is 2, ...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public void setTime (int parameterIndex, java.sql.Time x)
throws java.sql.SQLException {
wrappedStatement.setTime(parameterIndex, x);
saveQueryParamValue(parameterIndex, x);
}


/**
* JDBC 2.0
*
* Sets the designated parameter to a java.sql.Time value,
* using the given Calendar object. The driver uses
* the Calendar object to construct an SQL TIME,
* which the driver then sends to the database. With a
* a Calendar object, the driver can calculate the time
* taking into account a custom timezone and locale. If no
* Calendar object is specified, the driver uses the default
* timezone and locale.
*
* @param parameterIndex the first parameter is 1, the second is 2, ...
* @param x the parameter value
* @param cal the Calendar object the driver will use
* to construct the time
* @exception SQLException if a database access error occurs
*/
public void setTime (int parameterIndex, java.sql.Time x, java.util.Calendar cal)
throws java.sql.SQLException {
wrappedStatement.setTime(parameterIndex, x, cal);
saveQueryParamValue(parameterIndex, x);
}


/**
* Sets the designated parameter to a java.sql.Timestamp value. The driver
* converts this to an SQL TIMESTAMP value when it sends it to the
* database.
*
* @param parameterIndex the first parameter is 1, the second is 2, ...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public void setTimestamp (int parameterIndex, java.sql.Timestamp x)
throws java.sql.SQLException {
wrappedStatement.setTimestamp(parameterIndex, x);
saveQueryParamValue(parameterIndex, x);
}


/**
* JDBC 2.0
*
* Sets the designated parameter to a java.sql.Timestamp value,
* using the given Calendar object. The driver uses
* the Calendar object to construct an SQL TIMESTAMP,
* which the driver then sends to the database. With a
* a Calendar object, the driver can calculate the timestamp
* taking into account a custom timezone and locale. If no
* Calendar object is specified, the driver uses the default
* timezone and locale.
*
* @param parameterIndex the first parameter is 1, the second is 2, ...
* @param x the parameter value
* @param cal the Calendar object the driver will use
* to construct the timestamp
* @exception SQLException if a database access error occurs
*/
public void setTimestamp (int parameterIndex, java.sql.Timestamp x, java.util.Calendar cal)
throws java.sql.SQLException {
wrappedStatement.setTimestamp(parameterIndex, x, cal);
saveQueryParamValue(parameterIndex, x);
}


/**
* Sets the designated parameter to the given input stream, which will have
* the specified number of bytes.
* When a very large UNICODE value is input to a LONGVARCHAR
* parameter, it may be more practical to send it via a
* java.io.InputStream. JDBC will read the data from the stream
* as needed, until it reaches end-of-file. The JDBC driver will
* do any necessary conversion from UNICODE to the database char format.
* The byte format of the Unicode stream must be Java UTF-8, as
* defined in the Java Virtual Machine Specification.
*
*

Note: This stream object can either be a standard
* Java stream object or your own subclass that implements the
* standard interface.
*
* @param parameterIndex the first parameter is 1, the second is 2, ...
* @param x the java input stream which contains the
* UNICODE parameter value
* @param length the number of bytes in the stream
* @exception SQLException if a database access error occurs
* @deprecated
*/
public void setUnicodeStream (int parameterIndex, java.io.InputStream x, int length)
throws java.sql.SQLException {
wrappedStatement.setUnicodeStream(parameterIndex, x, length);
saveQueryParamValue(parameterIndex, x);
}


/**
* Returns the sql statement string (question marks replaced with set parameter values)
* that will be (or has been) executed by the {@link java.sql.PreparedStatement PreparedStatement} that this
* LoggableStatement is a wrapper for.
*


* @return java.lang.String the statemant represented by this LoggableStatement
*/
public String getQueryString () {
StringBuffer buf = new StringBuffer();
int qMarkCount = 0;
StringTokenizer tok = new StringTokenizer(sqlTemplate + " ", "?");

while (tok.hasMoreTokens()) {
String oneChunk = tok.nextToken();
buf.append(oneChunk);

Object value;

if (parameterValues.size() > (1 + qMarkCount)) {
value = parameterValues.get(1 + qMarkCount++);
}else {
if (tok.hasMoreTokens()) {
value = null;
}else {
value = "";
}
}

buf.append("" + value);
}

return buf.toString()
.trim();
}


/**
* Saves the parameter value obj for the specified position for use in logging output
*
* @param position position (starting at 1) of the parameter to save
* @param obj java.lang.Object the parameter value to save
*/
private void saveQueryParamValue (int position, Object obj) {
String strValue;

if (obj instanceof String || obj instanceof Date) {
// if we have a String or Date , include '' in the saved value
strValue = "'" + obj + "'";
}else {
if (obj == null) {
// convert null to the string null
strValue = "null";
}else {
// unknown object (includes all Numbers), just call toString
strValue = obj.toString();
}
}

// if we are setting a position larger than current size of parameterValues, first make it larger
while (position >= parameterValues.size()) {
parameterValues.add(null);
}

// save the parameter
parameterValues.set(position, strValue);
}


/**
*
*
* @return le parametre Metadata
*
* @throws SQLException erreur SQL
*/
public ParameterMetaData getParameterMetaData ()
throws SQLException {
return wrappedStatement.getParameterMetaData();
}


/**
*
*
* @param arg0 int
* @param arg1 URL
*
* @throws SQLException SQLException
*/
public void setURL (int arg0, URL arg1)
throws SQLException {
wrappedStatement.setURL(arg0, arg1);
}


/**
*
*
* @param arg0 String
* @param arg1 int
*
* @return boolean
*
* @throws SQLException SQLException
*/
public boolean execute (String arg0, int arg1)
throws SQLException {
return wrappedStatement.execute(arg0, arg1);
}


/**
*
*
* @param arg0 String
* @param arg1 int[]
*
* @return boolean
*
* @throws SQLException SQLException
*/
public boolean execute (String arg0, int[] arg1)
throws SQLException {
return wrappedStatement.execute(arg0, arg1);
}


/**
*
*
* @param arg0 String
* @param arg1 String[]
*
* @return boolean
*
* @throws SQLException SQLException
*/
public boolean execute (String arg0, String[] arg1)
throws SQLException {
return wrappedStatement.execute(arg0, arg1);
}


/**
*
*
* @param arg0 String
* @param arg1 int
*
* @return int
*
* @throws SQLException SQLException
*/
public int executeUpdate (String arg0, int arg1)
throws SQLException {
return wrappedStatement.executeUpdate(arg0, arg1);
}


/**
*
*
* @param arg0 String
* @param arg1 int[]
*
* @return int
*
* @throws SQLException SQLException
*/
public int executeUpdate (String arg0, int[] arg1)
throws SQLException {
return wrappedStatement.executeUpdate(arg0, arg1);
}


/**
*
*
* @param arg0 String
* @param arg1 String[]
*
* @return int
*
* @throws SQLException SQLException
*/
public int executeUpdate (String arg0, String[] arg1)
throws SQLException {
return wrappedStatement.executeUpdate(arg0, arg1);
}


/**
*
*
* @return ResultSet
*
* @throws SQLException SQLException
*/
public ResultSet getGeneratedKeys ()
throws SQLException {
return wrappedStatement.getGeneratedKeys();
}


/**
*
*
* @param arg0 int
*
* @return boolean
*
* @throws SQLException SQLException
*/
public boolean getMoreResults (int arg0)
throws SQLException {
return wrappedStatement.getMoreResults();
}


/**
*
*
* @return int
*
* @throws SQLException SQLException
*/
public int getResultSetHoldability ()
throws SQLException {
return wrappedStatement.getResultSetHoldability();
}
}