View Javadoc

1   
2   package atg.metier.dao.jdbc;
3   
4   import java.sql.ResultSet;
5   import java.sql.SQLException;
6   import java.sql.Statement;
7   import java.util.StringTokenizer;
8   import java.util.Vector;
9   import atg.metier.dao.ATGDao;
10  import atg.metier.dao.exception.ATGDaoDataNotFoundException;
11  import atg.metier.dao.jdbc.exception.ATGDaoBaseIndisponibleException;
12  import atg.metier.dao.jdbc.exception.ATGDaoRequeteException;
13  import atg.service.constante.AtgConstantes;
14  import atg.service.constante.AtgConstantesWF;
15  import atg.service.log.AtgLogManager;
16  import atg.util.service.identifiant.ATGCritereValue;
17  import atg.util.service.identifiant.ATGListCritereValue;
18  
19  /**
20   * <p>Titre : Classe DAO spécialisée en JDBC</p>
21   * <p>Description : Cette classe accède à une base de données relationnelle via le
22   * pool de connexion nommé ATGDaoPoolDataSource</p>
23   * <p>Copyright : FERRARI Olivier</p>
24   * @author  BOSC Frédéric repris et modifié par FERRARI Olivier
25   * @version 1.3.1
26   * Ce logiciel est régi par la licence CeCILL soumise au droit français et
27   * respectant les principes de diffusion des logiciels libres. Vous pouvez
28   * utiliser, modifier et/ou redistribuer ce programme sous les conditions
29   * de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA 
30   *  sur le site http://www.cecill.info.
31   * 
32   * Le fait que vous puissiez accéder à cet en-tête signifie que vous avez 
33   * pris connaissance de la licence CeCILL, et que vous en avez accepté les
34   * termes.
35   */
36  
37  abstract public class ATGDaoJdbc extends ATGDao
38  {
39  
40    //***************************************************************************
41    //                          Attributs
42    //***************************************************************************
43  
44    /**
45     * connexion de travail
46     */
47    protected java.sql.Connection connexion   = null;
48    /**
49     * statement de travail
50     */
51    protected Statement           statement   = null;
52    /**
53     * resultset de travail
54     */
55    protected ResultSet           resultset   = null;
56    /**
57     * référence le type de connexion (permet de gérer plusieurs connexion
58     * différente
59     */
60    protected String              reference   = null;
61    /**
62     * référence une connexion du pool
63     */
64    protected java.sql.Connection connInt     = null;
65  
66    /**
67     * Attribut de la connexion standard
68     */
69    // protected java.sql.Driver driver = null;
70    //***************************************************************************
71    //                          Constructeurs
72    //***************************************************************************
73    /**
74     * Constructeur.
75     */
76    public ATGDaoJdbc()
77    {
78      reference = ATGDaoPoolDataSource.CSTE_DEFAULT_REFERENCE;
79    }
80  
81    /**
82     * Retourne le contenu de l'execution d'un requete en base avec gestion de
83     * l'accès à la base
84     * 
85     * @param sql
86     *          String Chaine de caractère contenant la requête à exécuter
87     * @return ResulSet
88     */
89    public ResultSet send(String sql) throws ATGDaoBaseIndisponibleException,
90        ATGDaoRequeteException, ATGDaoDataNotFoundException
91    {
92      try
93      {
94        connexion = getConnection();
95        statement = connexion.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
96            ResultSet.CONCUR_UPDATABLE);
97      }
98      catch (SQLException ex)
99      {
100       logSevere("Impossible de poser question send " + ex.getMessage());
101       throw new ATGDaoBaseIndisponibleException();
102     }
103     try
104     {
105       resultset = statement.executeQuery(sql);
106       // Si on a pas de suivant, on jete une exception
107       if (!resultset.next())
108       {
109         logFinest("Pas de donnée trouvée pour cette requète");
110         throw new ATGDaoDataNotFoundException(
111             "Aucune donnée trouvée pour la requète");
112       }
113       else
114       {
115         // Sinon on se replace comme il faut.
116         logFinest("Données trouvées, on se replace comme il faut");
117         resultset.beforeFirst();
118       }
119 
120     }
121     catch (SQLException ex1)
122     {
123       throw new ATGDaoRequeteException("Erreur de sql = " + ex1.getMessage());
124     }
125     logFine("Requete posée = " + sql);
126     return resultset;
127   }
128 
129   /**
130    * Retourne le résultat d'une action requete mise à jour (update
131    * 
132    * @param sql
133    *          String Chaine de caractère contenant la requête à exécuter
134    * @return int valeur de retour d'éxécution
135    */
136   public int sendAction(String sql) throws ATGDaoBaseIndisponibleException,
137       ATGDaoDataNotFoundException, ATGDaoRequeteException
138   {
139 
140     int i = 0;
141 
142     try
143     { // Accès à la base.
144       connexion = getConnection();
145       statement = connexion.createStatement();
146     }
147     catch (SQLException ex)
148     {
149       logSevere("Impossible d'executer requete par sendAction "
150           + ex.getMessage());
151       throw new ATGDaoBaseIndisponibleException();
152     }
153 
154     try
155     {
156       // Seule exception possible : Erreur à l'éxécution du sql :
157       // Probleme de syntaxe sql
158       // Insertion sur doublon
159       i = statement.executeUpdate(sql);
160     }
161     catch (SQLException ex1)
162     {
163       throw new ATGDaoRequeteException("Erreur de sql = " + ex1.getMessage());
164 
165     }
166 
167     logFine("Requete posée = " + sql);
168     // Dans le cas ou le retour est à 0, on est soit en modification, soit en
169     // suppression et la clé n'est pas trouvée.
170     if (i == 0)
171     {
172       throw new ATGDaoDataNotFoundException();
173     }
174 
175     return i;
176   }
177 
178   //***************************************************************************
179   //                          Méthodes publiques
180   //***************************************************************************
181 
182   /**
183    * Retourne une connexion provenant du pool de connexion.
184    * 
185    * @return java.sql.Connection
186    */
187   protected java.sql.Connection getConnection()
188       throws ATGDaoBaseIndisponibleException
189   {
190     if (connInt == null)
191         connInt = ATGDaoPoolDataSource.getInstance(reference).getConnection();
192 
193     return connInt;
194   }
195 
196   /**
197    * Ferme le resultSet, le statement et la connexion en cours d'utilisation
198    */
199   protected void libererRessource()
200   {
201     // Fermeture du ResultSet
202     try
203     {
204       if (resultset != null) resultset.close();
205     }
206     catch (java.sql.SQLException sqlException)
207     {
208       logSevere("Impossible de fermer le resultSet  "
209           + sqlException.getMessage());
210     }
211 
212     // Fermeture du Statement
213     try
214     {
215       if (statement != null) statement.close();
216     }
217     catch (java.sql.SQLException sqlException)
218     {
219       logSevere("Impossible de fermer le statement  " + sqlException);
220     }
221 
222     // Fermeture de la connexion
223     if (connexion != null)
224     {
225       // la connection est libérée
226       connInt = null;
227       ATGDaoPoolDataSource.getInstance(reference).release(connexion);
228     }
229   }
230 
231   public String genererFROM(String sql)
232   {
233     String from = "";
234     Vector listeTemp = new Vector();
235 
236     StringTokenizer leToken = new StringTokenizer(sql, "(");
237     String temp = null;
238     while (leToken.hasMoreTokens())
239     {
240       // Il faut purger, trop de bordel
241       temp = leToken.nextToken();
242       logFinest("le token : " + temp);
243       temp = temp.substring(0, temp.indexOf("."));
244       logFinest("le table : " + temp);
245       if (!listeTemp.contains(temp))
246       {
247         logFinest("On a pas la table on la rajoute");
248         listeTemp.add(temp);
249       }
250     }
251 
252     // On fabrique la liste
253 
254     for (int i = 0; i < listeTemp.size(); i++)
255     {
256       temp = (String) listeTemp.elementAt(i);
257       if (i > 0) from += ", ";
258       from += temp;
259     }
260     return from;
261   }
262 
263   /**
264    * Ferme le resultSet, le statement et la connexion en cours d'utilisation
265    */
266   public String genererSQL(ATGListCritereValue listeCritere)
267   {
268     String sql = "";
269     ATGCritereValue critere;
270     ATGCritereValue critereSuivant;
271     String value;
272     Vector listeTriee = listeCritere.getSortedListByKey();
273 
274     Class classeSuivante;
275 
276     String jointure = "";
277 
278     if (listeCritere == null) return null;
279 
280     sql = "(";
281     for (int i = 0; i < listeTriee.size(); i++)
282     {
283 
284       critere = (ATGCritereValue) listeTriee.get(i);
285       // On récupère la valeur dans le fichier de constantes
286       value = AtgConstantesWF.getValue(critere.getKey());
287 
288       // Ajout du critere en cours dans sql
289       logFinest("Critère : " + critere.getKey() + " Valeur  : " + value);
290       String laValeur = value.substring(value.indexOf("_") + 1);
291       logFinest("Recomposé :" + laValeur);
292       sql += laValeur + critere.getOperation();
293 
294       if (value.startsWith("INT"))
295       {
296         sql += critere.getStringValue();
297       }
298       else if (value.startsWith("VARCHAR"))
299       {
300         sql += "'" + critere.getStringValue() + "'";
301       }
302 
303       // Si on est pas sur le dernier
304       if (i != (listeTriee.size() - 1))
305       {
306         classeSuivante = ((ATGCritereValue) listeTriee.get(i + 1)).getClasse();
307         // Si la classe suivante est différente, on essai de trouver la jointure
308         if (classeSuivante != critere.getClasse())
309         {
310           logFinest("Recherche de jointure : " + critere.getClasse().getName()
311               + "_TO_" + classeSuivante.getName());
312           //  On récupère la valeur dans le fichier de constantes
313           value = "("
314               + AtgConstantesWF.getValue(critere.getClasse().getName() + "_TO_"
315                   + classeSuivante.getName()) + ")";
316           logFinest("Jointure trouvée : " + value);
317           if (jointure.length() > 0) value = " AND " + value;
318           jointure = jointure + value;
319         }
320 
321        
322         // Si on à une opération entre, on prend le suivant et on rajoute AND
323         if (critere.getOperation() == ATGCritereValue.OPERATION_ENTRE)
324         {
325           logFiner("On a un critere ENTRE");
326           sql += " AND ";
327 
328           critere = (ATGCritereValue) listeTriee.get(++i);
329 
330           if (value.startsWith("INT"))
331           {
332             sql += critere.getStringValue();
333           }
334           else if (value.startsWith("VARCHAR"))
335           {
336             sql += "'" + critere.getStringValue() + "'";
337           }
338           logFiner("le sql : " + sql);
339         }
340         // Si on a le même critere à i et i+1
341         if(i+1< listeTriee.size())
342         {
343         critereSuivant = (ATGCritereValue) listeTriee.get(i + 1);
344         if (critere.getKey().equals(critereSuivant.getKey()))
345 
346           // On a le même critere donc OU
347           sql += " OR ";
348         else
349           // On a pas le même critere donc ET
350           sql += ") AND (";
351         }
352       }
353     }
354     // A la fin on ferme la parenthèse.
355     sql += ")";
356     if (jointure.length() > 0) sql = sql + " AND " + jointure;
357     logFiner(" critère généré : "  + sql);    
358     return sql;
359   }
360 
361   /*
362    * Permet de générer le SQL par rapport une classe Vo de référence.
363    */
364   public String genererSQL(Class classRef, ATGListCritereValue listeCritere)
365   {
366     String sql = "";
367     ATGCritereValue critere;
368     ATGCritereValue critereSuivant;
369     String value;
370     Vector listeTriee = listeCritere.getSortedListByKey();
371 
372     Class classeSuivante;
373 
374     String jointure = "";
375 
376     if (listeCritere == null) return null;
377 
378     sql = "(";
379     for (int i = 0; i < listeTriee.size(); i++)
380     {
381 
382       critere = (ATGCritereValue) listeTriee.get(i);
383       // On récupère la valeur dans le fichier de constantes
384       value = AtgConstantesWF.getValue(critere.getKey());
385 
386       // Ajout du critere en cours dans sql
387       logFinest("Critère : " + critere.getKey() + "Valeur  : " + value);
388       String laValeur = value.substring(value.indexOf("_") + 1);
389       logFinest("Recomposé :" + laValeur);
390       sql += laValeur + critere.getOperation();
391 
392       if (value.startsWith("INT"))
393       {
394         sql += critere.getStringValue();
395       }
396       else if (value.startsWith("VARCHAR"))
397       {
398         sql += "'" + critere.getStringValue() + "'";
399       }
400 
401       // Si on est pas sur le dernier
402       if (i != (listeTriee.size() - 1))
403       {
404         classeSuivante = ((ATGCritereValue) listeTriee.get(i + 1)).getClasse();
405         // Si la classe suivante est différente, on essai de trouver la jointure
406         if (classeSuivante != critere.getClasse())
407         {
408           logFinest("Recherche de jointure.");
409           //  On récupère la valeur dans le fichier de constantes
410           value = AtgConstantesWF.getValue(classeSuivante + "_TO_"
411               + critere.getClasse());
412           logFinest("Jointure trouvée  : " + value);
413           logFinest("la jointure existante :" + jointure);
414           if (jointure.indexOf(value) <= 0)
415           {
416             if (jointure.length() > 0)
417             {
418               value = " AND (" + value + ")";
419             }
420             jointure = jointure + value;
421           }
422         }
423 
424         // Si on à une opération entre, on prend le suivant et on rajoute AND
425         if (critere.getOperation() == ATGCritereValue.OPERATION_ENTRE)
426         {
427           logFiner("On a un critere ENTRE");
428           sql += " AND ";
429 
430           critere = (ATGCritereValue) listeTriee.get(++i);
431 
432           if (value.startsWith("INT"))
433           {
434             sql += critere.getStringValue();
435           }
436           else if (value.startsWith("VARCHAR"))
437           {
438             sql += "'" + critere.getStringValue() + "'";
439           }
440           logFiner("le sql : " + sql);
441         }
442         // Si on a le même critere à i et i+1
443         if(i+1< listeTriee.size())
444         {
445         critereSuivant = (ATGCritereValue) listeTriee.get(i + 1);
446         if (critere.getKey().equals(critereSuivant.getKey()))
447 
448           // On a le même critere donc OU
449           sql += " OR ";
450         else
451           // On a pas le même critere donc ET
452           sql += ") AND (";
453         }
454       }
455     }
456     // A la fin on ferme la parenthèse.
457     sql += ")";
458     if (jointure.length() > 0) sql = sql + " AND " + jointure;
459     logFiner(" critère généré : "  + sql);
460     return sql;
461   }
462 
463   //***************************************************************************
464   //                          Gestion des logs
465   //***************************************************************************
466 
467   /**
468    * référence vers le log
469    */
470   protected static java.util.logging.Logger logger_ = null;
471 
472   /**
473    * Retourne le log associé
474    * 
475    * @return java.util.logging.Logger Trace associée
476    */
477   protected java.util.logging.Logger getLogger()
478   {
479     if (logger_ == null)
480         logger_ = AtgLogManager
481             .getLog(AtgConstantes.ATG_LOG_CATEGORY_METIER_DAO_JDBC);
482 
483     return logger_;
484   }
485 
486 }