/**
* 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/>.
*/
/*
* Cr�� le 8 juil. 05
*
* Pour changer le mod�le de ce fichier g�n�r�, allez � :
* Fen�tre>Pr�f�rences>Java>G�n�ration de code>Code et commentaires
*/
package org.squale.squalecommon.daolayer.component;
import java.util.ArrayList;
import java.util.Collection;
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.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.ProjectBO;
import org.squale.squalecommon.enterpriselayer.businessobject.tag.TagBO;
import org.squale.squalecommon.util.mapping.Mapping;
/**
* @author M400843
*/
public class AbstractComponentDAOImpl
extends AbstractDAOImpl
{
/**
* Instance singleton
*/
private static AbstractComponentDAOImpl instance = null;
/** log */
private static Log LOG;
/** initialisation du singleton */
static
{
instance = new AbstractComponentDAOImpl();
}
/**
* Constructeur prive
*
* @throws JrafDaoException
*/
private AbstractComponentDAOImpl()
{
initialize( AbstractComponentBO.class );
if ( null == LOG )
{
LOG = LogFactory.getLog( AbstractComponentDAOImpl.class );
}
}
/**
* Retourne un singleton du DAO
*
* @return singleton du DAO
*/
public static AbstractComponentDAOImpl getInstance()
{
return instance;
}
/**
* R�cup�re les enfants de pProjet selon un audit et un type
*
* @param pSession la session
* @param pProjet le projet dont on veut les enfants
* @param pAudit l'audit
* @param pClass la classe du type dont on veut les enfants
* @return une collection d'enfants du projet du type demand�
* @throws JrafDaoException si une erreur � lieu
*/
public Collection findProjectChildren( ISession pSession, ProjectBO pProjet, AuditBO pAudit, Class pClass )
throws JrafDaoException
{
Collection children = new ArrayList();
// si la type d'enfant demand� est ApplicationBO, on retourne le projet
if ( pClass.isAssignableFrom( ApplicationBO.class ) )
{
children.add( pProjet );
}
else
{
// R�cup�ration de tout les composants �tant rattach� � l'audit concern�
String whereClause = "where ";
whereClause += pAudit.getId() + " in elements(" + getAlias() + ".audits)";
Iterator it = findWhere( pSession, whereClause ).iterator();
while ( it.hasNext() )
{
// Pour chaque enfant
AbstractComponentBO child = (AbstractComponentBO) it.next();
if ( pClass.isInstance( child ) )
{
/*
* Si l'enfant est du type souhait�, on v�rifie qu'il est bien enfant du projet demand�
* (indispensable si l'application � plusieurs projets)
*/
AbstractComponentBO tmpChild = child.getParent();
// tant que l'on a pas trouv� le projet et qu'il existe un parent
while ( ( null != tmpChild ) )
{
if ( tmpChild.equals( pProjet ) )
{
// si on a trouv� le projet, on ajoute l'enfant � la collection de retour
children.add( child );
// et on met tmpChild pour stopper le while
tmpChild = null;
}
else
{
// sinon on r�cup�re le parent suivant (parent du parent...)
tmpChild = tmpChild.getParent();
}
}
}
}
}
return children;
}
/**
* R�cup�re le composant dont le nom est pName et dont le parent est pParent.
*
* @param pSession la session
* @param pParent le parent du composant que l'on veut
* @param pName le nom du composant � chercher
* @return le composant recherch� ou null si il n'est pas pr�sent en base.
* @throws JrafDaoException si une erreur � lieu
*/
public AbstractComponentBO findChild( ISession pSession, AbstractComponentBO pParent, String pName )
throws JrafDaoException
{
AbstractComponentBO child = null;
String whereClause = "where ";
whereClause += getAlias() + ".parent=" + pParent.getId();
whereClause += "and " + getAlias() + ".name='" + pName + "'";
Iterator it = findWhere( pSession, whereClause ).iterator();
if ( it.hasNext() )
{
child = (AbstractComponentBO) it.next();
}
return child;
}
/**
* @param pSession la session
* @return les composants exclus du plan d'action
* @throws JrafDaoException en cas d'�chec
*/
public Collection getExcludedFromPlan( ISession pSession )
throws JrafDaoException
{
Collection components = new ArrayList( 0 );
String whereClause = "where " + getAlias() + ".excludedFromActionPlan=1";
components = findWhere( pSession, whereClause );
return components;
}
/**
* @param pSession la session
* @param pParentId l'id du parent
* @param pAuditId l'id de l'audit, peut �tre <code>null</code>
* @param pType le type de composants, peut �tre <code>null</code>
* @param pFilter le filtre sur le nom, peut �tre <code>null</code>
* @return les enfants (1000 au max) dont le parent a l'id <code>pParentId</code> de type <code>pType</code>
* rattach�s � l'audit d'id <code>pAuditId</code> et dont le nom correspond au pattern
* <code>*pFilter*</code>
* @throws JrafDaoException si erreur
*/
public Collection findChildrenWhere( ISession pSession, Long pParentId, Long pAuditId, String pType, String pFilter )
throws JrafDaoException
{
final int nbLines = 1000;
StringBuffer whereClause =
new StringBuffer( getCommonWhereChildrenRequest( pParentId, pAuditId, pType, pFilter ) );
whereClause.append( " order by " );
whereClause.append( getAlias() );
whereClause.append( ".name" );
LOG.debug( "findChildrenWhere: " + whereClause );
return (Collection) findWhereScrollable( pSession, whereClause.toString(), nbLines, 0, false );
}
/**
* @param pSession la session
* @param pParentId l'id du parent
* @param pAuditId l'id de l'audit, peut �tre <code>null</code>
* @param pSubClassName le type de composants, peut �tre <code>null</code>
* @return tous les enfants dont le parent a l'id <code>pParentId</code> de type <code>pSubClassName</code>
* rattach�s � l'audit d'id <code>pAuditId</code>
* @throws JrafDaoException si erreur
*/
public Collection findAllChildrenWhere( ISession pSession, Long pParentId, Long pAuditId, String pSubClassName )
throws JrafDaoException
{
StringBuffer whereClause = new StringBuffer( "where " );
whereClause.append( getAlias() + ".parent.id=" + pParentId );
if ( null != pAuditId )
{
whereClause.append( " and " );
whereClause.append( pAuditId + " in elements (" + getAlias() + ".audits)" );
}
if ( null != pSubClassName )
{
whereClause.append( " and " );
whereClause.append( getAlias() + ".class='" + pSubClassName + "'" );
}
LOG.warn( "findAllChildrenWhere: " + whereClause );
return (Collection) findWhere( pSession, whereClause.toString() );
}
/**
* @param pSession la session
* @param pParentId l'id du parent
* @param pAuditId l'id de l'audit, peut �tre <code>null</code>
* @param pType le type de composants, peut �tre <code>null</code>
* @param pFilter le filtre sur le nom, peut �tre <code>null</code>
* @return le nombre d'enfants dont le parent a l'id <code>pParentId</code> de type <code>pType</code> rattach�s �
* l'audit d'id <code>pAuditId</code> et dont le nom correspond au pattern <code>*pFilter*</code>
* @throws JrafDaoException si erreur
*/
public Integer countChildrenWhere( ISession pSession, Long pParentId, Long pAuditId, String pType, String pFilter )
throws JrafDaoException
{
return countWhere( pSession, getCommonWhereChildrenRequest( pParentId, pAuditId, pType, pFilter ) );
}
/**
* @param pParentId l'id du parent
* @param pAuditId l'id de l'audit, peut �tre <code>null</code>
* @param pType le type de composants, peut �tre <code>null</code>
* @param pFilter le filtre sur le nom, peut �tre <code>null</code>
* @return la clause where de recherche des enfants selon les crit�res pass�s en param�tre de type
* <code>pType</code> rattach�s � l'audit d'id <code>pAuditId</code> et dont le nom correspond au pattern
* <code>*pFilter*</code>
*/
private String getCommonWhereChildrenRequest( Long pParentId, Long pAuditId, String pType, String pFilter )
{
StringBuffer whereClause = new StringBuffer( "where " );
whereClause.append( getAlias() + ".parent.id=" + pParentId );
if ( null != pAuditId )
{
whereClause.append( " and " );
whereClause.append( pAuditId + " in elements (" + getAlias() + ".audits)" );
}
if ( null != pType )
{
// On r�cup�re le nom de la classe
String className = Mapping.getComponentMappingName( pType );
whereClause.append( " and " );
whereClause.append( getAlias() + ".class='" + className + "'" );
}
if ( null != pFilter )
{
whereClause.append( " and " );
whereClause.append( getAlias() + ".name like '%" + pFilter + "%'" );
}
return whereClause.toString();
}
/**
* Get components which have somme values for some tres
*
* @param pSession session
* @param pProjectId project id
* @param pAuditId audit id
* @param pTreKeys tres
* @param pTreValues value of tres
* @param pMax number of result to get
* @return list of components
* @throws JrafDaoException if error in database
*/
public List<AbstractComponentBO> findWhereTres( ISession pSession, long pProjectId, long pAuditId,
String[] pTreKeys, String[] pTreValues, Integer pMax )
throws JrafDaoException
{
SessionImpl sessionHibernate = (SessionImpl) pSession;
List<AbstractComponentBO> results = new ArrayList<AbstractComponentBO>();
String from = "";
String distinct = "";
String where = "";
// Creation de la requete
// /!\ Requete optimis�e car longue en prod
// TOUTES MODIF DOIT ETRE TESTEES EN FAISANT LE SELECT EN PROD !!
// Cette requ�te prend moins d'1 seconde en production
for ( int i = 0; i < pTreKeys.length; i++ )
{
// selecte sur n metric
// => construction des selects, from, et where de la query
if ( i > 0 )
{
distinct += ",";
}
from += ",IntegerMetricBO metric" + i;
where +=
" and metric" + i + ".measure.audit.id=" + pAuditId + " and metric" + i + ".measure.component.id="
+ getAlias() + ".id" + " and metric" + i + ".measure.class="
+ Mapping.getMetricClass( pTreKeys[i] ).getName() + " and metric" + i + ".name = '"
+ pTreKeys[i].substring( pTreKeys[i].lastIndexOf( '.' ) + 1 ) + "'" + " and metric" + i + ".value="
+ pTreValues[i];
}
// execution de la requete
try
{
// remonte les valeurs distinctes en une seule requete pour des raisons de perf
Query q =
sessionHibernate.getSession().createQuery( "select " + getAlias() + " "
// On ne recherche pas le type du composant afin
// d'optimiser la requ�te car la recherche
// est d�j� faite par le type de la m�trique.
+ getRequete() + from + " where (" + getAlias() + ".project.id =" + pProjectId + ")" + where ).setMaxResults(
pMax );
results = q.list();
}
catch ( HibernateException e )
{
throw new JrafDaoException( e );
}
return results;
}
/**
* This method returns the list of tags linked to the current component
*
* @param session The hibernate session
* @param componentId The technical id of the component
* @return The list of tags linked to the current component
* @throws JrafDaoException exception occurrs during the retrieve
*/
public List<TagBO> getTags( ISession session, long componentId )
throws JrafDaoException
{
List<TagBO> listToReturn = null;
StringBuffer request = new StringBuffer( "Select compo.tags from AbstractComponentBO compo where " );
request.append( "compo.id = " );
request.append( componentId );
listToReturn = find( session, request.toString() );
return listToReturn;
}
}