/** * 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.squalecommon.enterpriselayer.facade.quality; import java.text.DateFormat; import java.text.NumberFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.SortedMap; import java.util.TreeMap; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jfree.chart.JFreeChart; 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.provider.persistence.hibernate.facade.FacadeHelper; import org.squale.jraf.spi.enterpriselayer.IFacade; import org.squale.jraf.spi.persistence.IPersistenceProvider; import org.squale.jraf.spi.persistence.ISession; import org.squale.squalecommon.daolayer.component.AbstractComponentDAOImpl; import org.squale.squalecommon.daolayer.component.ApplicationDAOImpl; import org.squale.squalecommon.daolayer.component.AuditDAOImpl; import org.squale.squalecommon.daolayer.component.AuditDisplayConfDAOImpl; import org.squale.squalecommon.daolayer.component.AuditGridDAOImpl; 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.MetricDAOImpl; import org.squale.squalecommon.daolayer.result.QualityResultDAOImpl; import org.squale.squalecommon.daolayer.rule.PracticeRuleAPDAOImpl; import org.squale.squalecommon.datatransfertobject.component.AuditDTO; import org.squale.squalecommon.datatransfertobject.component.ComponentDTO; import org.squale.squalecommon.datatransfertobject.result.QualityResultDTO; import org.squale.squalecommon.datatransfertobject.result.ResultsDTO; import org.squale.squalecommon.datatransfertobject.transform.component.AuditTransform; import org.squale.squalecommon.datatransfertobject.transform.component.ComponentTransform; import org.squale.squalecommon.datatransfertobject.transform.result.MeasureTransform; import org.squale.squalecommon.datatransfertobject.transform.result.QualityResultTransform; import org.squale.squalecommon.enterpriselayer.businessobject.component.AbstractComponentBO; import org.squale.squalecommon.enterpriselayer.businessobject.component.ApplicationBO; import org.squale.squalecommon.enterpriselayer.businessobject.component.AuditBO; import org.squale.squalecommon.enterpriselayer.businessobject.component.AuditDisplayConfBO; import org.squale.squalecommon.enterpriselayer.businessobject.component.AuditGridBO; import org.squale.squalecommon.enterpriselayer.businessobject.component.ProjectBO; import org.squale.squalecommon.enterpriselayer.businessobject.config.web.BubbleConfBO; import org.squale.squalecommon.enterpriselayer.businessobject.config.web.DisplayConfConstants; import org.squale.squalecommon.enterpriselayer.businessobject.config.web.VolumetryConfBO; import org.squale.squalecommon.enterpriselayer.businessobject.result.FactorResultBO; import org.squale.squalecommon.enterpriselayer.businessobject.result.IntegerMetricBO; import org.squale.squalecommon.enterpriselayer.businessobject.result.MarkBO; import org.squale.squalecommon.enterpriselayer.businessobject.result.MeasureBO; import org.squale.squalecommon.enterpriselayer.businessobject.result.PracticeResultBO; import org.squale.squalecommon.enterpriselayer.businessobject.rule.PracticeRuleBO; import org.squale.squalecommon.util.TimeUtil; import org.squale.squalecommon.util.manualmark.TimeLimitationParser; import org.squale.squalecommon.util.mapping.Mapping; /** * The facade for the result information shown in the web portal */ public final class MeasureFacade implements IFacade { /** * Cle de tre relatif a l'historique */ private static final String HISTORIC_TYPE = "tre.graph.histo"; /** log */ private static Log LOG = LogFactory.getLog( MeasureFacade.class ); /** * provider de persistence */ private static final IPersistenceProvider PERSISTENTPROVIDER = PersistenceHelper.getPersistenceProvider(); /** * Permet de r�cup�rer une valeur pour un type de r�sultat, un composant et un audit donn� Format de ResultsDTO : 1 * ligne : -- null en cl� et liste contenant le resultat en valeur * * @param pAudit AuditDTO contenant l'ID de l'audit * @param pComponent ComponentDTO contenant l'ID du composant * @param pKeyTRE Cl� du type �l�mentaire de r�sultat * @return ResultsDTO correspondant � une valeur * @throws JrafEnterpriseException exception JRAF * @roseuid 42CBFFB4016D */ public static ResultsDTO getMeasures( AuditDTO pAudit, ComponentDTO pComponent, String pKeyTRE ) throws JrafEnterpriseException { ResultsDTO results = null; MeasureDAOImpl measureDAO = MeasureDAOImpl.getInstance(); ISession session = null; try { session = PERSISTENTPROVIDER.getSession(); Long idComponent = new Long( pComponent.getID() ); Long idAudit = new Long( pAudit.getID() ); MeasureBO measure = measureDAO.load( session, idComponent, idAudit, Mapping.getMetricClass( pKeyTRE ) ); results = MeasureTransform.bo2dto( measure, pKeyTRE ); } catch ( JrafDaoException e ) { FacadeHelper.convertException( e, MeasureFacade.class.getName() + ".getMeasures" ); } finally { FacadeHelper.closeSession( session, MeasureFacade.class.getName() + ".getMeasures" ); } return results; } /** * Permet de r�cup�rer une liste de valeurs pour une liste de types de r�sultat, un type de composant et un audit * donn� Format de ResultsDTO : 2 lignes : -- null en cl� et liste des cl�s des TREs en valeur -- ComponentDTO en * cl� et liste des r�sultats associ�es en valeur * * @param pAudit AuditDTO contenant l'ID de l'audit * @param pComponent ComponentDTO contenant l'ID du composant * @return ResultsDTO * @throws JrafEnterpriseException exception JRAF * @roseuid 42CBFFB40181 */ public static ResultsDTO getAllMeasures( AuditDTO pAudit, ComponentDTO pComponent ) throws JrafEnterpriseException { // D�claration du ResultsDTO � retourner ResultsDTO results = null; Collection trClasses = null; MeasureDAOImpl measureDAO = MeasureDAOImpl.getInstance(); // Session Hibernate ISession session = null; try { // R�cup�ration d'une session session = PERSISTENTPROVIDER.getSession(); // R�cup�ration des id de l'audit et du composant Long idComponent = new Long( pComponent.getID() ); Long idAudit = new Long( pAudit.getID() ); // R�cup�ration des mesures souhait�es Collection measures = measureDAO.findWhere( session, idComponent, idAudit ); // transformation de la liste de mesures en ResultsDTO results = MeasureTransform.bo2dtoByTRE( null, measures, pComponent ); // Pour la 3.0, on conserve les mesures mcCabe concernant le nombre de m�thodes et de classes sur un projet // On supprime (ATTENTION : seulement de l'affichage) donc les donn�es RSM �quivalentes pour ne pas faire // doublon // Toutefois on garde le stockage des donn�es en base // On r�cup�re les index des cl�s pour pouvoir supprimer les valeurs aussi int indexClasses = ( (List) ( results.getResultMap().get( null ) ) ).indexOf( "rsm.project.numberOfClasses" ); int indexMeth = ( (List) ( results.getResultMap().get( null ) ) ).indexOf( "rsm.project.numberOfMethods" ); // Supprime les cl�s ( (List) ( results.getResultMap().get( null ) ) ).remove( "rsm.project.numberOfClasses" ); ( (List) ( results.getResultMap().get( null ) ) ).remove( "rsm.project.numberOfMethods" ); // Supprime les valeurs // On supprime d'abord le plus grand index pour �viter les d�calages if ( indexClasses != -1 ) { if ( indexMeth != -1 ) { if ( indexClasses > indexMeth ) { ( (List) ( results.getResultMap().get( pComponent ) ) ).remove( indexClasses ); ( (List) ( results.getResultMap().get( pComponent ) ) ).remove( indexMeth ); } else { ( (List) ( results.getResultMap().get( pComponent ) ) ).remove( indexMeth ); ( (List) ( results.getResultMap().get( pComponent ) ) ).remove( indexClasses ); } } else { ( (List) ( results.getResultMap().get( pComponent ) ) ).remove( indexClasses ); } } else { if ( indexMeth != -1 ) { ( (List) ( results.getResultMap().get( pComponent ) ) ).remove( indexMeth ); } } } catch ( JrafDaoException e ) { FacadeHelper.convertException( e, MeasureFacade.class.getName() + ".getMeasuresByTRE" ); } finally { FacadeHelper.closeSession( session, MeasureFacade.class.getName() + ".getMeasuresByTRE" ); } return results; } /** * Permet de r�cup�rer une liste des "tops" composant / measure pour un audit et un tre donn�s Format de ResultsDTO * : 2 lignes : -- null en cl� et liste des ComponentDTOs -- AuditDTO en cl� et liste des r�sultats associ�es en * valeur * * @param pProject projet * @param pComponentType Type de composant (Method ou Class) * @param pAudit Audit * @param pTre Tre � retrouver et tri� * @param pMax nombre maxi de resultat retoun� * @return ResultsDTO tri� * @throws JrafEnterpriseException exception JRAF */ public static ResultsDTO getTop( ComponentDTO pProject, String pComponentType, AuditDTO pAudit, String pTre, Integer pMax ) throws JrafEnterpriseException { ResultsDTO results = null; MeasureDAOImpl measureDAO = MeasureDAOImpl.getInstance(); // Session Hibernate ISession session = null; try { session = PERSISTENTPROVIDER.getSession(); List component_measures = (List) measureDAO.findTop( session, pProject.getID(), Mapping.getComponentClass( pComponentType ), pAudit.getID(), pTre, pMax ); if ( component_measures.size() > 0 ) { // Transformation de la liste de mesures en ResultDTO results = MeasureTransform.bo2dtoByAuditOrComponent( null, component_measures, pAudit ); } } catch ( JrafDaoException e ) { FacadeHelper.convertException( e, MeasureFacade.class.getName() + ".getMeasuresByTRE" ); } finally { FacadeHelper.closeSession( session, MeasureFacade.class.getName() + ".getMeasuresByTRE" ); } return results; } /** * Retrieves components which have a precise score for some tres * * @param pProjectId project id * @param pAuditId Audit id * @param pTreKeys keys of tres to find * @param pTreValues value of tres * @param pMax number of components max to return * @return list of components * @throws JrafEnterpriseException if error */ public static List<ComponentDTO> getComponentsWhereTres( Long pProjectId, Long pAuditId, String[] pTreKeys, String[] pTreValues, Integer pMax ) throws JrafEnterpriseException { List<ComponentDTO> components = new ArrayList<ComponentDTO>(); AbstractComponentDAOImpl dao = AbstractComponentDAOImpl.getInstance(); // Hibernate session ISession session = null; try { session = PERSISTENTPROVIDER.getSession(); List<AbstractComponentBO> componentsBO = dao.findWhereTres( session, pProjectId, pAuditId, pTreKeys, pTreValues, pMax ); // bo -> dto for ( int i = 0; i < componentsBO.size(); i++ ) { components.add( ComponentTransform.bo2Dto( componentsBO.get( i ) ) ); } } catch ( JrafDaoException e ) { FacadeHelper.convertException( e, MeasureFacade.class.getName() + ".getComponentsWhereTres" ); } finally { FacadeHelper.closeSession( session, MeasureFacade.class.getName() + ".getComponentsWhereTres" ); } return components; } /** * Permet de r�cup�rer des valeurs pour une liste de types de r�sultat, une liste de types de composant et un audit * donn�s Format de ResultsDTO : 2 lignes : -- null en cl� et liste des cl�s de TREs en valeur -- ComponentDTO en * cl� et liste des r�sultats associ�es en valeur ( n fois ) * * @param pAudit AuditDTO contenant l'ID de l'audit * @param pTreKey l'id du tre correspondant � la pratique * @param pTREKeys liste des IDs des types de r�sultats souhait�s * @param pComponents liste de ComponentDTO souhait�s * @return ResultsDTO * @throws JrafEnterpriseException exception JRAF * @roseuid 42CBFFB401C0 */ public static ResultsDTO getMeasuresByTREAndComponent( Long pTreKey, List pTREKeys, List pComponents, AuditDTO pAudit ) throws JrafEnterpriseException { ResultsDTO results = null; Collection trClasses = null; MeasureDAOImpl measureDAO = MeasureDAOImpl.getInstance(); // Session Hibernate ISession session = null; try { // r�cup�ration d'une session session = PERSISTENTPROVIDER.getSession(); // R�cup�ration de la collection de classes de TREs trClasses = getTREClasses( pTREKeys ); if ( trClasses.size() > 0 ) { // initialisation du ResultsDTO et ajout des cl�s results = new ResultsDTO(); results.put( null, pTREKeys ); Iterator itComp = pComponents.iterator(); while ( itComp.hasNext() ) { // Pour chaque composant : ComponentDTO component = (ComponentDTO) itComp.next(); Long idComponent = new Long( component.getID() ); Long idAudit = new Long( pAudit.getID() ); // R�cup�ration des mesures souhait�es Collection measures = measureDAO.findWhere( session, idComponent, idAudit, trClasses ); if ( measures.size() > 0 ) { // ajout au R�sult DTO des mesures souhait�es results = MeasureTransform.bo2dtoByTRE( results, measures, pTREKeys, component ); // On r�cup�re aussi la note de la pratique associ�e � chaque composant // que l'on place en d�but de liste MarkBO mark = MarkDAOImpl.getInstance().load( session, new Long( component.getID() ), new Long( pAudit.getID() ), pTreKey ); ( (List) results.getResultMap().get( component ) ).add( 0, new Float( mark.getValue() ) ); } } } } catch ( JrafDaoException e ) { LOG.error( MeasureFacade.class.getName() + ".getMeasuresByTREAndComponent", e ); } finally { FacadeHelper.closeSession( session, MeasureFacade.class.getName() + ".getMeasuresByTREAndComponent" ); } return results; } /** * R�cup�re les classes de TRE � partir de la liste de TREs * * @param pTREKeys liste de cl�s de TREs * @return une collection de classe de TRE */ public static Collection getTREClasses( List pTREKeys ) { Set trClasses = new HashSet(); Iterator it = pTREKeys.iterator(); while ( it.hasNext() ) { // pour chaque cl� de type de r�sultat String treKey = (String) it.next(); // on ajoute la classe correspondante � la liste de classe de TRE trClasses.add( Mapping.getMetricClass( treKey ) ); } return trClasses; } /** * Constructeur vide * * @roseuid 42CBFFB40203 */ private MeasureFacade() { } /** * Creation d'une mesure de type Kiviat pour une application * * @param pAuditId Id de l'audit * @param pAllFactors tous les facteurs (= "true") ou seulement ceux ayant une note ? * @throws JrafEnterpriseException en cas de pb Hibernate * @return les donn�es n�cessaires � la conception du Kiviat via une Applet soit : Map dont la cl� contient les * projets et la valeur contient une map (facteurs, notes) */ public static Map getApplicationKiviat( Long pAuditId, String pAllFactors ) throws JrafEnterpriseException { MeasureDAOImpl measureDAO = MeasureDAOImpl.getInstance(); // Session Hibernate ISession session = null; Map result = new HashMap(); try { // r�cup�ration d'une session session = PERSISTENTPROVIDER.getSession(); ApplicationBO application = (ApplicationBO) ApplicationDAOImpl.getInstance().loadByAuditId( session, pAuditId ); Iterator itp = application.getChildren().iterator(); ArrayList nullValuesList = new ArrayList(); while ( itp.hasNext() ) { // On ajoute les notes de chaque projets sur le kiviat ProjectBO project = (ProjectBO) itp.next(); SortedMap values = new TreeMap(); Long idProject = new Long( project.getId() ); // recupere les facteurs du projet Collection factorResults = QualityResultDAOImpl.getInstance().findWhere( session, idProject, pAuditId ); // et cree le map nom => note correspondant Iterator itf = factorResults.iterator(); while ( itf.hasNext() ) { FactorResultBO factor = (FactorResultBO) itf.next(); // le -1 est trait� directement par le kiviatMaker Float value = new Float( factor.getMeanMark() ); // le nom internationalis� est g�r� dans le kiviatMaker String name = factor.getRule().getName(); values.put( name, value ); if ( factor.getMeanMark() < 0 ) { nullValuesList.add( name ); } } // affichage seulement des facteurs qui ont des valeurs final int FACTORS_MIN = 3; values = deleteFactors( values, nullValuesList, pAllFactors, FACTORS_MIN ); // et on envoie les valeurs result.put( project.getName(), values ); } } catch ( Exception e ) { FacadeHelper.convertException( e, MeasureFacade.class.getName() + ".getMeasures" ); } finally { FacadeHelper.closeSession( session, MeasureFacade.class.getName() + ".getMeasures" ); } return result; } /** * Creation d'une mesure de type Kiviat pour un projet * * @param pProjectId Id du projet * @param pAuditId Id de l'audit * @param pAllFactors tous les facteurs (= "true") ou seulement ceux ayant une note ? * @throws JrafEnterpriseException en cas de pb Hibernate * @return tableau d'objets : la map des donn�es + le bool�en pour affichage de la case � cocher tous les facteurs */ public static Object[] getProjectKiviat( Long pProjectId, Long pAuditId, String pAllFactors ) throws JrafEnterpriseException { Map result = new HashMap(); JFreeChart projectKiviat = null; MeasureDAOImpl measureDAO = MeasureDAOImpl.getInstance(); // Session Hibernate ISession session = null; // Bool�en conditonnanant l'affichage de la case � cocher "tous les facteurs" dans la page Jsp boolean displayCheckBoxFactors = true; try { // r�cup�ration d'une session session = PERSISTENTPROVIDER.getSession(); // On ajoute les notes de chaque projets sur le kiviat ProjectBO project = (ProjectBO) ProjectDAOImpl.getInstance().load( session, pProjectId ); SortedMap values = new TreeMap(); // recupere les facteurs du projet Collection factorResults = QualityResultDAOImpl.getInstance().findWhere( session, pProjectId, pAuditId ); // et cree le map nom => note correspondant Iterator it = factorResults.iterator(); ArrayList nullValuesList = new ArrayList(); while ( it.hasNext() ) { FactorResultBO factor = (FactorResultBO) it.next(); // le -1 est trait� directement par le kiviatMaker Float value = new Float( factor.getMeanMark() ); // ajoute la note dans le titre // TODO prendre le v�ritable nom du facteur String name = factor.getRule().getName(); if ( value.floatValue() >= 0 ) { // avec 1 seul chiffre apr�s la virgule NumberFormat nf = NumberFormat.getInstance(); nf.setMinimumFractionDigits( 1 ); nf.setMaximumFractionDigits( 1 ); name = name + " (" + nf.format( value ) + ")"; } else { // M�morisation temporaire des facteurs pour lesquels les notes sont nulles : sera utile si l'option // "Tous les facteurs" est coch�e pour afficher uniquement les facteurs ayant une note. nullValuesList.add( name ); } values.put( name, value ); } final int FACTORS_MIN = 3; if ( nullValuesList.size() <= 0 || values.size() <= FACTORS_MIN ) { displayCheckBoxFactors = false; } // Seulement les facteurs ayant une note ? ==> suppression des facteurs ayant une note nulle. // Mais trois facteurs doivent au moins s'afficher (nuls ou pas !) values = deleteFactors( values, nullValuesList, pAllFactors, FACTORS_MIN ); // recup�re le nom de l'audit String name = null; AuditBO audit = (AuditBO) AuditDAOImpl.getInstance().load( session, pAuditId ); if ( audit.getType().compareTo( AuditBO.MILESTONE ) == 0 ) { name = audit.getName(); } if ( null == name ) { DateFormat df = DateFormat.getDateInstance( DateFormat.LONG ); name = df.format( audit.getDate() ); } result.put( name, values ); } catch ( Exception e ) { FacadeHelper.convertException( e, MeasureFacade.class.getName() + ".getMeasures" ); } finally { FacadeHelper.closeSession( session, MeasureFacade.class.getName() + ".getMeasures" ); } Object[] kiviatObject = { result, new Boolean( displayCheckBoxFactors ) }; return kiviatObject; } /** * Affichage des facteurs du Kiviat : tous les facteurs ou seulement ceux ayant une note * * @param pValues les donn�es � afficher : facteur + note * @param pNullValuesList la liste des facteurs dont la note est nulle * @param pAllFactors tous les facteurs (="true") ou seulement les facteurs ayant une note * @param pFactorsMin nombre de facteurs minimal que l'on doit afficher sur le Kiviat * @return values les donn�es r�ellement � afficher : facteur + note */ private static SortedMap deleteFactors( SortedMap pValues, ArrayList pNullValuesList, String pAllFactors, int pFactorsMin ) { SortedMap values = new TreeMap(); // Seulement les facteurs ayant une note ? ==> suppression des facteurs ayant une note nulle. // Mais trois facteurs doivent au moins s'afficher (nuls ou pas !) if ( pValues.size() > pFactorsMin && !pAllFactors.equals( "true" ) ) { // Nombre de suppressions possible int nbTotalDeletions = pValues.size() - pFactorsMin; // Nombre de suppressions effectu� int nbCurrentDeletions = 0; // Parcours de la liste des facteurs avec une note nulle, pour les supprimer de l'affichage Iterator itList = pNullValuesList.iterator(); while ( itList.hasNext() && nbCurrentDeletions < nbTotalDeletions ) { String keyListe = (String) itList.next(); pValues.remove( keyListe ); nbCurrentDeletions += 1; } } values.putAll( pValues ); return values; } /** * Creation d'une mesure de type Bubble pour un projet * * @param pProjectId Id du projet * @param pAuditId Id de l'audit * @throws JrafEnterpriseException en cas de pb Hibernate * @return chart Scatterplot de l'Audit * @throws JrafEnterpriseException si pb Hibernate */ public static Object[] getProjectBubble( Long pProjectId, Long pAuditId ) throws JrafEnterpriseException { // R�cup�ration des valeurs int i = 0; Collection measures = new ArrayList( 0 ); MeasureDAOImpl measureDAO = MeasureDAOImpl.getInstance(); // Session Hibernate ISession session = null; Object[] result = null; try { // r�cup�ration d'une session session = PERSISTENTPROVIDER.getSession(); // On r�cup�re la configuration du scatterplot pour ce projet et cet audit AuditDisplayConfBO auditConf = AuditDisplayConfDAOImpl.getInstance().findConfigurationWhere( session, pProjectId, pAuditId, "bubble" ); if ( null != auditConf ) { BubbleConfBO bubble = (BubbleConfBO) auditConf.getDisplayConf(); String[] tre = { bubble.getXTre(), bubble.getYTre() }; // r�cup�ration des mesures distinctes rattach�es � l'audit et au projet measures = MeasureDAOImpl.getInstance().findDistinct( session, pProjectId.longValue(), pAuditId.longValue(), tre ); // recuperation des 2 tableaux evgs, vgs contenant les mesures double[] xMeasures = new double[measures.size()]; double[] yMeasures = new double[measures.size()]; double[] total = new double[measures.size()]; Iterator it = measures.iterator(); // Constantes pour la r�cup�rations des valeurs dans le tableau des r�sultats remont�s de la base final int VG_ID = 0; final int EVG_ID = 1; final int TOTAL_ID = 2; while ( it.hasNext() ) { Object[] res = (Object[]) it.next(); // on ajoute ses valeurs Integer vg = (Integer) res[VG_ID]; yMeasures[i] = vg.doubleValue(); Integer evg = (Integer) res[EVG_ID]; xMeasures[i] = evg.doubleValue(); Integer tt = (Integer) res[TOTAL_ID]; total[i] = tt.doubleValue(); i++; } // Positions des axes Long horizontal = new Long( bubble.getHorizontalAxisPos() ); Long vertical = new Long( bubble.getVerticalAxisPos() ); // construction des param�tres de la s�rie String displayedXTre = bubble.getXTre().substring( bubble.getXTre().lastIndexOf( "." ) + 1 ); String displayedYTre = bubble.getYTre().substring( bubble.getYTre().lastIndexOf( "." ) + 1 ); String measuresKinds = "(" + displayedXTre + "," + displayedYTre + ",total)"; result = new Object[] { horizontal, vertical, measuresKinds, yMeasures, xMeasures, total, yMeasures, xMeasures, total, tre }; } } catch ( Exception e ) { FacadeHelper.convertException( e, MeasureFacade.class.getName() + ".getMeasures" ); } finally { FacadeHelper.closeSession( session, MeasureFacade.class.getName() + ".getMeasures" ); } return result; } /** * Creation du Piechart d'une application * * @param pAuditId id de l'audit * @throws JrafEnterpriseException si pb Hibernate * @return les donn�es n�cessaires � la conception du PieChart via une Applet soit : Map dont la cl� contient les * projets et la valeur le nombre de lignes du projet */ public static Object[] getApplicationPieChart( Long pAuditId ) throws JrafEnterpriseException { // R�cup�ration des v(g) et des ev(g) Collection measures; MeasureDAOImpl measureDAO = MeasureDAOImpl.getInstance(); MetricDAOImpl metricDAO = MetricDAOImpl.getInstance(); AuditDisplayConfDAOImpl auditConfDao = AuditDisplayConfDAOImpl.getInstance(); // Session Hibernate ISession session = null; Object[] result = new Object[2]; try { // r�cup�ration d'une session session = PERSISTENTPROVIDER.getSession(); ApplicationBO application = (ApplicationBO) ApplicationDAOImpl.getInstance().loadByAuditId( session, pAuditId ); // On retrouve les ids de tous les projets de l'application : Set projects = new HashSet(); Iterator itChildren = application.getChildren().iterator(); // Pour chaque enfant du projet : while ( itChildren.hasNext() ) { // Une application ne contient que des projets ProjectBO projectBO = (ProjectBO) itChildren.next(); // On ajoute le projet seulement si celui-ci a �t� audit� // (cas par exemple d'une d�sactivation) if ( projectBO.containsAuditById( pAuditId.longValue() ) ) { projects.add( projectBO ); } } // r�cup�ration du nombre de ligne de code de chaque projet Map volum = new HashMap(); Map url = new HashMap(); // volum�trie par grille (ne sert que pour l'export PDF) Map volumByGrid = new HashMap(); Iterator itProjects = projects.iterator(); int i = 0; while ( itProjects.hasNext() ) { int accLines = 0; Long nbLignes = new Long( 0 ); ProjectBO project = (ProjectBO) itProjects.next(); Long idProject = new Long( project.getId() ); // R�cup�ration des mesures correspondant � l'audit et // au projet concern� � l'aide de la configuration de la volum�trie pour une application AuditDisplayConfBO auditConf = (AuditDisplayConfBO) auditConfDao.findConfigurationWhere( session, idProject, pAuditId, DisplayConfConstants.VOLUMETRY_SUBCLASS, DisplayConfConstants.VOLUMETRY_APPLICATION_TYPE ); if ( null != auditConf ) { VolumetryConfBO volumConf = (VolumetryConfBO) auditConf.getDisplayConf(); // On ajoute les volum�tries trouv�es en fonction des tres for ( Iterator it = volumConf.getTres().iterator(); it.hasNext(); ) { IntegerMetricBO metric = metricDAO.findIntegerMetricWhere( session, idProject.longValue(), pAuditId.longValue(), (String) it.next() ); if ( null != metric ) { accLines += ( (Integer) metric.getValue() ).intValue(); } } nbLignes = new Long( accLines ); // On ajoute la valeur au nb de ligne pour la grille du projet setApplicationVolumetryByGrid( session, idProject, pAuditId, volumByGrid, nbLignes ); } // si il n'y a pas de configuration, c'est qu'il y a un probl�me en base // Placement du nombre de lignes en regard du nom de projet si le nombre de lignes // et > 0 if ( 0 < nbLignes.longValue() ) { volum.put( project.getName(), nbLignes ); url.put( project.getName(), idProject ); } i++; } result = new Object[] { volum, url, volumByGrid }; } catch ( Exception e ) { FacadeHelper.convertException( e, MeasureFacade.class.getName() + ".getMeasures" ); } finally { FacadeHelper.closeSession( session, MeasureFacade.class.getName() + ".getMeasures" ); } return result; } /** * Ajoute le nombre de lignes d'un projet pour une grille donn�e * * @param session la session * @param idProject l'id du projet * @param pAuditId l'id de l'audit * @param volumByGrid la map du nombre de lignes par grille * @param nbLines le nombre de ligne � ajouter pour la grille * @throws JrafDaoException si erreur */ private static void setApplicationVolumetryByGrid( ISession session, Long idProject, Long pAuditId, Map volumByGrid, Long nbLines ) throws JrafDaoException { // R�cup�ration des grilles AuditGridDAOImpl auditGridDao = AuditGridDAOImpl.getInstance(); // On r�cup�re la grille associ�e au projet pour cet audit AuditGridBO auditGrid = auditGridDao.findWhere( session, idProject, pAuditId ); // on ajoute la valeur au nb de ligne pour la grille du projet Long nbLinesforGrid = (Long) volumByGrid.get( auditGrid.getGrid().getName() ); // Si on a d�j� eu un projet associ� � cette grille, on fait la somme des lignes if ( null != nbLinesforGrid ) { volumByGrid.put( auditGrid.getGrid().getName(), new Long( nbLinesforGrid.longValue() + nbLines.longValue() ) ); } else { volumByGrid.put( auditGrid.getGrid().getName(), nbLines ); } } /** * R�cup�re les valeurs permettant d'avoir l'historique relatif a des cles de tre et un composant * * @param pComponent un composant * @param pTreLabel label de tre * @param pTreKey cles de tre concerne par l'historique * @param pAuditDate date a partir de laquelle on souhaite recuperer tous les audits * @param pRuleId id de la r�gle qualit� ou null s'il s'agit d'une mesure * @return La map correspondant aux points * @throws JrafEnterpriseException exception Jraf */ public static Map getHistoricResults( ComponentDTO pComponent, String pTreKey, String pTreLabel, Date pAuditDate, Long pRuleId ) throws JrafEnterpriseException { // Session Hibernate ISession session = null; // Initialisation des differentes Daos AuditDAOImpl auditDao = AuditDAOImpl.getInstance(); List currentAudits = null; // liste des audits relatifs au composant Map values = null; try { session = PERSISTENTPROVIDER.getSession(); // recuperation des audits relatifs a un composant tri�s par date r�elle currentAudits = auditDao.findAfter( session, pComponent.getID(), pAuditDate ); // Initialisation de la Map values = new HashMap(); Iterator auditIterator = currentAudits.iterator(); AuditBO currentAuditBO = null; // AuditBO courant Long currentAuditId = null; AuditDTO currentAudit = null; // audit parcouru ResultsDTO currentResults = null; // ResultsDTO courant recupere while ( auditIterator.hasNext() ) { // recuperation de l'audit parcouru currentAuditBO = (AuditBO) auditIterator.next(); currentAuditId = new Long( currentAuditBO.getId() ); // recuperation de l'application associ�e a l'audit ApplicationBO currentApplication = (ApplicationBO) ApplicationDAOImpl.getInstance().loadByAuditId( session, currentAuditId ); currentAudit = AuditTransform.bo2Dto( currentAuditBO, currentApplication.getId() ); if ( pRuleId == null ) { currentResults = MeasureFacade.getMeasures( currentAudit, pComponent, pTreKey ); } else { currentResults = QualityResultFacade.getQResults( currentAudit, pComponent, pRuleId ); } // recuperation de la valeur associee du ResultsDTO Object objectValue = ( (ArrayList) currentResults.getResultMap().get( null ) ).get( 0 ); // On ajoute la valeur � la table (en fonction du type de l'objet) addHistoricValues( values, currentAudit.getRealDate(), objectValue ); } } catch ( JrafDaoException e ) { FacadeHelper.convertException( e, MeasureFacade.class.getName() + ".getHistoricResults" ); } finally { FacadeHelper.closeSession( session, MeasureFacade.class.getName() + ".getHistoricResults" ); } return values; } /** * Ajoute une entr�e � la table des valeurs du graphe historique * * @param values la table des valeurs * @param key la cl� * @param value la valeur */ private static void addHistoricValues( Map values, Date key, Object value ) { if ( value != null ) { // Petit test � faire sur le type de la note // Dans le cas ou c'est un bool�en, on met alors 1 si le bool�en // est � true, 0 sinon // Dans le cas d'une note, on met la valeur // Initialisation � 0 par d�faut Number numberToAdd = new Integer( "0" ); if ( value instanceof Boolean ) { // boole�n valant "true" if ( ( (Boolean) value ).booleanValue() ) { numberToAdd = new Integer( "1" ); } // else bool�en valant false, rien � faire car valeur par d�faut } else if ( value.toString().matches( "[0-9]+(\\.[0-9]+)?" ) ) { // R�cup�re directement le nombre numberToAdd = (Number) value; } if ( numberToAdd.intValue() != -1 ) { values.put( key, numberToAdd ); } } } /** * Permet de dessiner l'historique relatif a des cles de tre et un composant * * @param pComponent un composant * @param pTreLabel label de tre * @param pTreKey cles de tre concerne par l'historique * @param pAuditDate date a partir de laquelle on souhaite recuperer tous les audits * @param pRuleId id de la r�gle qualit� ou null s'il s'agit d'une mesure * @return GraphDTO * @throws JrafEnterpriseException exception Jraf */ public static Object[] getHistoricGraph( ComponentDTO pComponent, String pTreKey, String pTreLabel, Date pAuditDate, Long pRuleId ) throws JrafEnterpriseException { ISession session = null; PracticeRuleBO ruleBO = null; Object[] result = null; try { session = PERSISTENTPROVIDER.getSession(); // if pRuleId is not null, let's try to find the rule if ( pRuleId != null ) { // Recovery of the rule ruleBO = (PracticeRuleBO) PracticeRuleAPDAOImpl.getInstance().get( session, pRuleId ); } // If it's a manual practice if ( ruleBO != null && ruleBO.getFormula() == null ) { String timeLimitation = ruleBO.getTimeLimitation(); Object[] objectReturn = MeasureFacade.getHistoricManualMark( pComponent, pAuditDate, pRuleId, timeLimitation ); result = new Object[] { pTreLabel, objectReturn[0], HISTORIC_TYPE, objectReturn[1], objectReturn[2] }; } // If it's not a manual practice else { Map values = MeasureFacade.getHistoricResults( pComponent, pTreKey, pTreLabel, pAuditDate, pRuleId ); result = new Object[] { pTreLabel, values, HISTORIC_TYPE, new HashMap<Date, Float>() }; } } catch ( JrafPersistenceException e ) { FacadeHelper.convertException( e, MeasureFacade.class.getName() + ".getHistoricGraph" ); } catch ( JrafDaoException e ) { FacadeHelper.convertException( e, MeasureFacade.class.getName() + ".getHistoricGraph" ); } finally { FacadeHelper.closeSession( session, MeasureFacade.class.getName() + ".getHistoricGraph" ); } return result; } /** * Retourne les mesures associ�es � la volum�trie d'un projet d'apr�s sa configuration en base pour un audit donn� * sous la forme de ResultsDTO : ResultsDTO.getResultMap.get(null) --> les noms des tres * ResultsDTO.getResultMap.get(pProject) --> les valeurs associ�es * * @param pAuditId l'id de l'audit * @param pProject le projet * @return l'ensemble des mesures de la volum�trie du projet * @throws JrafEnterpriseException si erreur */ public static ResultsDTO getProjectVolumetry( Long pAuditId, ComponentDTO pProject ) throws JrafEnterpriseException { // D�claration du ResultsDTO � retourner ResultsDTO results = new ResultsDTO(); MetricDAOImpl metricDAO = MetricDAOImpl.getInstance(); // Session Hibernate ISession session = null; try { // R�cup�ration d'une session session = PERSISTENTPROVIDER.getSession(); // R�cup�ration de la configuration de la volum�trie pour ce projet et cet audit AuditDisplayConfBO auditConf = AuditDisplayConfDAOImpl.getInstance().findConfigurationWhere( session, new Long( pProject.getID() ), pAuditId, DisplayConfConstants.VOLUMETRY_SUBCLASS, DisplayConfConstants.VOLUMETRY_PROJECT_TYPE ); if ( null != auditConf ) { VolumetryConfBO volumConf = (VolumetryConfBO) auditConf.getDisplayConf(); // Pour chaque nom de tre, on r�cup�re la valeur de la m�trique associ�e // et on construit ainsi les r�sultats � retourner List tres = new ArrayList(); List values = new ArrayList(); for ( Iterator it = volumConf.getTres().iterator(); it.hasNext(); ) { String treName = (String) it.next(); IntegerMetricBO metric = metricDAO.findIntegerMetricWhere( session, pProject.getID(), pAuditId.longValue(), treName ); if ( null != metric ) { // On ajoute � la liste des r�sultats tres.add( treName ); values.add( metric.getValue() ); } } results.getResultMap().put( null, tres ); results.getResultMap().put( pProject, values ); } // Sinon il y a un probl�me en base } catch ( JrafDaoException e ) { FacadeHelper.convertException( e, MeasureFacade.class.getName() + ".getMeasuresByTRE" ); } finally { FacadeHelper.closeSession( session, MeasureFacade.class.getName() + ".getMeasuresByTRE" ); } return results; } /** * Recover the list of information needed to fill the historic of a manual practice The first object return * represent the historic of all the mark inserted for the manual practice. The second object represent the validity * of the last mark inserted * * @param component Component on which we do the search * @param auditDate The limit date for the search * @param ruleId The id of the rule on which we do the historic * @param timeLimitation This String represents the duration of validity of a mark for the manual practice * @return objects * @throws JrafEnterpriseException exception happen during the search */ public static Object[] getHistoricManualMark( ComponentDTO component, Date auditDate, Long ruleId, String timeLimitation ) throws JrafEnterpriseException { ISession session = null; Map values = new HashMap<Date, Float>(); Map extension = new HashMap<Date, Float>(); //List used to display manual mark comments history ArrayList<QualityResultDTO> listForComments = new ArrayList<QualityResultDTO>(); try { session = PERSISTENTPROVIDER.getSession(); QualityResultDAOImpl dao = QualityResultDAOImpl.getInstance(); Calendar todayCal = TimeUtil.calDateOnly(); PracticeResultBO lastResult = dao.findLastManualMark( session, component.getID(), ruleId ); if ( lastResult != null ) { Calendar endValidity = TimeLimitationParser.endValidityDate( timeLimitation, lastResult.getCreationDate() ); if ( endValidity.getTime().compareTo( auditDate ) > 0 ) { ArrayList<PracticeResultBO> resultList = (ArrayList<PracticeResultBO>) dao.findManualMarkSince( session, component.getID(), ruleId, auditDate ); if ( resultList != null ) { for ( PracticeResultBO practice : resultList ) { values.put( practice.getCreationDate(), practice.getMeanMark() ); QualityResultDTO manualMarkForCommentsHistory = QualityResultTransform.bo2Dto( practice ); listForComments.add( manualMarkForCommentsHistory ); } if ( lastResult.getCreationDate().compareTo( todayCal.getTime() ) < 0 ) { extension = MeasureFacade.fillExtensionMap( lastResult.getCreationDate(), lastResult.getMeanMark(), todayCal, endValidity ); } } else { extension = MeasureFacade.fillExtensionMap( auditDate, lastResult.getMeanMark(), todayCal, endValidity ); } } } } catch ( JrafPersistenceException e ) { FacadeHelper.convertException( e, MeasureFacade.class.getName() + ".getHistoricManualMark" ); } catch ( JrafDaoException e ) { FacadeHelper.convertException( e, MeasureFacade.class.getName() + ".getHistoricManualMark" ); } finally { FacadeHelper.closeSession( session, MeasureFacade.class.getName() + ".getHistoricManualMark" ); } return new Object[] { values, extension, listForComments }; } /** * When we create the historic for a manual practice, this method permit to fill part of the historic corresponding * to the validity of the last mark * * @param beginDate Date of creation of the mark * @param mark The mark * @param todayCal Calendar set on today * @param endValidity Date of end of validity of the mark * @return a map which contains information to display for the historic */ private static Map fillExtensionMap( Date beginDate, float mark, Calendar todayCal, Calendar endValidity ) { Map extension = new HashMap<Date, Float>(); extension.put( beginDate, mark ); if ( endValidity.after( todayCal ) ) { extension.put( todayCal.getTime(), mark ); } else { extension.put( endValidity.getTime(), mark ); } return extension; } }