/** * 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.cpd; import java.util.Iterator; import net.sourceforge.pmd.cpd.Match; import net.sourceforge.pmd.cpd.TokenEntry; 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.rulechecking.ProjectRuleSetDAOImpl; import org.squale.squalecommon.enterpriselayer.businessobject.component.AuditBO; import org.squale.squalecommon.enterpriselayer.businessobject.component.ProjectBO; import org.squale.squalecommon.enterpriselayer.businessobject.result.IntegerMetricBO; import org.squale.squalecommon.enterpriselayer.businessobject.result.rulechecking.CpdTransgressionBO; import org.squale.squalecommon.enterpriselayer.businessobject.result.rulechecking.RuleCheckingTransgressionBO; import org.squale.squalecommon.enterpriselayer.businessobject.result.rulechecking.RuleCheckingTransgressionItemBO; import org.squale.squalecommon.enterpriselayer.businessobject.rulechecking.ProjectRuleSetBO; import org.squale.squalecommon.enterpriselayer.businessobject.rulechecking.RuleBO; /** * Persistance des donn�es de Cpd Les donn�es sont stock�es dans une ruleset dynamique, ce ruleset contient une r�gle * par langage */ public class CpdPersistor { /** Transgression */ private CpdTransgressionBO mTransgression; /** RuleSet */ private ProjectRuleSetBO mRuleSet; /** Pr�fixe de chemin */ private String mPrefixPath; /** * Constructeur * * @param pProjectBO projet * @param pAuditBO audit * @param pPrefixPath pr�fixe de path */ public CpdPersistor( ProjectBO pProjectBO, AuditBO pAuditBO, String pPrefixPath ) { mPrefixPath = pPrefixPath; mRuleSet = createRuleSet( pProjectBO ); mTransgression = createTransgression( pProjectBO, pAuditBO ); } /** * Cr�ation de la transgression * * @param pProjectBO projet * @param pAuditBO audit * @return transgression */ protected CpdTransgressionBO createTransgression( ProjectBO pProjectBO, AuditBO pAuditBO ) { // Cr�ation de la transgression CpdTransgressionBO transgression = new CpdTransgressionBO(); transgression.setAudit( pAuditBO ); transgression.setComponent( pProjectBO ); transgression.setRuleSet( mRuleSet ); transgression.setTaskName( "CpdTask" ); return transgression; } /** * Cr�ation du RuleSet * * @param pProject projet * @return r�gle de copy/paste */ protected ProjectRuleSetBO createRuleSet( ProjectBO pProject ) { ProjectRuleSetBO ruleset = new ProjectRuleSetBO(); ruleset.setProject( pProject ); return ruleset; } /** * Cr�ation d'une r�gle * * @param pLanguage langage * @return r�gle */ protected RuleBO createRule( String pLanguage ) { RuleBO rule = new RuleBO(); rule.setCategory( "copypaste" ); rule.setCode( "cpd." + pLanguage ); rule.setSeverity( "error" ); rule.setRuleSet( mRuleSet ); mRuleSet.addRule( rule ); return rule; } /** * Sauvegarde des r�sultats * * @param pSession session * @throws JrafDaoException si erreur */ public void storeResults( ISession pSession ) throws JrafDaoException { // Cr�ation du RuleSet ProjectRuleSetDAOImpl.getInstance().create( pSession, mRuleSet ); // Sauvegarde des donn�es dans la base MeasureDAOImpl.getInstance().create( pSession, mTransgression ); } /** * Ajout d'un r�sultat * * @param pLanguage langage * @param pMatches d�tections */ public void addResult( String pLanguage, Iterator pMatches ) { RuleBO rule = createRule( pLanguage ); int nbOcc = 0; int dupLinesNb = 0; // On traite chaque d�tection while ( pMatches.hasNext() ) { Match m = (Match) pMatches.next(); StringBuffer detail = new StringBuffer(); detail.append( CpdMessages.getString( "copypaste.summary", new Object[] { new Integer( m.getLineCount() ), new Integer( m.getTokenCount() ) } ) ); detail.append( '\n' ); nbOcc++; Iterator occ = m.iterator(); // Parcours de chaque occurrence de copy/paste String itemFileName = ""; int itemLine = 0; while ( occ.hasNext() ) { TokenEntry entry = (TokenEntry) occ.next(); String fileName = entry.getTokenSrcID(); // On �limine dans le nom du fichier le nom de la vue if ( fileName.startsWith( mPrefixPath ) ) { fileName = fileName.substring( mPrefixPath.length() ); } detail.append( CpdMessages.getString( "copypaste.occurrenceentry", new Object[] { new Integer( entry.getBeginLine() ), fileName } ) ); detail.append( '\n' ); // On affecte le premier fichier et la premi�re ligne trouv�e � l'item if ( itemFileName.length() == 0 ) { itemFileName = fileName; itemLine = entry.getBeginLine(); } } dupLinesNb += ( m.getMarkCount() - 1 ) * m.getLineCount(); // On ne fait persister que les 100 premiers items par r�gle // ICI il n'y a qu'une r�gle d�finie par langage if ( nbOcc <= RuleCheckingTransgressionBO.MAX_DETAILS ) { RuleCheckingTransgressionItemBO item = new RuleCheckingTransgressionItemBO(); // Taille maximale pour les d�tails final int MAX_LENGTH = 3000; // Troncature du message si besoin if ( detail.length() > MAX_LENGTH ) { detail.setLength( MAX_LENGTH - 1 ); } item.setMessage( detail.toString() ); item.setRule( rule ); item.setComponentFile( itemFileName ); item.setLine( itemLine ); mTransgression.getDetails().add( item ); } } // On ajoute une m�trique de type Integer pour chaque r�gle transgress�e IntegerMetricBO metric = new IntegerMetricBO(); metric.setName( rule.getCode() ); metric.setValue( nbOcc ); metric.setMeasure( mTransgression ); mTransgression.putMetric( metric ); // Cr�ation de la m�trique donnant le nombre total de lignes pour le langage mTransgression.setDuplicateLinesForLanguage( pLanguage, new Integer( dupLinesNb ) ); // Incr�ment du nombre total de lignes dupliqu�es mTransgression.incrementDuplicateLinesNumber( dupLinesNb ); } }