/**
* 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/>.
*/
//Source file: D:\\cc_views\\squale_v0_0_act\\squale\\src\\squalix\\src\\org\\squale\\squalix\\core\\AuditExecutor.java
package org.squale.squalix.core;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
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.config.TaskRefBO;
import org.squale.squalix.messages.Messages;
/**
* Ex�cute un audit entier sur un projet. <br />
* Il ex�cute les t�ches associ�e � une application en les ordonnan�ant. Cet ordonnancement des t�ches est d�termin� par
* rapport au profil du projet. La configuration doit d�finir un sc�nario d'ex�cution pour le profil du projet. Voir la
* configuration de Squalix pour plus de renseignements. <br />
* <br />
* Toutes les t�ches que lancent l'ex�cuteur d'analyse doivent h�riter de la classe abstraite <code>Task</code>.
* <br />
* <br />
* Deux groupes de t�ches sont lanc�s par l'ex�cuteur d'analyse :
* <ul>
* <li>le premier concerne les analyses par des outils divers,</il>
* <li>le second n�cessite que toutes les t�ches du premier soient termin�es (consolidation de r�sultats, g�n�ration de
* graphiques...).</li>
* </ul>
*
* @see org.squale.squalix.configurationmanager.Configuration
* @author m400842
* @version 1.0
*/
public class AuditExecutor
implements Runnable
{
/**
* Statut de l'ex�cution de l'audit � la fin de l'ex�cution
*/
private int mFinalStatus = AuditBO.NOT_ATTEMPTED;
/**
* Audit param�trant l'analyse.
*/
private AuditBO mAudit;
/**
* Projet sur lequel est ex�cut�e l'audit.
*/
private ProjectBO mProject;
/**
* Logger
*/
private static final Log LOGGER = LogFactory.getLog( AuditExecutor.class );
/**
* Liste des t�ches instanci�es dans l'audit.
*/
private List mTasks;
/**
* T�ches � r�aliser lorsque toutes les t�ches d'analyse sont termin�es.
*/
private List mTerminationTasks = null;
/**
* Instance du scheduleur de l'audit
*/
private Scheduler mScheduler = null;
/**
* Constructor.<br>
* Create the audit executor which contains task and termination task to execute for an audit.
*
* @param pAudit The audit to do.
* @param pProject Project on which we realize the audit.
* @param pTasks Analyze tasks to realize.
* @param pTerminationTasks Termination task to realize
* @param lastProject Is it the last project ?
* @roseuid 42AE866F01F7
*/
public AuditExecutor( final List pTasks, final List pTerminationTasks, final AuditBO pAudit,
final ProjectBO pProject, boolean lastProject )
{
/*
* The TaskData contains some temporary parameter. Empty at the beginning, it could be modified by each task.
* Then the following tasks could recover the informations they need and which depends from a previous task.
*/
TaskData taskData = new TaskData();
ApplicationBO appli = (ApplicationBO) pProject.getParent();
// Creation des t�ches d'analyse
mTasks = new ArrayList();
AbstractTask task = null;
for ( int i = 0; i < pTasks.size(); i++ )
{
// Creation of each task
task =
TaskUtility.createTask( (TaskRefBO) pTasks.get( i ), pProject.getId(), pProject.getParent().getId(),
pAudit.getId(), taskData );
// The list of task is completed with the new one
mTasks.add( task );
}
// Creation des t�ches de compl�tude sur le m�me sch�ma
mTerminationTasks = new ArrayList();
for ( int i = 0; i < pTerminationTasks.size(); i++ )
{
task =
TaskUtility.createTask( (TaskRefBO) pTerminationTasks.get( i ), pProject.getId(),
pProject.getParent().getId(), pAudit.getId(), taskData );
// Is the task a source code recovering termination task ?
if ( task instanceof AbstractSourceTerminationTask )
{
// if yes then we should determine if task does the optimization of the source code recovering
AbstractSourceTerminationTask sourceterminationtask = (AbstractSourceTerminationTask) task;
if ( sourceterminationtask.doOptimization() )
{
// If the task does the optimization of the source code recovering then we don't add this task to
// the list and we keep it for after
appli.getSourceCodeTerminationTask().add( pTerminationTasks.get( i ) );
}
else
{
// If the task doesn't do the optimization of the source code recovering then we add it to list of
// termination task
mTerminationTasks.add( task );
}
}
else
{
// if the task is not a source code recovering termination task then we add it to the list of
// termination task
mTerminationTasks.add( task );
}
}
// Is it the last project of this Audit ?
if ( lastProject )
{
// If yes then we add all source code termination task we keep
Iterator keepTaskIt = appli.getSourceCodeTerminationTask().iterator();
while ( keepTaskIt.hasNext() )
{
// Creation of each task
task =
TaskUtility.createTask( (TaskRefBO) keepTaskIt.next(), pProject.getId(),
pProject.getParent().getId(), pAudit.getId(), taskData );
// The termination task list is completed with the new one
mTerminationTasks.add( task );
}
}
mAudit = pAudit;
mProject = pProject;
}
/**
* @param pTask la t�che observ�e ayant chang� de statut.
* @return un bool�en indiquant si on doit continuer � faire les taches d'analyse, return false si une tache a
* �chou�e
* @roseuid 42C29E870138
*/
public boolean update( final AbstractTask pTask )
{
// bool�en indiquant si on doit continuer � faire l'ensemble
// des taches normalement ou si on doit arr�ter si il y a eu un probl�me
boolean stop = false;
int status = pTask.getStatus();
Iterator it = mTasks.iterator();
if ( AbstractTask.FAILED == status )
{
// la tache a �chou�e
// On stoppe l'audit de toutes les t�ches en cours non encore lanc�es
// En les mettant en statut CANCELLED
LOGGER.error( "La tache : " + pTask.getClass().getName() + " a echouee" );
// On parcours la liste des taches jusqu'� celle pass�e en param�tre
while ( it.hasNext() && (AbstractTask) it.next() != pTask )
{
}
;
// on dit que celle l� a �chou�e
pTask.setStatus( AbstractTask.FAILED );
// Si la tache �tait obligatoire, on annule les autres sinon on continue
// mais dans tous les cas la tache est mise en echec
stop = pTask.isMandatoryTask();
if ( stop )
{
// et on change le status des suivantes � "annuler"
while ( it.hasNext() )
{
AbstractTask t = (AbstractTask) it.next();
TaskUtility.stopTask( t );
LOGGER.info( "La tache : " + t.getClass().getName() + " a ete annulee" );
}
}
}
return stop;
}
/**
* Renvoie le status de l'audit executor apr�s analyse des status de toutes les taches
*
* @return le status
*/
private int getStatus()
{
// Initialisation � termin� par d�faut
int result = AuditBO.TERMINATED;
// On met dans les conditions de sortie de la boucle le staus failed,
// car une fois que c'est failed c'est d�finitif
// On n'affecte jamais termin� dans la boucle, car si on passe dans un des tests
// c'est qu'il ne peut pas etre termin�
// Termin� < partiel < failed
for ( int i = 0; result != AuditBO.FAILED && i < mTasks.size(); i++ )
{
AbstractTask task = ( (AbstractTask) mTasks.get( i ) );
if ( task.getStatus() == AbstractTask.FAILED )
{
if ( !task.isMandatoryTask() )
{
result = AuditBO.PARTIAL;
}
else
{
result = AuditBO.FAILED;
}
}
}
return result;
}
/**
* Access method for the mAudit property.
*
* @return the current value of the mAudit property
* @roseuid 42C2A3B000B6
*/
public AuditBO getAudit()
{
return mAudit;
}
/**
* Getter method for the mTerminationTasks property.
*
* @return the current value of the mTerminationTasks property
*/
public List getTerminationTasks()
{
return mTerminationTasks;
}
/**
* Termine l'audit en effectuant les op�rations n�cessaires � sa cl�ture
*
* @roseuid 42CBC4C001F3
*/
private void terminateAudit()
{
try
{
LOGGER.info( Messages.getString( "log.audit_executor.terminated" ) + mProject.getParent().getName()
+ Messages.getString( "separator.project" ) + mProject.getName() );
// Execution des t�ches de compl�tude
LOGGER.info( "**** Execution des taches terminales ****" );
for ( int i = 0; i < mTerminationTasks.size(); i++ )
{
AbstractTask task = (AbstractTask) mTerminationTasks.get( i );
task.run();
// Attention: bien mettre les taches de terminaison
// qui ne sont pas critiques comme �tant facultatives pour ne pas avoir
// un audit en �chec si ces taches l� �chouent
update( task );
}
// Les status termin�s ,partiels ou en �chec ne peuvent etre affect�s qu'ici
// une fois que toutes les taches ont �t� r�alis�es
mFinalStatus = getStatus();
}
catch ( Exception e )
{
LOGGER.error( e, e );
}
}
/**
* Execute l'ensemble des taches de l'audit
*
* @roseuid 42CCD3550279
*/
public void run()
{
boolean stop = false;
// On lance les taches syst�mes pr�alables
AbstractTask task = null;
if ( mFinalStatus != AuditBO.FAILED )
{
// Execution des t�ches d'analyse
for ( int i = 0; i < mTasks.size() && !stop; i++ )
{
task = (AbstractTask) mTasks.get( i );
task.run();
// On signale que la tache a �t� faite
// et on met � jour son status
stop = update( task );
}
}
// met � jour la taille du file system
mAudit.setMaxFileSystemSize( getMax( mTasks ) );
// Puis on lance les t�ches qui cloturent l'analyse du projet
terminateAudit();
}
/**
* @param pTasks la liste des taches de l'audit
* @return la taille max du file system durant l'audit
*/
private Long getMax( List pTasks )
{
long finalMax = 0;
for ( int i = 0; i < mTasks.size(); i++ )
{
long max = ( (AbstractTask) mTasks.get( i ) ).getMaxFileSystemSize();
for ( int j = 0; j < mTasks.size(); j++ )
{
max += ( (AbstractTask) mTasks.get( i ) ).getPersistentFileSystemSize();
}
if ( max > finalMax )
{
finalMax = max;
}
}
// Pour un affichage en m�gaOctet
final int Mega = 1000000;
return new Long( finalMax / Mega );
}
/**
* Sets the value of the mScheduler property.
*
* @param pScheduler the new value of the mScheduler property
* @roseuid 42CE36C70276
*/
public void setScheduler( Scheduler pScheduler )
{
mScheduler = pScheduler;
}
/**
* Projet sur lequel est ex�cut� l'analyse.
*
* @return le projet.
* @roseuid 42DFC07A01C5
*/
public ProjectBO getProject()
{
return mProject;
}
/**
* @return le status � la fin de l'ex�cution
*/
public int getFinalStatus()
{
return mFinalStatus;
}
/**
* @param pFinalStatus la nouvelle valeur du status � la fin de l'ex�cution
*/
public void setFinalStatus( int pFinalStatus )
{
mFinalStatus = pFinalStatus;
}
}