/**
* 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/>.
*/
/*
* Created on 3 ao�t 06
*
*/
package org.squale.squalix.core.purge;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.squale.jraf.commons.exception.JrafDaoException;
import org.squale.jraf.commons.exception.JrafPersistenceException;
import org.squale.jraf.helper.PersistenceHelper;
import org.squale.jraf.spi.persistence.ISession;
import org.squale.squalecommon.daolayer.component.ApplicationDAOImpl;
import org.squale.squalecommon.daolayer.component.AuditDAOImpl;
import org.squale.squalecommon.daolayer.component.ProjectDAOImpl;
import org.squale.squalecommon.daolayer.config.web.AbstractDisplayConfDAOImpl;
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.squalix.core.CoreMessages;
/**
* Thread s�par�e de purge
* @author M401540
*/
public class Purge
extends Thread
{
/**
* Logger
*/
private static final Log LOGGER = LogFactory.getLog( Purge.class );
/**
* Site
*/
private long mSiteId;
/**
* La liste des applications qui vont �tre audit�es en m�me temps que la purge. Pour �viter d'avoir des croisements
* de session, on ne va pas purger les audits qui rattach� � une de ces applications
*/
private Set mForbiddenApplis = new HashSet();
/**
* Fichier de configuration de la purge.
*/
private final String mPurgeConfigFile = "config/purge.xml";
/**
* Analyseur de fichier de configuration de la purge d'audits.
*/
private final PurgeConfParser mPurgeConfParser = new PurgeConfParser();
/**
* Constructeur
*
* @param pSiteId site de lancement
* @param pRunningAudits les audits qui vont �tre lanc�s
*/
public Purge( long pSiteId, List pRunningAudits )
{
mSiteId = pSiteId;
configPurge();
setForbiddenApplis( pRunningAudits );
}
/**
* Lance le Thread de purge des applications et des audits
*/
public void run()
{
try
{
// ouvre une session Hibernate
ISession session = PersistenceHelper.getPersistenceProvider().getSession();
// purge des audits supprim�s ou obsol�tes � supprimer
purgeAudits( session );
// On va purger les configurations d'affichage qui ne servent plus
// i.e. qui ne sont plus rattach�es ni � un audit, ni a un profil
session.beginTransaction();
AbstractDisplayConfDAOImpl.getInstance().removeUnusedConf( session );
session.commitTransactionWithoutClose();
// Apr�s les audits, on va supprimer les projets...
session.beginTransaction();
Collection projects =
ProjectDAOImpl.getInstance().findWhereStatusAndSite( session, ProjectBO.DELETED, mSiteId );
Iterator it = projects.iterator();
LOGGER.info( CoreMessages.getString( "projects.todelete", new Object[] { new Integer( projects.size() ) } ) );
session.commitTransactionWithoutClose();
while ( it.hasNext() )
{
ProjectBO p = (ProjectBO) it.next();
// supresion physique comme pour les audits
// Commit un par un pour des raisons de perf
session.beginTransaction();
ProjectDAOImpl.getInstance().remove( session, (Object) p );
session.commitTransactionWithoutClose();
}
// maintenant que tous les audits sont supprim�s, on peut supprimer les applis...
session.beginTransaction();
it = ApplicationDAOImpl.getInstance().findWhereStatus( session, ApplicationBO.DELETED ).iterator();
session.commitTransactionWithoutClose();
while ( it.hasNext() )
{
ApplicationBO a = (ApplicationBO) it.next();
// du site
if ( a.getServeurBO() == null || a.getServeurBO().getServeurId() == mSiteId )
{
// supresion physique comme pour les audits
// Commit un par un pour des raisons de perf
session.beginTransaction();
ApplicationDAOImpl.getInstance().remove( session, (Object) a );
session.commitTransactionWithoutClose();
}
}
// ferme la session
session.closeSession();
}
catch ( JrafPersistenceException e )
{
LOGGER.error( e, e );
}
catch ( JrafDaoException e )
{
LOGGER.error( e, e );
}
}
/**
* Purge les audits supprim�s ou obsol�tes au regard de la fr�quence de purge de l'application. <br />
* Pour les audits de jalon, seuls les audits en �chec sont supprim�s. <br />
* Pour les audits de suivi, un minimum d'audits obsol�tes sont conserv�s pour historique (selon configuration).
* <br />
* Un maximum donn� d'audits sont supprim�s (selon configuration). Pr�-condition : la liste des audits est tri�e par
* date d�croissante.
*
* @param pSession session de persistence.
* @throws JrafDaoException si exception de persistence.
*/
private void purgeAudits( ISession pSession )
throws JrafDaoException
{
int lNbAuditsDeleted = 0;
// suppression des audits supprim�s qui n'appartiennent pas � une application
// audit�e dans un thread parall�le
Iterator it = AuditDAOImpl.getInstance().findDeleted( pSession, mSiteId, mForbiddenApplis ).iterator();
while ( it.hasNext() && lNbAuditsDeleted < mPurgeConfParser.getMaxAuditsToDelete().intValue() )
{
AuditBO a = (AuditBO) it.next();
// Commit un par un pour des raisons de perf/charge
purgeOneAudit( pSession, a );
lNbAuditsDeleted++;
LOGGER.info( CoreMessages.getString( "purge.info.deleted", new Object[] { new Long( a.getId() ) } ) );
}
// traitement des audits obsol�tes � supprimer
List lAuditsList = AuditDAOImpl.getInstance().findObsoleteAuditsToDelete( pSession, mSiteId, mForbiddenApplis );
List lAuditsToDelete = new ArrayList();
List lTreatedApplicationsList = new ArrayList();
it = lAuditsList.iterator();
// les derniers audits obsol�tes de suivi d'une application sont conserv�s
while ( it.hasNext() )
{
Object[] lListItem = (Object[]) it.next();
AuditBO lAuditBO = (AuditBO) lListItem[0];
ApplicationBO lApplicationBO = (ApplicationBO) lListItem[1];
if ( !lTreatedApplicationsList.contains( new Long( lApplicationBO.getId() ) ) )
{
// copie des audits obsol�tes de suivi � ne pas conserver
Iterator it2 = lAuditsList.iterator();
int lNbAuditsKept = 0;
while ( it2.hasNext() )
{
Object[] lListItem2 = (Object[]) it2.next();
AuditBO lAuditBO2 = (AuditBO) lListItem2[0];
ApplicationBO lApplicationBO2 = (ApplicationBO) lListItem2[1];
if ( lApplicationBO.getId() == lApplicationBO2.getId() )
{
if ( lAuditBO2.getType().equals( AuditBO.NORMAL )
&& lNbAuditsKept < mPurgeConfParser.getMinObsoleteAuditsToKeep().intValue() )
{
lNbAuditsKept++;
}
else
{
lAuditsToDelete.add( lAuditBO2 );
}
}
}
// les audits de l'application ont �t� trait�s
lTreatedApplicationsList.add( new Long( lApplicationBO.getId() ) );
}
}
// suppression des audits obsol�tes � supprimer (ordre chronologique)
final int lNbAuditsToDelete = lAuditsToDelete.size();
int i = lNbAuditsToDelete - 1;
while ( i >= 0 && lNbAuditsDeleted < mPurgeConfParser.getMaxAuditsToDelete().intValue() )
{
AuditBO lAuditBO = (AuditBO) lAuditsToDelete.get( i );
purgeOneAudit( pSession, lAuditBO );
lNbAuditsDeleted++;
i--;
LOGGER.info( CoreMessages.getString( "purge.info.obsolete", new Object[] { new Long( lAuditBO.getId() ) } ) );
}
}
/**
* Supprime un audit.
*
* @param pSession session de persistence.
* @param pAuditBO audit � supprimer.
* @throws JrafDaoException exception de persistence.
*/
private void purgeOneAudit( ISession pSession, AuditBO pAuditBO )
throws JrafDaoException
{
// supprime vraiment l'audit (et tous le reste avec le delete cascade)
// en appelant la methode remove Object (et no AuditBO qui ne realise
// que le delete logique
pSession.beginTransaction();
AuditDAOImpl.getInstance().remove( pSession, (Object) pAuditBO );
pSession.commitTransactionWithoutClose();
}
/**
* Configure la purge.
*/
private void configPurge()
{
try
{
mPurgeConfParser.parse( new FileInputStream( mPurgeConfigFile ) );
// suppression de la contrainte de maximum d'audits
if ( mPurgeConfParser.getMaxAuditsToDelete().intValue() < 0 )
{
mPurgeConfParser.setMaxAuditsToDelete( new Integer( Integer.MAX_VALUE ) );
}
}
catch ( Exception e )
{
// r�-initialisation de la configuration de purge
mPurgeConfParser.setMinObsoleteAuditsToKeep( new Integer( 0 ) );
mPurgeConfParser.setMaxAuditsToDelete( new Integer( 0 ) );
LOGGER.error( CoreMessages.getString( "purge.config.error.1" ) );
LOGGER.error( CoreMessages.getString( "purge.config.error.2" ) );
}
}
/**
* Cr�er l'ensemble des ids des applications audit�es en m�me temps que la purge
*
* @param pRunningAudits les audits qui peuvent �tre audit�s en m�me temps que la purge
*/
private void setForbiddenApplis( List pRunningAudits )
{
try
{
// ouvre une session Hibernate
ISession session = PersistenceHelper.getPersistenceProvider().getSession();
ApplicationBO curAppli;
AuditBO curAudit;
for ( int i = 0; i < pRunningAudits.size(); i++ )
{
curAudit = (AuditBO) pRunningAudits.get( i );
curAppli = ApplicationDAOImpl.getInstance().loadByAuditId( session, new Long( curAudit.getId() ) );
// On ajoute son id au set
mForbiddenApplis.add( new Long( curAppli.getId() ) );
}
// ferme la session
session.closeSession();
}
catch ( JrafPersistenceException e )
{
LOGGER.error( e, e );
}
catch ( JrafDaoException e )
{
LOGGER.error( e, e );
}
}
}