/**
* 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.tools.mccabe;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.squale.jraf.commons.exception.JrafDaoException;
import org.squale.jraf.spi.persistence.ISession;
import org.squale.squalecommon.daolayer.result.MeasureDAOImpl;
import org.squale.squalecommon.daolayer.component.AbstractComponentDAOImpl;
import org.squale.squalecommon.enterpriselayer.businessobject.component.AuditBO;
import org.squale.squalecommon.enterpriselayer.businessobject.component.ComponentType;
import org.squale.squalecommon.enterpriselayer.businessobject.component.ProjectBO;
import org.squale.squalecommon.enterpriselayer.businessobject.component.PackageBO;
import org.squale.squalecommon.enterpriselayer.businessobject.component.ClassBO;
import org.squale.squalecommon.enterpriselayer.businessobject.result.mccabe.McCabeQAMethodMetricsBO;
import org.squale.squalecommon.enterpriselayer.businessobject.result.mccabe.McCabeQAClassMetricsBO;
import org.squale.squalecommon.enterpriselayer.businessobject.result.mccabe.McCabeQAProjectMetricsBO;
import org.squale.squalix.core.TaskData;
import org.squale.squalix.util.csv.CSVParser;
import org.squale.squalix.util.parser.CobolParser;
import org.squale.squalix.util.repository.ComponentRepository;
import org.squale.squalecommon.util.mapping.Mapping;
/**
* Objet charg� de faire persister les m�triques McCabe pour les projets Cobol.
*/
public class CobolMcCabePersistor
extends McCabePersistor
{
/**
* Logger.
*/
private static final Log LOGGER = LogFactory.getLog( CobolMcCabePersistor.class );
/**
* Adaptateur.
*/
private CobolMcCabeAdaptator mAdaptator;
/**
* Le parser.
*/
private CobolParser mParser;
/**
* Nombre de module du projet.
*/
private int mNumberOfModules;
/**
* Nombre de programmes.
*/
private int mNumberOfPrograms;
/**
* Nombre total de ligne du projet.
*/
private int mTotalNl;
/**
* Constructeur.
*
* @param pSession la session de persistence utilis�e par la t�che.
* @param pDatas la liste des param�tres temporaires du projet
* @param pTaskName le nom de la tache
* @param pAudit l'audit en cours
* @param pConfiguration la configuration
* @param pCobolParser le parser Cobol
*/
public CobolMcCabePersistor( final ISession pSession, final TaskData pDatas, final String pTaskName,
final AuditBO pAudit, final McCabeConfiguration pConfiguration,
final CobolParser pCobolParser )
{
super( pSession, pDatas, pTaskName, pAudit, pConfiguration );
mParser = pCobolParser;
ComponentRepository repository = new ComponentRepository( mProject, mSession );
mAdaptator = new CobolMcCabeAdaptator( repository, mParser );
}
/**
* Analyse le rapport des m�triques McCabe et enregistre les composants et m�triques associ�es.
*
* @param pFilename le nom du fichier des m�triques rapport�es par McCabe.
* @throws Exception si exception
*/
public void parseCobolReport( final String pFilename )
throws Exception
{
LOGGER.info( McCabeMessages.getString( "logs.debug.report_parsing_module" ) + pFilename );
// chargement du mod�le csv de rapport McCabe pour le Cobol
CSVParser csvparser = new CSVParser( McCabeMessages.getString( "csv.config.file" ) );
// analyse du rapport des m�triques et cr�ation des objets m�tier des m�triques
Collection<McCabeQAMethodMetricsBO> moduleResults = new ArrayList<McCabeQAMethodMetricsBO>();
moduleResults = csvparser.parse( McCabeMessages.getString( "csv.template.cobol" ), pFilename );
// association des m�triques avec le composant Cobol avant enregistrement en base
McCabeQAMethodMetricsBO bo = null;
Iterator<McCabeQAMethodMetricsBO> it = moduleResults.iterator();
Set<String> lSetOfProgramNames = new TreeSet<String>();
while ( it.hasNext() )
{
bo = it.next();
bo.setAudit( mAudit );
bo.setTaskName( mTaskName );
// association des m�triques avec les composants Cobol
String lPrgName = mAdaptator.adaptModuleResult( bo );
// ajout du nom du programme dans l'ensemble (si non pr�sent)
lSetOfProgramNames.add( lPrgName );
// incr�ment du nombre de modules
mNumberOfModules++;
// incr�ment du nombre de lignes
mTotalNl += bo.getNl();
}
// calcul du nombre final de programmes analys�s
mNumberOfPrograms = lSetOfProgramNames.size();
// enregistrement en base des m�triques McCabe
LOGGER.info( McCabeMessages.getString( "logs.debug.report_parsing_database" ) );
MeasureDAOImpl.getInstance().saveAll( mSession, moduleResults );
mSession.commitTransactionWithoutClose();
mSession.beginTransaction();
LOGGER.info( McCabeMessages.getString( "logs.debug.report_parsing_end" ) );
}
/**
* Calcule les m�triques au niveau Programme � partir de l'arbre des composants
*/
public void calculateCobolProgramMetrics()
throws Exception
{
LOGGER.info( McCabeMessages.getString( "logs.debug.program_processing" ) );
// R�cup�ration du Package Root du projet COBOL
ProjectBO lProject = mParser.getProject();
Collection lListRootPackage =
AbstractComponentDAOImpl.getInstance().findAllChildrenWhere( mSession, lProject.getId(), mAudit.getId(),
"Package" );
if ( lListRootPackage.size() != 1 )
{
// Erreur car un projet COBOL ne peut contenir qu'un root package SOURCE par audit
LOGGER.error( "Zero or more than one Root Package detected. Impossible to calculate COBOL Program Metric." );
}
else
{
PackageBO lRootPackage = (PackageBO) lListRootPackage.toArray()[0];
Collection lListProgram =
AbstractComponentDAOImpl.getInstance().findAllChildrenWhere( mSession, lRootPackage.getId(),
mAudit.getId(), "Class" );
generateProgramMetrics( lListProgram );
}
}
/**
* G�n�ration des m�triques au niveau Programme
*
* @param listProgram liste des programmes
* @return true si les m�triques ont �t� g�n�r�s
*/
private void generateProgramMetrics( Collection listProgram )
throws Exception
{
LOGGER.info( McCabeMessages.getString( "logs.debug.program_calculating" ) );
Collection<McCabeQAClassMetricsBO> programResults = new ArrayList<McCabeQAClassMetricsBO>();
Iterator itProgram = listProgram.iterator();
while ( itProgram.hasNext() )
{
ClassBO program = (ClassBO) itProgram.next();
// R�cup�ration des m�triques des modules du programme
Collection<McCabeQAMethodMetricsBO> programMeasureList =
MeasureDAOImpl.getInstance().findWhereParent( mSession, program.getId(), mAudit.getId(),
"MethodMetrics" );
// Si ce programme n'existe plus pour cet audit, pas de mesures retourn�es
if ( programMeasureList.size() > 0 )
{
// Init des m�triques Programmes qu'on va calculer
McCabeQAClassMetricsBO programMetric = new McCabeQAClassMetricsBO();
programMetric.setTaskName( mTaskName );
programMetric.setAudit( mAudit );
programMetric.setComponent( program );
programMetric.setComponentName( program.getName() );
// en COBOL, on a 1 mesure / composant
programMetric.setWmc( programMeasureList.size() );
int sumNbLoc = 0;
int sumNbLoCom = 0;
boolean deadM = false;
int sumVg = 0;
int maxVg = 0;
// It�ration sur les mesures des modules
Iterator itMesure = programMeasureList.iterator();
while ( itMesure.hasNext() )
{
McCabeQAMethodMetricsBO mesure = (McCabeQAMethodMetricsBO) itMesure.next();
sumNbLoc += mesure.getNsloc();
sumNbLoCom += mesure.getNcloc();
sumVg += mesure.getVg();
maxVg = Math.max( maxVg, mesure.getVg() );
if ( deadM == false && mesure.getDeadCode() == 1 )
{
deadM = true;
}
}
// Calcul pour le programme puis ajout dans la collection
programMetric.setSloc( sumNbLoc );
programMetric.setCloc( sumNbLoCom );
programMetric.setSumvg( sumVg );
programMetric.setDeadModule( deadM );
programMetric.setMaxvg( maxVg );
programResults.add( programMetric );
}
}
// Persistance de la collection obtenue
LOGGER.info( McCabeMessages.getString( "logs.debug.program_processing_database" ) );
MeasureDAOImpl.getInstance().saveAll( mSession, programResults );
mSession.commitTransactionWithoutClose();
mSession.beginTransaction();
LOGGER.info( McCabeMessages.getString( "logs.debug.program_processing_end" ) );
}
/**
* Cr�e les r�sultats de niveau projet et les enregistre en base.
*/
public void persistProjectResult()
{
LOGGER.info( McCabeMessages.getString( "logs.debug.project_database" ) );
McCabeQAProjectMetricsBO metrics = new McCabeQAProjectMetricsBO();
// Cr�ation des m�triques de niveau projet
metrics.setComponent( mProject );
metrics.setAudit( mAudit );
metrics.setTaskName( mTaskName );
metrics.setNumberOfClasses( new Integer( mNumberOfPrograms ) );
metrics.setNumberOfMethods( new Integer( mNumberOfModules ) );
metrics.setTotalNl( mTotalNl );
try
{
MeasureDAOImpl.getInstance().create( mSession, metrics );
}
catch ( JrafDaoException e )
{
LOGGER.error( e, e );
}
}
}