View Javadoc

1   /**
2    * <p>
3    * Titre : Classe DAO spécialisée en JDO
4    * </p>
5    * <p>
6    * Description : Cette classe accède à un gestionnaire de persistance via le
7    * pool de gestionnaire persisance nommé ATGDaoJdoPoolDataSource
8    * </p>
9    * <p>
10   * Copyright : FERRARI Olivier
11   * </p>
12   * 
13   * @author YSMAL Vincent
14   * @version 1.0 Ce logiciel est régi par la licence CeCILL soumise au droit
15   *          français et respectant les principes de diffusion des logiciels
16   *          libres. Vous pouvez utiliser, modifier et/ou redistribuer ce
17   *          programme sous les conditions de la licence CeCILL telle que
18   *          diffusée par le CEA, le CNRS et l'INRIA sur le site
19   *          http://www.cecill.info.
20   * 
21   * Le fait que vous puissiez accéder à cet en-tête signifie que vous avez pris
22   * connaissance de la licence CeCILL, et que vous en avez accepté les termes.
23   */
24  package atg.metier.dao.jdo;
25  
26  import java.util.Collection;
27  import java.util.Vector;
28  import javax.jdo.JDOException;
29  import javax.jdo.JDOObjectNotFoundException;
30  import javax.jdo.PersistenceManager;
31  import javax.jdo.Query;
32  import javax.jdo.spi.PersistenceCapable;
33  import atg.metier.dao.ATGDao;
34  import atg.metier.dao.exception.ATGDaoAccessSupportException;
35  import atg.metier.dao.exception.ATGDaoDataNotFoundException;
36  import atg.metier.dao.jdbc.exception.ATGDaoBaseIndisponibleException;
37  import atg.metier.entite.ATGIEntite;
38  import atg.service.constante.AtgConstantes;
39  import atg.service.log.AtgLogManager;
40  import atg.util.service.identifiant.ATGCritereValue;
41  import atg.util.service.identifiant.ATGIdentifiant;
42  import atg.util.service.identifiant.ATGListCritereValue;
43  import atg.util.service.list.ATGIListEntity;
44  import atg.util.service.list.ATGListEntity;
45  import atg.util.service.list.ATGListException;
46  import com.versant.core.jdo.VersantPersistenceManager;
47  
48  public class ATGDaoJdo<K extends ATGIEntite> extends ATGDao<K>
49  {
50    /**
51     * référence le type de connexion (permet de gérer plusieurs connexion
52     * différente
53     */
54    protected String           reference                   = "versant";
55    /**
56     * Classe sur laquelle on va effectuer la recherche
57     */
58    protected Class            laClasse                    = null;
59    /**
60     * Opérateur : Egalité
61     */
62    private static String      OPERATION_EGAL              = " == ";
63    /**
64     * Opérateur : Supérieur strict
65     */
66    private static String      OPERATION_SUPERIEUR_STRICT  = " > ";
67    /**
68     * Opérateur : Supérieur ou égal
69     */
70    private static String      OPERATION_SUPERIEUR_OU_EGAL = " >= ";
71    /**
72     * Opérateur : Inférieur strict
73     */
74    static public String       OPERATION_INFERIEUR_STRICT  = " < ";
75    /**
76     * Opérateur : Inférieur ou égal
77     */
78    static public String       OPERATION_INFERIEUR_OU_EGAL = " >= ";
79    
80    /**
81     * Opérateur : Inférieur ou égal
82     */
83    static public String       OPERATION_COMME = ".sql(\" $1 like ";
84    
85    private PersistenceManager lePm                        = null;
86  
87    //***************************************************************************
88    //                          Méthodes publiques
89    //***************************************************************************
90    public ATGDaoJdo(Class uneClasse)
91    {
92      this.laClasse = uneClasse;
93    }
94  
95    /**
96     * Retourne une instance de Persistance Manager provenant du pool .
97     * 
98     * @return javax.jdo.PersistenceMangager
99     */
100   protected javax.jdo.PersistenceManager getConnection()
101       throws ATGDaoBaseIndisponibleException
102   {
103     try
104     {
105       if (this.lePm == null)
106       {
107         this.lePm = ATGDaoJdoPoolDataSource.getInstance(reference)
108             .getPersistenceManager();
109         this.lePm.currentTransaction().setNontransactionalWrite(true);
110         this.lePm.currentTransaction().setNontransactionalRead(true);
111       }
112       return lePm;
113     }
114     catch (JDOException ex)
115     {
116       this.libererRessource();
117       logSevere("Impossible de récupèrer un gestionnaire de persistance.");
118       throw new ATGDaoBaseIndisponibleException(
119           "Impossible de récupérer un gestionnaire de persistance : "
120               + ex.getMessage());
121     }
122   }
123 
124   private String getCritere(String critere)
125   {
126     if (critere.equals(ATGCritereValue.OPERATION_EGAL)) return OPERATION_EGAL;
127     if (critere.equals(ATGCritereValue.OPERATION_SUPERIEUR_OU_EGAL))
128         return OPERATION_SUPERIEUR_OU_EGAL;
129     if (critere.equals(ATGCritereValue.OPERATION_SUPERIEUR_STRICT))
130         return OPERATION_SUPERIEUR_STRICT;
131     if (critere.equals(ATGCritereValue.OPERATION_INFERIEUR_OU_EGAL))
132         return OPERATION_INFERIEUR_OU_EGAL;
133     if (critere.equals(ATGCritereValue.OPERATION_INFERIEUR_STRICT))
134         return OPERATION_INFERIEUR_STRICT;
135     if (critere.equals(ATGCritereValue.OPERATION_COMME))
136       return OPERATION_COMME;    
137     return null;
138   }
139 
140   /**
141    * Exécute une requete
142    */
143   public ATGIListEntity<K> executeRequete(ATGListCritereValue listeCritere,
144       int niveau) throws ATGDaoBaseIndisponibleException,
145       ATGDaoAccessSupportException, ATGDaoDataNotFoundException
146   {
147     try
148     {
149       String requete; // Chaine contenant le corps de la requete
150       ATGCritereValue critere;
151       ATGCritereValue critereSuivant;
152       Vector listeTriee = listeCritere.getSortedListByKey();
153       String courant = "";
154       String nomVar = "";
155       String temp = "";
156       String classeCritere = null;
157       ATGListEntity laListe = new ATGListEntity();
158       // La requete vers le gestionnaires de persistance
159       //this.getConnection().currentTransaction().setNontransactionalRead(true);
160       //if(!this.getConnection().currentTransaction().isActive())
161       // this.getConnection().currentTransaction().begin();
162       Query query = this.getConnection().newQuery(this.laClasse);
163       requete = "";
164       if (listeTriee.size() > 0)
165       {
166         requete = "(";
167         for (int i = 0; i < listeTriee.size(); i++)
168         {
169           critere = (ATGCritereValue) listeTriee.get(i);
170           // Critere en cours
171           classeCritere = critere.getClasse().toString().substring(
172               critere.getClasse().toString().lastIndexOf(".") + 1);
173           logFinest("Class : " + classeCritere);
174           // Si le critère correspond à la classe d'interro, on ne met que
175           // l'attribut
176           if (critere.getClasse().equals(laClasse))
177           {
178             nomVar = "";
179           }
180           else
181           {
182             temp = classeCritere.toLowerCase();
183             // Si nomVar = temp ca veut dire qu'on a changé de critere, on doit
184             // donc le rajouter
185             if (nomVar.compareTo(temp + ".") != 0)
186             {
187               logFinest("Ajout d'une variable dans la requete : "
188                   + classeCritere + " " + temp);
189               query.declareVariables(classeCritere + " " + temp);
190             }
191             nomVar = temp + ".";
192           }
193           courant = nomVar + critere.getAttribut()
194               + this.getCritere(critere.getOperation()) + "\'"
195               + critere.getStringValue() + "\'";
196           if(this.getCritere(critere.getOperation())==OPERATION_COMME) courant =courant + "\")";
197           // Ajout du critere en cours dans sql
198           logFinest("Critère : " + courant);
199           requete += courant;
200           // Si on est pas sur le dernier
201           if (i != (listeTriee.size() - 1))
202           {
203             // Si on a le même critere à i et i+1
204             critereSuivant = (ATGCritereValue) listeTriee.get(i + 1);
205             if (critere.getKey().equals(critereSuivant.getKey()))
206               // On a le même critere donc OU
207               requete += " || ";
208             else
209               // On a pas le même critere donc ET
210               requete += ") && (";
211           }
212         }
213         // A la fin on ferme la parenthèse.
214         requete += ")";
215       }
216       logFinest("paramètres générés : " + requete);
217       if (requete != null && requete.length() > 0) query.setFilter(requete);
218       Collection resultat = (Collection) query.execute();
219       logFinest("On détache la collection du gestionnaire de persistance, nivea : "
220           + getFetchGroupByNiveau(niveau));
221       ((VersantPersistenceManager) this.getConnection()).versantDetachCopy(
222           resultat, getFetchGroupByNiveau(niveau));
223       Vector uneListe = new Vector(resultat);
224       logFinest("Nb de resultats correspondant à la requete : "
225           + uneListe.size());
226       query.closeAll();
227       if (uneListe.size() == 0)
228       {
229         logFinest("Aucune données trouvée.");
230         libererRessource();
231         throw new ATGDaoDataNotFoundException("Aucune donnée trouvée.");
232       }
233       try
234       {
235         laListe.setListeElement(uneListe);
236       }
237       catch (ATGListException e)
238       {
239         logSevere("Erreur lors de la gestion de la liste de résultat : "
240             + e.getMessage());
241         throw new ATGDaoAccessSupportException(
242             "Impossible de charger l'ATGList");
243       }
244       libererRessource();
245       return laListe;
246     }
247     catch (JDOObjectNotFoundException e)
248     {
249       this.libererRessource();
250       logFinest("Aucune données trouvées : " + e.getMessage());
251       throw new ATGDaoDataNotFoundException("Aucune données trouvées : "
252           + e.getMessage());
253     }
254     catch (JDOException ex)
255     {/*
256       * JDOCanRetryException JDODataStoreException JDOUserException
257       * JDOUnsupportedOptionException JDOFatalException
258       * JDOFatalDataStoreException JDOOptimisticVerificationException
259       * JDOFatalInternalException JDOFatalUserException
260       */
261       this.libererRessource();
262       throw new ATGDaoAccessSupportException("Erreur d'access aux données : "
263           + ex.getMessage());
264     }
265     /*
266      * Exemple de requetes "Complexes", en Jdo
267      * 
268      * 
269      * pm; // PersistenceManager (already initialized)
270      * 
271      * pm.currentTransaction().begin(); Query query =
272      * pm.newQuery(BatchRequestVo.class); query.declareVariables("RequeteVo
273      * req"); query.setFilter("nom ==\"STRJD_REQUEST.FR.20040316.173011\" &&
274      * requetes.contains(req) && \n"+ "( \n"+ "req.immatriculation
275      * ==\"285PKL75\" || \n"+ "req.immatriculation ==\"4460VS93\" || \n"+
276      * "req.immatriculation ==\"482CWY77\" )"); Collection col =
277      * (Collection)query.execute(); for (Iterator iter = col.iterator();
278      * iter.hasNext();) { BatchRequestVo batchrequestvo =
279      * (BatchRequestVo)iter.next(); // System.out.println(batchrequestvo); }
280      * query.closeAll(); pm.currentTransaction().commit();
281      *  
282      */
283   }
284 
285   public void delete(K entite) throws ATGDaoDataNotFoundException,
286       ATGDaoAccessSupportException
287   {
288     try
289     {
290       logFinest("Suppression d'une entite en JDO (" + entite + ").");
291       logFinest("L'identifiant jdo de l'objet : " + ((PersistenceCapable)entite).jdoGetObjectId());
292       PersistenceManager pm = this.getConnection();
293       if (!pm.currentTransaction().isActive()) pm.currentTransaction().begin();
294       logFinest("On récupère l'entite dans le gestionnaire de persistance, par son Id : " );
295       Object lObj = pm.getObjectById(((PersistenceCapable)entite).jdoGetObjectId(), true);
296       logFinest("Une fois récupèré on le supprime." );
297       pm.deletePersistent(lObj);
298       pm.currentTransaction().commit();
299       this.libererRessource();
300     }
301     catch (JDOObjectNotFoundException e)
302     {
303       this.libererRessource();
304       logFinest("Aucune données trouvées : " + e.getMessage());
305       throw new ATGDaoDataNotFoundException("Aucune données trouvées : "
306           + e.getMessage());
307     }
308     catch (JDOException ex)
309     {/*
310       * JDOCanRetryException JDODataStoreException JDOUserException
311       * JDOUnsupportedOptionException JDOFatalException
312       * JDOFatalDataStoreException JDOOptimisticVerificationException
313       * JDOFatalInternalException JDOFatalUserException
314       */
315       this.libererRessource();
316       throw new ATGDaoAccessSupportException("Erreur d'access aux données : "
317           + ex.getMessage());
318     }
319   }
320 
321   public void delete(ATGIdentifiant identifiant)
322       throws ATGDaoDataNotFoundException, ATGDaoAccessSupportException
323   {
324     try
325     {
326       logFinest("Suppression d'une entite en JDO depuis son identifiant ("
327           + identifiant + ").");
328       PersistenceManager pm = this.getConnection();
329       pm.currentTransaction().begin();
330       //Object lObj =this.selectByIdentifiant(identifiant);
331       Object lObj = pm.getObjectById(identifiant, true);
332       pm.deletePersistent(lObj);
333       pm.currentTransaction().commit();
334       this.libererRessource();
335     }
336     catch (JDOObjectNotFoundException e)
337     {
338       this.libererRessource();
339       logFinest("Aucune données trouvées : " + e.getMessage());
340       throw new ATGDaoDataNotFoundException("Aucune données trouvées : "
341           + e.getMessage());
342     }
343     catch (JDOException ex)
344     {/*
345       * JDOCanRetryException JDODataStoreException JDOUserException
346       * JDOUnsupportedOptionException JDOFatalException
347       * JDOFatalDataStoreException JDOOptimisticVerificationException
348       * JDOFatalInternalException JDOFatalUserException
349       */
350       this.libererRessource();
351       throw new ATGDaoAccessSupportException("Erreur d'access aux données : "
352           + ex.getMessage());
353     }
354   }
355 
356   public void insert(K valueObject)
357       throws ATGDaoAccessSupportException
358   {
359     try
360     {
361       logFinest("Insertion d'une entité en JDO (" + valueObject + ").");
362       if (lePm == null) lePm = this.getConnection();
363       lePm.currentTransaction().begin();
364       lePm.makePersistent(valueObject);
365       lePm.currentTransaction().commit();
366       //lePm.makeTransient(valueObject);
367       //lePm.makeNontransactional(valueObject);
368       this.libererRessource();
369     }
370     catch (JDOException ex)
371     {/*
372       * JDOCanRetryException JDODataStoreException JDOUserException
373       * JDOUnsupportedOptionException JDOFatalException
374       * JDOFatalDataStoreException JDOOptimisticVerificationException
375       * JDOFatalInternalException JDOFatalUserException
376       */
377       this.libererRessource();
378       throw new ATGDaoAccessSupportException("Erreur d'access aux données : "
379           + ex.getMessage());
380     }
381   }
382 
383   public ATGIListEntity<K> selectAll() throws ATGDaoDataNotFoundException,
384       ATGDaoAccessSupportException
385   {
386     try
387     {
388       logFinest("Select all en JDO pour la classe " + this.laClasse);
389       logFinest("Un selectAll sans niveau, on met un niveau 0, qui correspont on niveau par défaut");
390       return this.executeRequete(new ATGListCritereValue(), 0);
391       /*
392        * if (lePm==null) lePm= this.getConnection();
393        * lePm.currentTransaction().begin(); lePm.getExtent(this.laClasse,true).;
394        * lePm.currentTransaction().commit();
395        */
396     }
397     catch (JDOObjectNotFoundException e)
398     {
399       this.libererRessource();
400       logFinest("Aucune données trouvées : " + e.getMessage());
401       throw new ATGDaoDataNotFoundException("Aucune données trouvées : "
402           + e.getMessage());
403     }
404     catch (JDOException ex)
405     {/*
406       * JDOCanRetryException JDODataStoreException JDOUserException
407       * JDOUnsupportedOptionException JDOFatalException
408       * JDOFatalDataStoreException JDOOptimisticVerificationException
409       * JDOFatalInternalException JDOFatalUserException
410       */
411       this.libererRessource();
412       throw new ATGDaoAccessSupportException("Erreur d'access aux données : "
413           + ex.getMessage());
414     }
415   }
416 
417   public ATGIListEntity<K> selectByCritere(ATGListCritereValue critere, int niveau)
418       throws ATGDaoDataNotFoundException, ATGDaoAccessSupportException
419   {
420     return this.executeRequete(critere, niveau);
421   }
422 
423   public ATGIListEntity<K> selectByCritere(ATGListCritereValue critere)
424       throws ATGDaoDataNotFoundException, ATGDaoAccessSupportException
425   {
426     logFinest("Un select By Critere sans niveau, on met un niveau 0, qui correspont on niveau par défaut");
427     return this.executeRequete(critere, 0);
428   }
429 
430   private static String getFetchGroupByNiveau(int niveau)
431   {
432     switch (niveau)
433     {
434       case NIVEAU_IDENTIFIANT:
435         return "NIVEAU_INDENTIFIANT";
436       case NIVEAU_ATTRIBUTS:
437         return "NIVEAU_ATTRIBUTS";
438       case NIVEAU_ATTRIBUTS_VO:
439         return "NIVEAU_ATTRIBUTS_VO";
440       default:
441         return null;
442     }
443   }
444 
445   public K selectByIdentifiant(ATGIdentifiant identifiant, int niveau)
446       throws ATGDaoDataNotFoundException, ATGDaoAccessSupportException
447   {
448     try
449     {
450       //this.getConnection().currentTransaction().setNontransactionalRead(true);
451       //if(!this.getConnection().currentTransaction().isActive())this.getConnection().currentTransaction().begin();
452       K obj = (K)this.getConnection().getObjectById(identifiant, true);
453       // Ceci n'a de raison d'etre que du fait que la méthode :
454       // versantDetachCopy, ne prend en paramètre qu'une collection
455       Vector laCollect = new Vector();
456       laCollect.add(obj);
457       logFinest("on détache une copie de l'objet");
458       logFinest("on utilise le fetch correspondant au niveau : " + niveau
459           + " : " + getFetchGroupByNiveau(niveau));
460       Collection detachees = ((VersantPersistenceManager) this.getConnection())
461           .versantDetachCopy(laCollect, getFetchGroupByNiveau(niveau));
462       obj = (K)detachees.toArray()[0];
463       this.libererRessource();
464       return  obj;
465     }
466     catch (JDOObjectNotFoundException e)
467     {
468       this.libererRessource();
469       logFinest("Aucune données trouvées : " + e.getMessage());
470       throw new ATGDaoDataNotFoundException("Aucune données trouvées : "
471           + e.getMessage());
472     }
473     catch (JDOException ex)
474     {/*
475       * JDOCanRetryException JDODataStoreException JDOUserException
476       * JDOUnsupportedOptionException JDOFatalException
477       * JDOFatalDataStoreException JDOOptimisticVerificationException
478       * JDOFatalInternalException JDOFatalUserException
479       */
480       this.libererRessource();
481       throw new ATGDaoAccessSupportException("Erreur d'access aux données : "
482           + ex.getMessage());
483     }
484   }
485 
486   public K selectByIdentifiant(ATGIdentifiant identifiant)
487       throws ATGDaoDataNotFoundException, ATGDaoAccessSupportException
488   {
489     return this.selectByIdentifiant(identifiant, NIVEAU_ATTRIBUTS_VO);
490   }
491 
492   public void update(ATGIEntite valueObject)
493       throws ATGDaoDataNotFoundException, ATGDaoAccessSupportException
494   {
495     try
496     {
497       this.getConnection().currentTransaction().begin();
498       // EN update, on a une version dettachée que l'on doit rattacher
499       Vector leVect = new Vector();
500       leVect.add(valueObject);
501       ((VersantPersistenceManager) this.getConnection()).versantAttachCopy(
502           leVect, true);
503       //this.getConnection().makePersistent(valueObject);
504       this.getConnection().currentTransaction().commit();
505       this.libererRessource();
506     }
507     catch (JDOObjectNotFoundException e)
508     {
509       this.libererRessource();
510       logFinest("Aucune données trouvées : " + e.getMessage());
511       throw new ATGDaoDataNotFoundException("Aucune données trouvées : "
512           + e.getMessage());
513     }
514     catch (JDOException ex)
515     {/*
516       * JDOCanRetryException JDODataStoreException JDOUserException
517       * JDOUnsupportedOptionException JDOFatalException
518       * JDOFatalDataStoreException JDOOptimisticVerificationException
519       * JDOFatalInternalException JDOFatalUserException
520       */
521       this.libererRessource();
522       throw new ATGDaoAccessSupportException("Erreur d'access aux données : "
523           + ex.getMessage());
524     }
525   }
526 
527   public int countByCritere(ATGListCritereValue critere)
528       throws ATGDaoAccessSupportException
529   {
530     try
531     {
532       ATGIListEntity liste = this.executeRequete(critere, 0);
533       return liste.getTotalEnregistrement();
534     }
535     catch (ATGDaoDataNotFoundException e)
536     {
537       return 0;
538     }
539     catch (ATGListException e)
540     {
541       logSevere("Erreur de parcours de la liste de résultat !");
542       throw new ATGDaoAccessSupportException(
543           "Erreur de parcours de la liste de résultat !");
544     }
545   }
546 
547   /**
548    * Ferme le resultSet, le statement et la connexion en cours d'utilisation
549    */
550   protected void libererRessource()
551   {
552     // Fermeture de la connexion
553     if (lePm != null)
554     {
555       // la connection est libérée
556       ATGDaoJdoPoolDataSource.getInstance(reference).release(lePm);
557       lePm = null;
558     }
559   }
560 
561   /**
562    * @return Renvoie reference.
563    */
564   public String getReference()
565   {
566     return reference;
567   }
568 
569   /**
570    * @param reference
571    *          reference à définir.
572    */
573   public void setReference(String reference)
574   {
575     this.reference = reference;
576   }
577   //***************************************************************************
578   //                          Gestion des logs
579   //***************************************************************************
580   /**
581    * référence vers le log
582    */
583   protected static java.util.logging.Logger logger_ = null;
584 
585   /**
586    * Retourne le log associé
587    * 
588    * @return java.util.logging.Logger Trace associée
589    */
590   protected java.util.logging.Logger getLogger()
591   {
592     if (logger_ == null)
593         logger_ = AtgLogManager
594             .getLog(AtgConstantes.ATG_LOG_CATEGORY_METIER_DAO_JDO);
595     return logger_;
596   }
597 }