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.stats; import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; import java.util.Date; import java.util.GregorianCalendar; import java.util.Iterator; import java.util.List; import java.util.Set; 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.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.config.ProjectProfileDAOImpl; import org.squale.squalecommon.daolayer.config.web.AbstractDisplayConfDAOImpl; import org.squale.squalecommon.daolayer.result.MeasureDAOImpl; import org.squale.squalecommon.daolayer.result.MetricDAOImpl; import org.squale.squalecommon.daolayer.result.QualityResultDAOImpl; import org.squale.squalecommon.daolayer.result.SimpleFormulaDAOImpl; import org.squale.squalecommon.daolayer.stats.SiteAndProfilStatsDICTDAOImpl; import org.squale.squalecommon.daolayer.stats.SiteStatsDICTDAOImpl; import org.squale.squalecommon.datatransfertobject.config.ServeurDTO; import org.squale.squalecommon.enterpriselayer.businessobject.component.ApplicationBO; import org.squale.squalecommon.enterpriselayer.businessobject.component.AuditBO; import org.squale.squalecommon.enterpriselayer.businessobject.config.Profile_DisplayConfBO; import org.squale.squalecommon.enterpriselayer.businessobject.config.ProjectProfileBO; import org.squale.squalecommon.enterpriselayer.businessobject.config.web.AbstractDisplayConfBO; import org.squale.squalecommon.enterpriselayer.businessobject.config.web.VolumetryConfBO; import org.squale.squalecommon.enterpriselayer.businessobject.result.IntegerMetricBO; import org.squale.squalecommon.enterpriselayer.businessobject.result.QualityResultBO; import org.squale.squalecommon.enterpriselayer.businessobject.rule.SimpleFormulaBO; import org.squale.squalecommon.enterpriselayer.businessobject.stats.SiteAndProfilStatsDICTBO; import org.squale.squalecommon.enterpriselayer.businessobject.stats.SiteStatsDICTBO; import org.squale.squalecommon.enterpriselayer.facade.roi.RoiFacade; import org.squale.squalecommon.enterpriselayer.facade.rule.FormulaException; import org.squale.squalecommon.enterpriselayer.facade.component.ServeurFacade; import org.squale.squalecommon.util.mapping.Mapping; import org.squale.squalix.core.CoreMessages; /** */ public class ComputeStats { // TODO voir avec laurent et nicolas comment le moteur d'indicateur SQUALE // fournit ce paramtre (SEB) /** Le nombre de mois prcdents pris en compte */ private final static int NB_MONTHS = 2; /** Le nombre de chiffres pour l'arrondi */ private final static int NB_DIGITS = 2; /** * Logger */ private static final Log LOGGER = LogFactory.getLog(ComputeStats.class); /** * Provider de persistance */ private static final IPersistenceProvider PERSISTANT_PROVIDER = PersistenceHelper.getPersistenceProvider(); /** * Session de travail */ private ISession mSession; /** Constructeur */ public ComputeStats() { try { mSession = PERSISTANT_PROVIDER.getSession(); // on instancie les diffrents DAO ncessaires profileDao = ProjectProfileDAOImpl.getInstance(); appliDao = ApplicationDAOImpl.getInstance(); resultDao = QualityResultDAOImpl.getInstance(); measureDao = MeasureDAOImpl.getInstance(); formulaDAO = SimpleFormulaDAOImpl.getInstance(); metricDao = MetricDAOImpl.getInstance(); siteAndProfilDao = SiteAndProfilStatsDICTDAOImpl.getInstance(); siteDao = SiteStatsDICTDAOImpl.getInstance(); auditDao = AuditDAOImpl.getInstance(); projectDao = ProjectDAOImpl.getInstance(); } catch (JrafPersistenceException e) { LOGGER.error(CoreMessages.getString("exception"), e); } } /** les diffrents DAO ncessaires au calcul */ /** pour les stats concernant les profils */ private ProjectProfileDAOImpl profileDao; /** pour le nombre de projets */ private ProjectDAOImpl projectDao; /** pour les applications */ private ApplicationDAOImpl appliDao; /** pour la volumtrie */ private MetricDAOImpl metricDao; /** pour les audits */ private AuditDAOImpl auditDao; /** pour les stats facteurs */ private QualityResultDAOImpl resultDao; /** pour le roi */ private MeasureDAOImpl measureDao; /** pour la formule du roi */ private SimpleFormulaDAOImpl formulaDAO; /** Les DAO pour l'enregistrement en base */ /** DAO pour enregistrer les SiteStatsDICTBO */ private SiteAndProfilStatsDICTDAOImpl siteAndProfilDao; /** DAO pour enregistrer les StatsDICTBO */ private SiteStatsDICTDAOImpl siteDao; /** * Calcule et enregistre en base les diffrents statistiques ncessaires au calcul des indicateurs SQUALE pour DICT * Ces statistiques sont: Le nombre total d'appli (par site) Le nombre total d'appli avec un audit excut depuis n * mois Le nombre total d'appli avec un audit russi depuis n mois Le nombre de lignes de codes par site et par * profil Le nombre de facteurs accepts / accepts avec rserves / refuss Le ROI en ke par site */ public void computeDICTStats() { try { // la liste des StatsDICTBO, un par site List siteStatsList = new ArrayList(0); // la liste des SiteStatsDICTBO, il y en a // un par site et par profil, soit nbSites*nbProfils List siteProfilStatsList = new ArrayList(0); // on rcupre la liste des profils disponibles Collection profiles = profileDao.findAll(mSession); // Pour chaque site, on cre un SiteStatsDICTBO // Pour chaque combinaison site/profil, on cre un SiteStatsDICTBO Collection lServeurList = new ArrayList(); try { lServeurList = ServeurFacade.listeServeurs(); } catch (Exception e) { } Iterator lServeurListIt = lServeurList.iterator(); for (int i = 0; i < lServeurList.size(); i++) { ServeurDTO lServeurDTO = (ServeurDTO) lServeurListIt.next(); long lSiteId = lServeurDTO.getServeurId(); int nbAppli = appliDao.countWhereSite(mSession, lSiteId); int nbAppliWithAudit = appliDao.countWhereHaveOnlyFailedAudit(mSession, lSiteId); int nbAppliWithAuditSuccessful = appliDao.countWhereHaveAuditByStatus(mSession, lSiteId, new Integer(AuditBO.TERMINATED), null); int nbAppliWithoutAudits = appliDao.countWhereHaveNoAudits(mSession, lSiteId); int nbApplisToValidate = appliDao.countNotValidate(mSession, lSiteId); int nbFactorsAcc = resultDao.countFactorsByAcceptanceLevelAndSite(mSession, QualityResultBO.ACCEPTED, lSiteId); int nbFactorsRes = resultDao.countFactorsByAcceptanceLevelAndSite(mSession, QualityResultBO.RESERVED, lSiteId); int nbFactorsRef = resultDao.countFactorsByAcceptanceLevelAndSite(mSession, QualityResultBO.REFUSED, lSiteId); int nbAuditsFailed = auditDao.countWhereStatusAndSite(mSession, lSiteId, AuditBO.FAILED); int nbAuditsSuccessfuls = auditDao.countWhereStatusAndSite(mSession, lSiteId, AuditBO.TERMINATED); int nbAuditsPartials = auditDao.countWhereStatusAndSite(mSession, lSiteId, AuditBO.PARTIAL); int nbAuditsNotAttempted = auditDao.countWhereStatusAndSite(mSession, lSiteId, AuditBO.NOT_ATTEMPTED); double roi = calculateGlobalROI(lSiteId); siteStatsList .add(new SiteStatsDICTBO(lSiteId, nbAppli, nbAppliWithAudit, nbAppliWithAuditSuccessful, nbAppliWithoutAudits, nbApplisToValidate, nbFactorsAcc, nbFactorsRes, nbFactorsRef, nbAuditsFailed, nbAuditsSuccessfuls, nbAuditsPartials, nbAuditsNotAttempted, roi)); // Les stats concernant les profils et les sites Iterator it = profiles.iterator(); while (it.hasNext()) { ProjectProfileBO profile = (ProjectProfileBO) it.next(); //The name of the profile String profileName = (profile).getName(); //The number of code line by profile Set profileDisplayConfList = profile.getProfileDisplayConfs(); Iterator<Profile_DisplayConfBO> profileDisplayConfIt = profileDisplayConfList.iterator(); boolean found = false; //Profile_DisplayConfBO porfileDisplayConf = null; AbstractDisplayConfBO displayConf = null; AbstractDisplayConfDAOImpl displayConfDAO = AbstractDisplayConfDAOImpl.getInstance(); while (profileDisplayConfIt.hasNext() && !found) { displayConf = (AbstractDisplayConfBO) displayConfDAO.get(mSession, profileDisplayConfIt.next().getDisplayConf().getId()); if (displayConf instanceof VolumetryConfBO && ((VolumetryConfBO) displayConf).getComponentType().equals("project")) { found = true; } } Set treList = ((VolumetryConfBO) displayConf).getTres(); Iterator<String> treNameIt = treList.iterator(); String volumetryType; ArrayList<String> metricList = new ArrayList<String>(); while (treNameIt.hasNext()) { String treName = (String) treNameIt.next(); volumetryType = Mapping.getVolumetryType(treName); if (volumetryType.startsWith(Mapping.VOLUMETRY_NB_CODES_LINES)) { metricList.add(treName); } } int nbLines = metricDao.getVolumetryBySiteAndProfil(mSession, lSiteId, profileName, metricList); // Number of projects by profile int nbProjects = projectDao.countBySiteAndProfil(mSession, lSiteId, profileName); siteProfilStatsList .add(new SiteAndProfilStatsDICTBO(lSiteId, profileName, nbLines, nbProjects)); } } // enregistre les rsultats en base storeResults(siteStatsList, siteProfilStatsList); LOGGER.info("Statistics 'calculation done"); } catch (JrafDaoException e) { LOGGER.error(CoreMessages.getString("exception"), e); } } /** * @return la date courante moins le nombre de mois dfinis */ private Date getBeginDate() { GregorianCalendar cal = new GregorianCalendar(); long today = Calendar.getInstance().getTimeInMillis(); cal.add(GregorianCalendar.MONTH, 0 - NB_MONTHS); return cal.getTime(); } /** * Enregistre les rsultats en base * * @param siteStatsList la liste des StatsDICTBO, un par site * @param siteProfilStatsList // la liste des SiteStatsDICTBO, un par site et par profil * @throws JrafDaoException en cas d'chec de l'enregistrement en base des stats */ private void storeResults(List siteStatsList, List siteProfilStatsList) throws JrafDaoException { // on cre une transaction car il faut d'abord enregister les objets // de type SiteStatsDICTBO , committer et ensuite enregister les // objets SiteAndProfilStatsDICTBO for (int i = 0; i < siteStatsList.size(); i++) { SiteStatsDICTBO site = (SiteStatsDICTBO) siteStatsList.get(i); // on commence par supprimer toutes les stats concernant ce site // vite les doublons et permet d'viter le test est-ce que ca existe dj ou pas // pour savoir si il faut faire un update ou un create mSession.beginTransaction(); // suppression // commence par supprimer les stats annexes sur le site siteAndProfilDao.removeWhereSite(mSession, site.getServeurBO().getServeurId()); siteDao.removeWhereSite(mSession, site.getServeurBO().getServeurId()); mSession.commitTransactionWithoutClose(); mSession.beginTransaction(); // cration siteDao.create(mSession, site); mSession.commitTransactionWithoutClose(); } // maintenant ont peut enregistrer les SiteAndProfilStatsDICTBO for (int i = 0; i < siteProfilStatsList.size(); i++) { SiteAndProfilStatsDICTBO siteAndProfil = (SiteAndProfilStatsDICTBO) siteProfilStatsList.get(i); // on commence par supprimer toutes les stats concernant ce site et ce profil // vite les doublons et permet d'viter le test est-ce que ca existe dj ou pas // pour savoir si il faut faire un update ou un create mSession.beginTransaction(); // suppression siteAndProfilDao.removeWhereSiteAndProfil(mSession, siteAndProfil.getServeurBO().getServeurId(), siteAndProfil.getProfil()); mSession.commitTransactionWithoutClose(); mSession.beginTransaction(); // cration siteAndProfilDao.create(mSession, siteAndProfil); mSession.commitTransactionWithoutClose(); } } /** * Calcul le roi sur l'ensemble des applications du site * * @param pSiteId l'id du site * @return le roi global du site * @throws JrafDaoException en cas d'chec */ private double calculateGlobalROI(long pSiteId) throws JrafDaoException { int result = 0; Collection appliList = appliDao.findWhereSite(mSession, pSiteId); // Pour toutes les applis, on rcupre tous les diffrents nombres de corrections // sur les audits fait depuis la plage donne Iterator it = appliList.iterator(); while (it.hasNext()) { ApplicationBO appli = (ApplicationBO) it.next(); Collection rois = metricDao.findROIWhereApplicationSinceDate(mSession, new Long(appli.getId()), getBeginDate()); Iterator itRois = rois.iterator(); while (itRois.hasNext()) { IntegerMetricBO roiBo = (IntegerMetricBO) itRois.next(); result += ((Integer) roiBo.getValue()).intValue(); } } // pour l'instant le rsultat est en nombre de corrections // et on doit le calculer en nombre de MHI // on enregistre la valeur -1 en cas de problmes avec le calcul du roi double ke = -1; try { ke = computeRoiMHI(result); } catch (FormulaException e) { LOGGER.error( "Problems encountered while calculating squale's stats: roi formula not found or uncorrect"); } return ke; } /** * @param pNbCorrections le nombre total de corrections sur toutes les applications * @return le roi en ke en fonction du nombre de corrections et de la formule courante * @throws JrafDaoException en cas d'chec * @throws FormulaException si erreur ai niveau de la formule */ private double computeRoiMHI(int pNbCorrections) throws JrafDaoException, FormulaException { double result = 0; // On rcupre l'unique formule du ROI en base SimpleFormulaBO roiFormula = formulaDAO.getRoiFormula(mSession); float MhiRoi = RoiFacade.calculateROI(pNbCorrections, roiFormula); // arrondi NB_DIGITS chiffres aprs la virgule int number = (int) Math.pow(10, NB_DIGITS); result = ((int) (MhiRoi * number)) / number; return result; } }