Java tutorial
/** * Copyright (C) 2008-2010, Squale Project - http://www.squale.org * * This file is part of Squale. * * Squale is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the * License, or any later version. * * Squale is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Squale. If not, see <http://www.gnu.org/licenses/>. */ package org.squale.squalix.core; import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; import java.util.GregorianCalendar; import java.util.Iterator; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.squale.jraf.commons.exception.JrafDaoException; import org.squale.jraf.commons.exception.JrafEnterpriseException; import org.squale.jraf.commons.exception.JrafPersistenceException; import org.squale.jraf.helper.PersistenceHelper; import org.squale.jraf.spi.persistence.IPersistenceProvider; import org.squale.jraf.spi.persistence.ISession; import org.squale.squalecommon.daolayer.component.ApplicationDAOImpl; import org.squale.squalecommon.daolayer.component.AuditDAOImpl; import org.squale.squalecommon.daolayer.component.ProjectDAOImpl; import org.squale.squalecommon.daolayer.result.MarkDAOImpl; import org.squale.squalecommon.daolayer.result.MeasureDAOImpl; import org.squale.squalecommon.daolayer.result.rulechecking.RuleCheckingTransgressionDAOImpl; import org.squale.squalecommon.datatransfertobject.config.ServeurDTO; import org.squale.squalecommon.datatransfertobject.config.SqualixConfigurationDTO; import org.squale.squalecommon.datatransfertobject.result.SqualeReferenceDTO; import org.squale.squalecommon.datatransfertobject.transform.component.AuditTransform; import org.squale.squalecommon.datatransfertobject.transform.config.AuditFrequencyTransform; import org.squale.squalecommon.enterpriselayer.businessobject.component.ApplicationBO; import org.squale.squalecommon.enterpriselayer.businessobject.component.AuditBO; import org.squale.squalecommon.enterpriselayer.businessobject.component.ProjectBO; import org.squale.squalecommon.enterpriselayer.businessobject.result.roi.RoiMetricsBO; import org.squale.squalecommon.enterpriselayer.facade.config.ServeurFacade; import org.squale.squalecommon.enterpriselayer.facade.config.SqualixConfigFacade; import org.squale.squalecommon.enterpriselayer.facade.quality.SqualeReferenceFacade; import org.squale.squalecommon.util.SqualeCommonConstants; import org.squale.squalecommon.util.SqualeCommonUtils; import org.squale.squalecommon.util.mail.IMailerProvider; import org.squale.squalecommon.util.mail.MailerHelper; import org.squale.squalix.core.exception.ConfigurationException; import org.squale.squalix.core.export.Export; import org.squale.squalix.core.purge.Purge; import org.squale.squalix.messages.MessageMailManager; import org.squale.squalix.messages.Messages; import org.squale.squalix.stats.ComputeStats; import org.squale.squalix.util.sourcesrecovering.SourcesRecoveringOptimisation; import org.squale.squalix.util.stoptime.StopTimeHelper; /** * A partir du fichier de configuration globale, il dtermine la squence des actions pour le projet associ et les * excute.<br /> * Le scheduler assure : * <ul> * <li>la rcupration de la configuration du moteur de tches,</li> * <li>la rcupration des audits lancer,</li> * <li>la cration d'un excuteur d'analyse (AuditExecutor) pour chacun des projets associs aux audits,</li> * <li>le lancement des tches indpendantes d'un projet,</li> * <li>le lancement des excuteurs d'analyse,</li> * <li>le lancement des tches calculant les rsultats au niveau du projet (graphes,...),</li> * <li>la modification du statut de l'audit lorsque celui-ci est termin, et la cration ventuelle du prochain audit * dans le cas d'un audit de suivi.</li> * </ul> * <br /> * Tous les audits et tches sont excuts via des pools de threads, grs par le gestionnaire de ressources.<br /> * Voir la documentation de la classe <code>ResourcesManager</code> pour plus de renseignements sur son fonctionnement. <br /> * <br /> * Lorsque tous les audits ont t lancs, les scheduler est bloqu tant que les pools sont ouverts.<br /> * Pour s'assurer que ceux-ci sont ouverts, on utilise un <code>CountDownLatch</code> dcrment par le gestionnaire de * ressources lorsqu'il ferme ses pools. <br /> * <br /> * Les tches non lies un projet et les excuteurs d'analyse sont associs au scheduler par un pattern * Observateur-Observable, dans lequel le scheduler est l'observateur. Sa mthode <code>update()</code> est appele * lorsque l'excuteur ou la tche est termin. * * @see org.squale.squalix.core.ResourcesManager * @see org.squale.squalix.core.AuditExecutor * @author m400842 * @version 1.0 */ public class Scheduler implements Runnable { /** * L'objet contenant les configurations */ private SqualixConfigurationDTO mConf; /** * Logger */ private static final Log LOGGER = LogFactory.getLog(Scheduler.class); /** * Liste des audits executeur cres. */ private List mAudits = new ArrayList(0); /** * Cl du site hbergeant l'application. */ private long mSiteId; /** * Provider de persistance */ private static final IPersistenceProvider PERSISTANT_PROVIDER = PersistenceHelper.getPersistenceProvider(); /** * Session de travail */ private ISession mSession; /** * Le calendrier permettant de savoir quel heure t lanc le batch */ private Calendar mLaunchingCal; /** la liste des projets d'un audit */ private List mProjectsByAudit; /** pour envoyer des mails */ private IMailerProvider mMailer = MailerHelper.getMailerProvider(); /** * Instantiate a scheduler. * * @param pSiteId Technical id of the Squalix server. * @param launchMail boolean which indicate if we want launch a mail * @throws ConfigurationException Si un problme de configuration apparat. * @roseuid 42935241035F */ public Scheduler(long pSiteId, boolean launchMail) throws ConfigurationException { try { mSession = PERSISTANT_PROVIDER.getSession(); mConf = SqualixConfigFacade.getConfig(); mLaunchingCal = Calendar.getInstance(); // If launchMail is true then we launch a mail fro indicat to the admins that squalix has been launched if (launchMail) { String sender = Messages.getString("mail.sender.squalix"); MessageMailManager mail = new MessageMailManager(); String object = sender + Messages.getString("mail.squalix.launch.object"); mail.addContent("mail.header", null); mail.addContent("mail.squalix.launch.content", null); String content = mail.getContent(); SqualeCommonUtils.notifyByEmail(mMailer, null, SqualeCommonConstants.ONLY_ADMINS, null, object, content, false); } } catch (JrafEnterpriseException e) { LOGGER.error(CoreMessages.getString("exception"), e); } catch (JrafPersistenceException e) { LOGGER.error(CoreMessages.getString("exception"), e); } mSiteId = pSiteId; } /** * Rcupre les audits raliser le jour prsent. * * @param pStopTime timer donnant l'arrt du batch * @return la liste des audits raliser ce jour * @throws JrafDaoException si un probleme de rcupration apparat. * @roseuid 42B7E4E30396 */ private List getAudits(StopTimeHelper pStopTime) throws JrafDaoException { mSession.beginTransaction(); // Rcupre les audits dont la date d'excution est // antrieure la date limite d'excution List audits = (List) AuditDAOImpl.getInstance().findBeforeBySiteAndStatus(mSession, mSiteId, AuditBO.NOT_ATTEMPTED, pStopTime.getLimitCal().getTime()); mSession.commitTransactionWithoutClose(); LOGGER.info(CoreMessages.getString("audits.toprocess", new Object[] { new Integer(audits.size()) })); return audits; } /** * Rcupre la liste des projets d'un audit, et excute les analyses dans l'ordre. L'audit est rattach chaque * projet * * @param pAudit Audit pour lequel on dsire obtenir la liste des projets * @return La collection des projets lis l'audit * @roseuid 42B7E54D0127 */ private List getProjectsByAudit(final AuditBO pAudit) { List list = new ArrayList(); try { Long id = new Long(pAudit.getId()); mSession.beginTransaction(); ApplicationBO application = ApplicationDAOImpl.getInstance().loadByAuditId(mSession, id); Collection children = application.getChildren(); if (null != children) { // Si l'application contient des projets, on les ajoute // la liste des projets analyser // pour cet audit. Iterator it = children.iterator(); Object obj = null; while (it.hasNext()) { obj = it.next(); if (obj instanceof ProjectBO) { ProjectBO project = (ProjectBO) obj; // Rattachement de l'audit au projet si celui-ci est actif if (project.getStatus() == ProjectBO.ACTIVATED) { project.addAudit(pAudit); ProjectDAOImpl.getInstance().save(mSession, project); list.add(project); } } } } mSession.commitTransactionWithoutClose(); } catch (Exception e) { // Si un problme de DAO apparat, l'exception est loggue LOGGER.error(CoreMessages.getString("exception"), e); } return list; } /** * Lance le scheduleur.<br> * * @roseuid 42CD2F0B0287 */ public void run() { try { // On lance le monitoring de la mmoire // MemoryMonitor.startMonitoring(new MemoryMonitorConfiguration()); StopTimeHelper stop = new StopTimeHelper(mConf, mLaunchingCal); if (LOGGER.isDebugEnabled()) { LOGGER.debug(CoreMessages.getString("time.limit", stop.getLimitCal().getTime())); } boolean canContinue = true; List audits = getAudits(stop); // Launch the export for the shared repository Thread export = null; Export exportTools = new Export(); export = exportTools.launchExport(mSiteId); // purge dans un thread parallele Purge prg = new Purge(mSiteId, audits); prg.start(); // Test si il y a des audits avec le status en cours pour le site concern // Si oui, c'est anormal, on prvient les administrateurs mais on continue quand meme // car c'est peut etre simplement un audit qui a t interrompu brutalement et a n'empechera // donc pas le nouveau de tourner if (existsAlreadyRunningAudits(mSiteId)) { // On envoie un mail pour signaler qu'un audit est en cours sur l'application String sender = Messages.getString("mail.sender.squalix"); String object = sender + Messages.getString("mail.running_audit.exists.object"); MessageMailManager mail = new MessageMailManager(); mail.addContent("mail.header", null); mail.addContent("mail.running_audit.exists.content", null); String content = mail.getContent(); String dest = SqualeCommonConstants.ONLY_ADMINS; // On envoir le mail qu'aux abonns SqualeCommonUtils.notifyByEmail(mMailer, null, dest, null, object, content, false); } // Excuter les audits launchAudits(audits, stop); // Mise jour des indicateurs DICT pour squale if (!audits.isEmpty()) { new ComputeStats().computeDICTStats(); } // Correction automatique de la frquence des audits si la configuration existe if (null != mConf.getFrequencies() && mConf.getFrequencies().size() > 0) { manageAuditFrequency(); } // Wait the end of the purge thread prg.join(); if (export != null) { export.join(); } LOGGER.info(CoreMessages.getString("endofexec")); // Fermeture de la session mSession.closeSession(); } catch (JrafDaoException e) { LOGGER.error(CoreMessages.getString("exception"), e); } catch (ConfigurationException e) { LOGGER.error(CoreMessages.getString("exception"), e); } catch (InterruptedException e) { // On n'a pas pu effectuer la purge correctement // On prvient les admins String sender = Messages.getString("mail.sender.squalix"); String object = sender + Messages.getString("mail.rotation.audit.shutDown.object"); MessageMailManager mail = new MessageMailManager(); mail.addContent("mail.header", null); mail.addContent("mail.rotation.audit.shutDown.content", null); String content = mail.getContent(); SqualeCommonUtils.notifyByEmail(mMailer, null, SqualeCommonConstants.ONLY_ADMINS, null, object, content, false); } } /** * On fait une passe sur toutes les applications ayant un audit programm pour vrifier les rgles dfini dans le * paramtrage de la frquence. On baisse ensuite la frquence des applications si besoin et on envoie un mail de * notification de changement de paramtrage l'administrateur de l'application et aux admins SQUALE. * * @throws JrafDaoException si erreur */ private void manageAuditFrequency() throws JrafDaoException { mSession.beginTransaction(); // On rcupre les applications du site qui ont un audit de suivi programm Collection applis = ApplicationDAOImpl.getInstance().findWhereHaveNotAttemptedAuditBySite(mSession, mSiteId); // Pour toutes les applis, on modifie la frquence en fonction de son dernier accs utilisateur ApplicationBO appli = null; // On sauvegarde l'ancienne valeur de la frquence pour le message du mail int oldFreq = 0; for (Iterator it = applis.iterator(); it.hasNext();) { appli = (ApplicationBO) it.next(); oldFreq = appli.getAuditFrequency(); // On change la frquence si ncessaire if (appli.changeFrequency(AuditFrequencyTransform.dto2bo(mConf.getFrequencies()))) { LOGGER.info("frequency has been changed for " + appli.getName()); // On sauvegarde les modifications ApplicationDAOImpl.getInstance().save(mSession, appli); // On envoit un mail d'information aux managers de l'application et aux admins SQUALE String sender = Messages.getString("mail.sender.squalix"); String object = sender + Messages.getString("mail.application_frequency.changed.object"); MessageMailManager mail = new MessageMailManager(); mail.addContent("mail.header", null); mail.addContent("mail.application_frequency.changed.content", new String[] { appli.getName(), "" + oldFreq, "" + appli.getAuditFrequency() }); String content = mail.getContent(); SqualeCommonUtils.notifyByEmail(mMailer, null, SqualeCommonConstants.MANAGERS_AND_ADMINS, null, object, content, false); } } mSession.commitTransactionWithoutClose(); } /** * @param pSiteId le nom du site * @return true si il existe des audits avec le status running pour ce site * @throws JrafDaoException en cas d'chec */ private boolean existsAlreadyRunningAudits(long pSiteId) throws JrafDaoException { return AuditDAOImpl.getInstance().countWhereStatusAndSite(mSession, pSiteId, AuditBO.RUNNING) != 0; } /** * @return un boolen indiquant si il faut faire la rpartition des audits ou pas * @throws JrafDaoException en cas d'echec de rcupration de l'audit */ private boolean isRotationDay() throws JrafDaoException { AuditDAOImpl auditDao = AuditDAOImpl.getInstance(); Calendar today = Calendar.getInstance(); Calendar auditDate = Calendar.getInstance(); Collection coll; boolean result = false; coll = auditDao.findRotationAudit(mSession); if (coll != null && coll.size() != 0) { Iterator it = coll.iterator(); // Normalement un seul rsultat while (it.hasNext()) { AuditBO audit = (AuditBO) it.next(); auditDate.setTime(audit.getDate()); result = audit.getDate() != null && auditDate.get(Calendar.DAY_OF_WEEK) <= today.get(Calendar.DAY_OF_WEEK); } } else { // On a pas pu trouver l'audit de rotation des partitions, // On en informe les admins ServeurDTO serveur = new ServeurDTO(); serveur = ServeurFacade.getServeur(mSiteId); String sender = Messages.getString("mail.sender.squalix"); String object = sender + Messages.getString("mail.rotation.audit.unknown.object", new String[] { serveur.getName() }); MessageMailManager mail = new MessageMailManager(); mail.addContent("mail.header", null); mail.addContent("mail.rotation.audit.unknown.content", null); String content = mail.getContent(); SqualeCommonUtils.notifyByEmail(mMailer, null, SqualeCommonConstants.ONLY_ADMINS, null, object, content, false); } return result; } /** * Lance les excutions des audits * * @param pAudits audits raliser. * @param pStopTime timer d'arrt du scheduler * @roseuid 42CE34390161 */ private void launchAudits(List pAudits, StopTimeHelper pStopTime) { if (null != pAudits) { Iterator it = pAudits.iterator(); AuditBO audit = null; // pour chaque audit lance les auditExecutors associs while (it.hasNext() && !pStopTime.isTimeToStop()) { SourcesRecoveringOptimisation.reinit(); audit = (AuditBO) it.next(); audit.setRealBeginningDate(Calendar.getInstance().getTime()); launchAudit(audit); audit.setEndDate(Calendar.getInstance().getTime()); // met jour le champ dure de l'audit en calculant // partir des dates de dbut et de fin audit.calculeDuration(); // Ne stocke pas la taille de la JVM car le rsultat n'est pas pertinent } // Affichage d'un message s'il reste des audits traiter if (it.hasNext()) { LOGGER.warn(CoreMessages.getString("time.limitreached")); } } } /** * Lance l'excution d'un audit et donc de tous ses excuteurs d'audit pour les projets que l'application contient * * @param pCurrentAudit l'audit lanc */ private void launchAudit(AuditBO pCurrentAudit) { AuditBO previousAudit = null; ApplicationBO application = null; // on passe tout de suite le status de l'audit "en cours" et on cre de suite // un nouvel audit pour viter les problmes lis l'interruption brutale du batch // enregistrement de l'audit try { mSession.beginTransaction(); pCurrentAudit.setStatus(AuditBO.RUNNING); // On met jour la version de SQUALE pCurrentAudit.setSqualeVersion(AuditBO.getCurrentSqualeVersion()); // On met la date tout de suite pour ne pas avoir de problmes avec les audits interrompus pCurrentAudit.setDate(Calendar.getInstance().getTime()); AuditDAOImpl.getInstance().save(mSession, pCurrentAudit); application = ApplicationDAOImpl.getInstance().loadByAuditId(mSession, new Long(pCurrentAudit.getId())); // On rcupre l'audit prcdent AuditDAOImpl dao = AuditDAOImpl.getInstance(); previousAudit = dao.getLastAuditByApplication(mSession, application.getId(), null, AuditBO.TERMINATED); createNewAudit(pCurrentAudit, application); mSession.commitTransactionWithoutClose(); // On met la variable termin par dfaut, de toute faon si on l'affecte alors la bonne valeur // a t traite dans la boucle suivante, et si on ne rentre pas dans la boucle // c'est qu'on avait rien faire mais on a pas eu d'erreurs int status = AuditBO.TERMINATED; // rcupre la liste des auditsExecutors // un AuditExecutor par projet de l'application de l'audit List aeList = getAuditExecutors(pCurrentAudit); // le nombre de projets pour cet audit // aeList ne peut pas etre null, au pire vide // lance les taches de l'auditExecutor for (int i = 0; i < aeList.size(); i++) { launchTasks((AuditExecutor) aeList.get(i)); // un audit failed est dfinitif if (status != AuditBO.FAILED) { // Si il n'est pas non plus partiel, on rcupre la valeur courante // Sinon, un status partial ne peut etre chang que pour un status failed // car failed est prioritaire sur partial int newStatus = ((AuditExecutor) aeList.get(i)).getFinalStatus(); if (status != AuditBO.PARTIAL || (status == AuditBO.PARTIAL && newStatus == AuditBO.FAILED)) { status = newStatus; } } } // on met jour le status de l'audit que si on a effectu tous les projets de l'application de l'audit pCurrentAudit.setStatus(status); // sauvegarde l'audit saveCurrentAudit(pCurrentAudit, application); // Notification : en cas de russite, on prvient les managers de l'application // que l'audit s'est bien pass String[] infos = new String[] { application.getName(), application.getServeurBO().getName() }; manageResultMailing(pCurrentAudit.getStatus(), infos, application.getId()); // On excute le calcul du ROI si l'audit a fonctionn et si l'application a un audit // termin qui prcde le courant if (pCurrentAudit.getStatus() == AuditBO.TERMINATED && null != previousAudit) { mSession.beginTransaction(); int nbCorrections = calculateNbCorrection(previousAudit, pCurrentAudit); createROI(nbCorrections, application, pCurrentAudit); mSession.commitTransactionWithoutClose(); } } catch (JrafDaoException e) { LOGGER.error(CoreMessages.getString("exception"), e); } } /** * Mthode qui gre l'envoi de mail en fonction du rsultat de l'audit * * @param pStatus le status de l'audit * @param pInfos les informations concernant l'audit pour le mail * @param pApplicationId l'id de l'application concerne */ private void manageResultMailing(int pStatus, String[] pInfos, long pApplicationId) { String dest = ""; String object = ""; String content = ""; boolean sendMail = false; String sender = Messages.getString("mail.sender.squalix.task", pInfos); MessageMailManager mail = new MessageMailManager(); if (pStatus == AuditBO.TERMINATED) { object = sender + Messages.getString("mail.audit.terminated.object", pInfos); mail.addContent("mail.header", null); mail.addContent("mail.audit.terminated.content", pInfos); content = mail.getContent(); dest = SqualeCommonConstants.MANAGERS_AND_READERS; sendMail = true; } else { // en cas d'chec, on prvient les administrateurs de SQUALE et // les managers de l'application concerne de l'chec if (pStatus == AuditBO.FAILED) { object = sender + Messages.getString("mail.audit.failed.object", pInfos); mail.addContent("mail.header", null); mail.addContent("mail.audit.failed.content", pInfos); content = mail.getContent(); dest = SqualeCommonConstants.MANAGERS_AND_ADMINS; sendMail = true; } else { // en cas d'chec, on prvient les administrateurs de SQUALE et // les managers de l'application concerne de l'chec if (pStatus == AuditBO.PARTIAL) { object = sender + Messages.getString("mail.audit.partial.object", pInfos); mail.addContent("mail.header", null); mail.addContent("mail.audit.partial.content", pInfos); content = mail.getContent(); dest = SqualeCommonConstants.MANAGERS_AND_ADMINS; sendMail = true; } } } // On envoie un email aux utilisateurs abonns selon le statut de l'audit if (sendMail) { // complment d'infos SqualeCommonUtils.notifyByEmail(mMailer, null, dest, new Long(pApplicationId), object, content, false); } } /** * Sauvegarde le roi calcul en base * * @param pValue le nombre de correction * @param pApplication l'application courante * @param pAudit l'audit courant * @throws JrafDaoException si erreur */ public void createROI(int pValue, ApplicationBO pApplication, AuditBO pAudit) throws JrafDaoException { RoiMetricsBO roi = new RoiMetricsBO(); roi.setNbCorrections(pValue); roi.setComponent(pApplication); roi.setAudit(pAudit); // Initialisation du DAO MeasureDAOImpl roiDAO = MeasureDAOImpl.getInstance(); roiDAO.create(mSession, roi); } /** * Calcule le nombre de corrections pour l'audit courant pour le ROI * * @param pPreviousAudit l'audit prcdent * @param pCurrentAudit l'audit courant * @return le nombre de corrections faites entre les deux audits * @throws JrafDaoException si erreur */ public int calculateNbCorrection(AuditBO pPreviousAudit, AuditBO pCurrentAudit) throws JrafDaoException { int nbProgressions = 0; int nbSuppressions = 0; int transgressionDiff = 0; if (pCurrentAudit.getRealDate().before(pPreviousAudit.getRealDate())) { // On ne calcule pas le nombre de correction si il s'agit d'un audit de jalon intercal LOGGER.info( CoreMessages.getString("roi.not_calculated", new Object[] { new Long(pCurrentAudit.getId()) })); } else { /* On rcupre le nombre de corrections faites entre les deux audits */ Long auditId = new Long(pCurrentAudit.getId()); Long previousAuditId = new Long(pPreviousAudit.getId()); MarkDAOImpl markDao = MarkDAOImpl.getInstance(); // Les composants qui sont passs de zro 1, 2 ou 3 nbProgressions = markDao.findCorrectionsWithProgessions(mSession, auditId, previousAuditId); // Les composants qui taient zro et qui n'existent plus nbSuppressions = markDao.findCorrectionsWithSuppressions(mSession, auditId, previousAuditId); // La progression du nombre de transgressions de niveau erreur et warning RuleCheckingTransgressionDAOImpl ruleDao = RuleCheckingTransgressionDAOImpl.getInstance(); int nbTransgressions = ruleDao.findNbErrorAndWarning(mSession, auditId); int nbPreviousTransgressions = ruleDao.findNbErrorAndWarning(mSession, previousAuditId); transgressionDiff = nbPreviousTransgressions - nbTransgressions; if (transgressionDiff <= 0) { transgressionDiff = 0; } } return nbProgressions + nbSuppressions + transgressionDiff; } /** * Lance les tches . * * @param pAuditExec l'executeur d'audit . * @roseuid 42CE30D601DD */ private void launchTasks(AuditExecutor pAuditExec) { // lance les taches de l'auditExecutor pAuditExec.run(); } /** * @param pAudit audit d'applications raliser. * @return Retourne une liste d'executeur d'audits pour l'audit en parametre.<br> * @roseuid 42CE37D70124 */ private List getAuditExecutors(final AuditBO pAudit) { AuditExecutor ae = null; List aeList = new ArrayList(0); ProjectBO project = null; // La liste des taches effectuer List analyze = new ArrayList(0); // La liste des taches de terminaison effectuer dans tous les cas List termination = new ArrayList(0); // La liste des taches effectuer pour rcuprer les sources List analyzeSource = new ArrayList(0); // La liste des taches de terminaison effectuer pour la rcupration // de sources, comme le dmontage de la vue clearcase... List terminationSource = new ArrayList(0); // La liste des taches de profil List analyzeProfil = new ArrayList(0); // La liste des taches de terminaison de profil effectuer List terminationProfil = new ArrayList(0); try { // On rcupre tous les projets analyser pour cet audit mProjectsByAudit = getProjectsByAudit(pAudit); Iterator it = mProjectsByAudit.iterator(); while (it.hasNext()) { // Pour chaque projet, on cre un excuteur d'audit, // grant le type de rcuprateur de source associ au projet et // dpendant du profil du projet project = (ProjectBO) it.next(); analyzeSource = project.getSourceManager().getAnalysisTasks(); terminationSource = project.getSourceManager().getTerminationTasks(); String profile = project.getProfile().getName(); analyzeProfil = project.getProfile().getAnalysisTasks(); terminationProfil = project.getProfile().getTerminationTasks(); // Il y a 2 types de taches (analyse ou terminale) combinable // avec 2 types de fonction (rcupration de source ou profil) // il faut faire dans l'ordre: // * Taches d'analyse de rcupration de source // * Taches d'analyse du profil // * Taches terminales du profil // * Taches terminales de rcupration de source analyze.addAll(analyzeSource); analyze.addAll(analyzeProfil); termination.addAll(terminationProfil); termination.addAll(terminationSource); // Es-ce le dernier projet de l'audit ? boolean lastProject = false; if (!it.hasNext()) { lastProject = true; } // creation de lauditexecutor associ ae = new AuditExecutor(analyze, termination, pAudit, project, lastProject); ae.setScheduler(this); aeList.add(ae); mAudits.add(ae); analyze = new ArrayList(0); termination = new ArrayList(0); } } catch (Exception e) { LOGGER.error(CoreMessages.getString("exception"), e); pAudit.setStatus(AuditBO.FAILED); } return aeList; } /** * Ralise les tches de niveau application (cration des graphes, calculs,...) * * @param pCurrentAudit l'audit courant. * @param pApplicationBO l'application sur lequel calculer les rsultats. * @roseuid 42CE40E102B8 */ private void createNewAudit(final AuditBO pCurrentAudit, final ApplicationBO pApplicationBO) { ApplicationBO application = null; // on ne cre pas de nouvelles transactions car il faut faut que la transaction // pour cette mthode soit la meme que pour la mthode appelante de cette mthode try { Long applicationId = new Long(pApplicationBO.getId()); application = (ApplicationBO) ApplicationDAOImpl.getInstance().get(mSession, applicationId); GregorianCalendar cal = new GregorianCalendar(); // Cration d'un nouvel audit si il s'agit d'un audit de suivi if (pCurrentAudit.getType().equals(AuditBO.NORMAL)) { // Cration d'un nouvel audit AuditBO audit = new AuditBO(); // Ajout de la frquence d'audit la date courante cal.add(Calendar.DATE, pApplicationBO.getAuditFrequency()); audit.setDate(cal.getTime()); audit.setStatus(AuditBO.NOT_ATTEMPTED); audit.setType(pCurrentAudit.getType()); AuditDAOImpl.getInstance().create(mSession, audit); // Ajout du nouvel audit l'application application.addAudit(audit); ApplicationDAOImpl.getInstance().save(mSession, application); } } catch (Exception e) { LOGGER.error(CoreMessages.getString("exception"), e); } } /** * enregistre l'audit courant * * @param pCurrentAudit l'audit courant * @param pApplicationBO l'application lie l'audit */ private void saveCurrentAudit(final AuditBO pCurrentAudit, final ApplicationBO pApplicationBO) { ApplicationBO application = null; try { Long applicationId = new Long(pApplicationBO.getId()); mSession.beginTransaction(); application = (ApplicationBO) ApplicationDAOImpl.getInstance().get(mSession, applicationId); Long auditId = new Long(pCurrentAudit.getId()); GregorianCalendar cal = new GregorianCalendar(); AuditBO finishedAudit = (AuditBO) AuditDAOImpl.getInstance().get(mSession, auditId); // Remet jour la date relle de l'audit finishedAudit.setDate(Calendar.getInstance().getTime()); finishedAudit.setStatus(pCurrentAudit.getStatus()); // sauvegarde l'audit AuditDAOImpl.getInstance().save(mSession, finishedAudit); // on commit pour sauvegarder le status de l'audit mSession.commitTransactionWithoutClose(); mSession.beginTransaction(); // Ajoute l'audit russit dans le Referenciel manageSqualeReference(finishedAudit, pApplicationBO.getName(), pApplicationBO.getId()); mSession.commitTransactionWithoutClose(); } catch (Exception e) { LOGGER.error(CoreMessages.getString("exception"), e); } } /** * @param pAudit l'audit courant termin * @param pAppliName le nom de l'application recherch * @param pAppliId l'id de l'application pour la transformation * @throws JrafEnterpriseException en cas d'chec de sauvegarde de l'outil */ private void manageSqualeReference(AuditBO pAudit, String pAppliName, long pAppliId) throws JrafEnterpriseException { boolean insert = false; SqualeReferenceDTO storedAudit = SqualeReferenceFacade.getReferencedAudit(pAppliName, mSession); // Les diffrentes rgles suivantes sont priorises // 1) On ne peut ajouter au rfrentiel que des audits termins // 2) Si aucun audit n'est dj prsent en base, on insre le courant de toute facon // 3) les audits de jalon sont prioritaires // 4) On garde l'audit le plus rcent if (pAudit.getStatus() == AuditBO.TERMINATED && (null == storedAudit || ((AuditBO.NORMAL.equals(storedAudit.getAuditType()) && AuditBO.MILESTONE.equals(pAudit.getType())) || (storedAudit.getAuditType().equals(pAudit.getType()) && pAudit.getDate().getTime() > storedAudit.getDate().getTime())))) { SqualeReferenceFacade.insertAudit(AuditTransform.bo2Dto(pAudit, pAppliId), mSession); } } }