/**
* 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.daolayer.result;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.squale.jraf.commons.exception.JrafDaoException;
import org.squale.jraf.provider.persistence.hibernate.AbstractDAOImpl;
import org.squale.jraf.provider.persistence.hibernate.SessionImpl;
import org.squale.jraf.spi.persistence.ISession;
import org.squale.squalecommon.daolayer.DAOMessages;
import org.squale.squalecommon.daolayer.DAOUtils;
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.FactorResultBO;
import org.squale.squalecommon.enterpriselayer.businessobject.result.PracticeResultBO;
import org.squale.squalecommon.enterpriselayer.businessobject.result.QualityResultBO;
/**
* @author M400843
*/
public class QualityResultDAOImpl
extends AbstractDAOImpl
{
/**
* Instance singleton
*/
private static QualityResultDAOImpl instance;
/** log */
private static Log LOG;
/** initialisation du singleton */
static
{
instance = new QualityResultDAOImpl();
}
/**
* Constructeur prive
*/
private QualityResultDAOImpl()
{
initialize( QualityResultBO.class );
LOG = LogFactory.getLog( MarkDAOImpl.class );
}
/**
* Retourne un singleton du DAO
*
* @return singleton du DAO
*/
public static QualityResultDAOImpl getInstance()
{
return instance;
}
/**
* Supprime tous les r�sultats qualit�s li�s � un projet
*
* @param pSession la session
* @param pProject le projet
* @throws JrafDaoException si une erreur � lieu
*/
public void removeWhereProject( ISession pSession, ProjectBO pProject )
throws JrafDaoException
{
String whereClause = "where ";
whereClause += getAlias() + ".project.id = " + pProject.getId();
removeWhere( pSession, whereClause );
}
/**
* Permet de r�cup�rer les notes en fonction d'une liste de composants
*
* @param pSession session Hibernate
* @param pProjectIDs liste des identifiants des composants
* @param pAuditID identifiant de l'audit
* @param pRuleId id de la r�gle qualit�
* @return liste des valeurs ordonn�s par raopport a la liste des composants
* @throws JrafDaoException exception DAO
*/
public List<QualityResultBO> findWhere( ISession pSession, List pProjectIDs, Long pAuditID, Long pRuleId )
throws JrafDaoException
{
List<QualityResultBO> marks = new ArrayList<QualityResultBO>();
Iterator it = pProjectIDs.iterator();
while ( it.hasNext() )
{
Long componentId = (Long) it.next();
marks.add( load( pSession, componentId, pAuditID, pRuleId ) );
}
return marks;
}
/**
* Permet de r�cup�rer les r�sultats de qualit�s en fonction d'une liste d'audits
*
* @param pSession session Hibernate
* @param pProjectID identifiant du composant
* @param pAuditIDs liste des identifiants de l'audit
* @param pRuleId id de la r�gle qualit�
* @return liste des valeurs ordonn�s par raopport a la liste des composants
* @throws JrafDaoException exception DAO
*/
public List<QualityResultBO> findWhere( ISession pSession, Long pProjectID, List pAuditIDs, Long pRuleId )
throws JrafDaoException
{
List<QualityResultBO> marks = new ArrayList<QualityResultBO>();
Iterator it = pAuditIDs.iterator();
while ( it.hasNext() )
{
Long auditId = (Long) it.next();
marks.add( load( pSession, pProjectID, auditId, pRuleId ) );
}
return marks;
}
/**
* Permet de r�cup�rer un r�sultat de qualit� en fonction d'un d'audit, d'un composant et d'un TRE
*
* @param pSession session Hibernate
* @param pProjectID identifiant du composant
* @param pAuditID identifiant de l'audit
* @param pRuleId id du TRE
* @return un r�sultat de qualit�
* @throws JrafDaoException exception DAO
*/
public QualityResultBO load( ISession pSession, Long pProjectID, Long pAuditID, Long pRuleId )
throws JrafDaoException
{
String whereClause = "where ";
whereClause += getAlias() + ".rule.id = " + pRuleId;
whereClause += " and ";
whereClause += getAlias() + ".project.id = '" + pProjectID + "'";
whereClause += " and ";
whereClause += getAlias() + ".audit.id = '" + pAuditID + "'";
QualityResultBO result = null;
Collection col = findWhere( pSession, whereClause );
if ( col.size() >= 1 )
{
result = (QualityResultBO) col.iterator().next();
if ( col.size() > 1 )
{
String tab[] = { pAuditID.toString(), pProjectID.toString(), pRuleId.toString() };
LOG.warn( DAOMessages.getString( "qualityresult.many.audit_project_tre", tab ) );
}
}
return result;
}
/**
* Obtention des r�sultats sur les facteurs
*
* @param pSession session
* @param pProjectID projet
* @param pAuditID audit
* @return r�sultats associ�s
* @throws JrafDaoException si erreur
*/
public Collection findWhere( ISession pSession, Long pProjectID, Long pAuditID )
throws JrafDaoException
{
String whereClause = "where ";
whereClause += getAlias() + ".project.id = '" + pProjectID + "'";
whereClause += " and ";
whereClause += getAlias() + ".audit.id = '" + pAuditID + "'";
whereClause += " and ";
whereClause += getAlias() + ".rule.class='FactorRule'";
whereClause += " order by " + getAlias() + ".rule.name";
QualityResultBO result = null;
Collection col = findWhere( pSession, whereClause );
return col;
}
/**
* Obtention des r�sultats sur les pratiques
*
* @param pSession session
* @param pProjectID projet
* @param pAuditID audit
* @return r�sultats associ�s
* @throws JrafDaoException si erreur
*/
public Collection findPracticesWhere( ISession pSession, Long pProjectID, Long pAuditID )
throws JrafDaoException
{
String whereClause = "where ";
whereClause += getAlias() + ".project.id = '" + pProjectID + "'";
whereClause += " and ";
whereClause += getAlias() + ".audit.id = '" + pAuditID + "'";
whereClause += " and ";
whereClause += getAlias() + ".rule.class='PracticeRule'";
whereClause += " order by " + getAlias() + ".rule.name";
QualityResultBO result = null;
Collection col = findWhere( pSession, whereClause );
return col;
}
/**
* Obtention des r�sultats d'un projet
*
* @param pSession session
* @param pProjectID projet
* @param pAuditID audit
* @param pRuleIDs ids des r�gles qualit�
* @return r�sultats du projet tri�s par nom de r�gle
* @throws JrafDaoException si erreur
*/
public Collection findWhere( ISession pSession, Long pProjectID, Long pAuditID, Collection pRuleIDs )
throws JrafDaoException
{
// Initialisation
Collection col = new ArrayList();
// Protection du code car in () n'est pas valable
if ( pRuleIDs.size() > 0 )
{
StringBuffer ruleIds = new StringBuffer();
Iterator rules = pRuleIDs.iterator();
while ( rules.hasNext() )
{
if ( ruleIds.length() > 0 )
{
ruleIds.append( ',' );
}
ruleIds.append( ( (Long) rules.next() ).longValue() );
}
String whereClause = "where ";
whereClause += getAlias() + ".project.id = '" + pProjectID + "'";
whereClause += " and ";
whereClause += getAlias() + ".audit.id = '" + pAuditID + "'";
whereClause += " and ";
whereClause +=
getAlias() + ".rule.id in (" + ruleIds.toString() + ") order by " + getAlias() + ".rule.name";
// Requ�te dans la base
col = findWhere( pSession, whereClause );
// On compl�te avec des r�sultats nuls dans ce cas
if ( col.size() != pRuleIDs.size() )
{
col = adaptResults( pRuleIDs, col );
}
}
return col;
}
/**
* Obtention des r�sultats d'un projet
*
* @param pSession session
* @param pAcceptanceLevel le niveau (accept�, accept� avec r�serves, refus�s)
* @param pSiteId l'id du site
* @return r�sultats du projet tri�s par nom de r�gle
* @throws JrafDaoException si erreur
*/
public int countFactorsByAcceptanceLevelAndSite( ISession pSession, String pAcceptanceLevel, long pSiteId )
throws JrafDaoException
{
int result = 0;
String whereClause = "where " + getAlias() + ".class='FactorResult'";
if ( pAcceptanceLevel.equals( QualityResultBO.ACCEPTED ) )
{
whereClause += " AND " + getAlias() + ".meanMark <= 3 AND " + getAlias() + ".meanMark >= 2 ";
}
else
{
if ( pAcceptanceLevel.equals( QualityResultBO.RESERVED ) )
{
whereClause += " AND " + getAlias() + ".meanMark < 2 AND " + getAlias() + ".meanMark >= 1 ";
}
else
{
if ( pAcceptanceLevel.equals( QualityResultBO.REFUSED ) )
{
whereClause += " AND " + getAlias() + ".meanMark < 1 AND " + getAlias() + ".meanMark > 0 ";
}
}
}
if ( pSiteId != 0 )
{
whereClause += " AND " + getAlias() + ".project.parent.serveurBO.serveurId='" + pSiteId + "'";
}
// On ne prend que les applications non supprim�es et les audits r�ussis
// ou partiels
whereClause += " AND " + getAlias() + ".project.parent.status!=" + ApplicationBO.DELETED;
// whereClause += " AND " + getAlias()+ ".audit.id =(" + selectLastAudit + ")";
whereClause += " AND (" + getAlias() + ".audit.status=" + AuditBO.TERMINATED;
whereClause += " or " + getAlias() + ".audit.status=" + AuditBO.PARTIAL + ")";
// On tri pour r�cup�rer les r�sultats selon le dernier audit r�ussi ou partiel
// si il n'y a aucun audit r�ussi
whereClause += " order by " + getAlias() + ".project.id, ";
whereClause += getAlias() + ".audit.status asc, coalesce(";
whereClause += getAlias() + ".audit.historicalDate, ";
whereClause += getAlias() + ".audit.date) desc";
LOG.debug( "countFactorsByAcceptanceLevelAndSite:" + whereClause );
// Requ�te dans la base
List results = findWhere( pSession, whereClause );
long lastProjectId = -1;
long lastAuditId = -1;
for ( int i = 0; i < results.size(); i++ )
{
QualityResultBO cur = (QualityResultBO) results.get( i );
if ( cur.getProject().getId() != lastProjectId )
{
result++;
lastAuditId = cur.getAudit().getId();
}
else if ( cur.getAudit().getId() == lastAuditId )
{
result++;
}
lastProjectId = cur.getProject().getId();
}
return result;
}
/**
* Adaptation des r�sultats La liste des r�sultats peut �tre diff�rente de celle des r�gles, dans ce cas on cr�e des
* r�sultats vierges pour faire en sorte que la liste des r�sultats concorde avec celle des r�gles
*
* @param pRuleIDs liste des r�gles
* @param pResults liste des r�sultats
* @return liste des r�sultats adapt�e
*/
private Collection adaptResults( Collection pRuleIDs, Collection pResults )
{
Collection result = new ArrayList();
Iterator rules = pRuleIDs.iterator();
Iterator results = pResults.iterator();
QualityResultBO currentResult = null;
// Initialisation du r�sultat courant
if ( results.hasNext() )
{
currentResult = (QualityResultBO) results.next();
} // Parcours de toutes les r�gles
while ( rules.hasNext() )
{
Long rule = (Long) rules.next();
// Si il n'existe pas de r�sultat correspondant � la r�gle, on
// en cr�e un qui soit vierge avec une note de -1
if ( ( currentResult == null ) || ( rule.longValue() != currentResult.getRule().getId() ) )
{
QualityResultBO res = new FactorResultBO( -1.0f, null, null, null );
result.add( res );
}
else
{ // Le r�sultat est en concordance avec la r�gle
result.add( currentResult ); // On passe au r�sultat suivant
if ( results.hasNext() )
{
currentResult = (QualityResultBO) results.next();
}
else
{
currentResult = null;
}
}
}
return result;
}
/**
* This method recover the last mark inserted (if there is one) for a manual practice
*
* @param pSession hibernate session
* @param pProjectID Id of the project
* @param pRuleId Id of the practice rule
* @return The PraticeresultBO linked to the last manual mark inserted for the rule id and the project id give in
* argument. This method return null if it finds nothing.
* @throws JrafDaoException exception happen during the hibernate search
*/
public PracticeResultBO findLastManualMark( ISession pSession, Long pProjectID, Long pRuleId )
throws JrafDaoException
{
StringBuffer whereClause = new StringBuffer( "where " );
whereClause.append( getAlias() + ".rule.id = " + pRuleId );
whereClause.append( " and " + getAlias() + ".project.id = " + pProjectID );
whereClause.append( " and " + getAlias() + ".meanMark!= -1.0" );
// This mark is not linked to an audit
whereClause.append( " and " + getAlias() + ".audit.id is null" );
whereClause.append( " order by " + getAlias() + ".creationDate desc" );
whereClause.append( " , " + getAlias() + ".id desc" );
List col = findWhere( pSession, whereClause.toString() );
PracticeResultBO result = null;
if ( col.size() > 0 )
{
// Recovery the last inserted mark
result = (PracticeResultBO) col.get( 0 );
}
return result;
}
/**
* This method return the list of all the mark inserted for manual practice between the date give in argument and
* today
*
* @param pSession The hibernate session
* @param pProjectID The ID of the project
* @param pRuleId The rule ID
* @param date The limit date
* @return The list of mark
* @throws JrafDaoException Exception happen during the search in the DB
*/
public Collection<PracticeResultBO> findManualMarkSince( ISession pSession, Long pProjectID, Long pRuleId, Date date )
throws JrafDaoException
{
StringBuffer whereClause = new StringBuffer( "where " );
whereClause.append( getAlias() + ".rule.id = " + pRuleId );
whereClause.append( " and " + getAlias() + ".project.id = " + pProjectID );
whereClause.append( " and " + getAlias() + ".meanMark!= -1.0" );
whereClause.append( " and " + getAlias() + ".audit.id is null" );
whereClause.append( " and " + getAlias() + ".creationDate > " + DAOUtils.makeQueryDate( date ) );
whereClause.append( " order by " + getAlias() + ".creationDate desc" );
whereClause.append( " , " + getAlias() + ".id desc" );
Collection<PracticeResultBO> col = findWhere( pSession, whereClause.toString() );
return col;
}
/***
* This method return the last manual mark inserted (if there is one) for a manual practice and a specific audit
*
* @param pSession The hibernate session
* @param pProjectId The ID of the project
* @param pRuleId The rule ID
* @param pAuditId The audit ID
* @return The PracticeRsultBO linked to the last manual mark inserted for the rule, the project and the audit
* specified in argument. This method returns null if it finds nothing.
* @throws JrafDaoException Exception happen during the hibernate search
*/
public PracticeResultBO findLastManualMarkByAudit( ISession pSession, Long pProjectId, Long pRuleId, Long pAuditId )
throws JrafDaoException
{
StringBuffer whereClause = new StringBuffer( "where " );
whereClause.append( getAlias() + ".rule.id = " + pRuleId );
whereClause.append( " and " + getAlias() + ".project.id = " + pProjectId );
whereClause.append( " and " + getAlias() + ".audit.id = " + pAuditId );
whereClause.append( " and " + getAlias() + ".meanMark!= -1.0" );
List col = findWhere( pSession, whereClause.toString() );
PracticeResultBO result = null;
if ( col.size() > 0 )
{
// Recovery the last inserted mark for a specific audit
result = (PracticeResultBO) col.get( 0 );
}
return result;
}
/**
* Returns raw data that will be used by the Distribution Map to display, for a specific practice, the marks of all
* the components related to this practice, for the given audit and project. <br>
* The raw data that is returned is a list of arrays, each array containing the following data:
* <ul>
* <li>0 - the component ID [long]</li>
* <li>1 - the component name [String]</li>
* <li>2 - the ID of the component's parent [long]</li>
* <li>3 - the name of the component's parent [String]</li>
* <li>4 - the mark of this component for the practice [float]</li>
* </ul>
*
* @param session The hibernate session
* @param auditId the audit
* @param projectId the project
* @param practiceId the practice
* @param componentLevel the level of components for this practice
* @return a list of object arrays, each array corresponding to the data of a component related to the practice
* @throws JrafDaoException if the method fails to retrieve the data
*/
@SuppressWarnings( "unchecked" )
public List<Object[]> findMarkDistribution( ISession session, long auditId, long projectId, long practiceId,
String componentLevel )
throws JrafDaoException
{
List<Object[]> result = new ArrayList<Object[]>();
try
{
String requete =
"select component.id, component.name, component.parent.id, component.parent.name, mark.value from AbstractComponentBO component, MarkBO mark where lower(component.class)='"
+ componentLevel.toLowerCase()
+ "' and component.project.id="
+ projectId
+ " and "
+ auditId
+ " in elements(component.audits) and mark.practice.rule.id="
+ practiceId
+ "and mark.practice.audit.id=" + auditId + " and mark.component.id=component.id";
Query query = ( (SessionImpl) session ).getSession().createQuery( requete );
result = query.list();
}
catch ( HibernateException e )
{
throw new JrafDaoException( "Database problem while retrieving data for " + getClass().getName()
+ ".getMarkDistribution", e );
}
return result;
}
/**
* Returns raw data that will be used by the Motion Chart. <br>
* The raw data that is returned is a list of arrays, each array containing the following data:
* <ul>
* <li>0 - the project ID [long]</li>
* <li>1 - the project name [String]</li>
* <li>2 - the audit ID [long]</li>
* <li>3 - the audit historical date [Date] - can be NULL</li>
* <li>4 - the audit start date [Date]</li>
* <li>5 - the metric name [String]</li>
* <li>6 - the metric value [IntegerMetricBO]</li>
* </ul>
*
* @param session The hibernate session
* @param applicationId the application DB identifier
* @return a list of object arrays, each array corresponding to the data described above
* @throws JrafDaoException if the method fails to retrieve the data
*/
@SuppressWarnings( "unchecked" )
public List<Object[]> findMetricsForMotionChart( ISession session, long applicationId )
throws JrafDaoException
{
List<Object[]> result = new ArrayList<Object[]>();
try
{
String requete =
"select component.id, component.name, audit.id, audit.historicalDate, audit.date, metric.name, metric"
+ " from AbstractComponentBO component, AuditBO audit, MeasureBO measure, MetricBO metric"
+ " where component.class='Project' and component.parent.id=" + applicationId
+ " and audit.id in elements(component.audits)" + " and audit.status=" + AuditBO.TERMINATED
+ " and measure.audit.id=audit.id and measure.component.id=component.id"
+ " and metric.measure.id=measure.id and metric.class='Int'"
+ " and (metric.name='numberOfCodeLines' or metric.name='sumVg')"
+ " order by audit.id, metric.name";
Query query = ( (SessionImpl) session ).getSession().createQuery( requete );
result = query.list();
}
catch ( HibernateException e )
{
throw new JrafDaoException( "Database problem while retrieving data for " + getClass().getName()
+ ".findMetricsForMotionChart", e );
}
return result;
}
/**
* This method retrieves the factor linked to the audit and the application given in argument
*
* @param session The hibernate session
* @param applicationId the application id
* @param auditId Then audit id
* @return The list of factor linked to the current audit
* @throws JrafDaoException Exception occurs during the retrieve of the factors
*/
public List<QualityResultBO> findFactor( ISession session, Long applicationId, Long auditId )
throws JrafDaoException
{
StringBuffer whereClause = new StringBuffer( " where " );
whereClause.append( getAlias() );
whereClause.append( ".project.parent.id = " );
whereClause.append( applicationId );
whereClause.append( " and " );
whereClause.append( getAlias() );
whereClause.append( ".audit.id = " );
whereClause.append( auditId );
whereClause.append( " and " );
whereClause.append( getAlias() );
whereClause.append( ".rule.class='FactorRule' order by " );
whereClause.append( getAlias() );
whereClause.append( ".project.name ," );
whereClause.append( getAlias() );
whereClause.append( ".rule.name" );
List<QualityResultBO> result = null;
result = (List<QualityResultBO>) findWhere( session, whereClause.toString() );
LOG.debug( whereClause.toString() );
return result;
}
}