package jmav.component;
import java.io.File;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import jmav.exception.AnalysisAlreadyStartedException;
import jmav.exception.ParameterNotNullException;
import jmav.exception.ValueNotFoundException;
import jmav.object.Granularita;
import jmav.object.JavaProject;
import jmav.object.OccorrenzaSmell;
import jmav.object.Posizione;
import jmav.object.Smell;
import jmav.smellFinder.LargeClassAgent;
import jmav.smellFinder.LongMethodAgent;
import jmav.smellFinder.LongParameterListAgent;
import jmav.visitor.ClassVisitor;
import jmav.visitor.MethodVisitor;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.TypeDeclaration;
public class GestoreAnalisi {
private int numSmells;
private GestoreImpostazioni gestoreImpostazioni;
private CalcolatoreMetriche calcolatoreMetriche;
private List<Posizione> posizioni;
private JavaProject project;
private List<OccorrenzaSmell> occorrenzaSmells;
private boolean avviata;
public GestoreAnalisi(GestoreImpostazioni gestoreImpostazioni, CalcolatoreMetriche calcolatoreMetriche) {
this.gestoreImpostazioni = gestoreImpostazioni;
this.calcolatoreMetriche = calcolatoreMetriche;
resetPosizioni();
resetOccorrenzeSmell();
avviata = false;
}
public synchronized void avviaAnalisi(JavaProject project) throws AnalysisAlreadyStartedException, ParameterNotNullException, ValueNotFoundException, InterruptedException, ExecutionException {
if(avviata) {
throw new AnalysisAlreadyStartedException("Analisi gi� avviata");
}
avviata = true;
this.project = project;
resetPosizioni();
calcolatoreMetriche.resetValoriMetriche();
resetOccorrenzeSmell();
numSmells = 0;
LargeClassAgent largeClassAgent = null;
LongParameterListAgent longParameterListAgent = null;
LongMethodAgent longMethodAgent = null;
/* Prendi smell selezionati */
boolean largeClassBV = false;
Integer largeClassSG = Integer.MAX_VALUE;
boolean longParListBV = false;
Integer longParListSG = Integer.MAX_VALUE;
boolean longMethodBV = false;
Integer longMethodSG = Integer.MAX_VALUE;
for(Smell smell : gestoreImpostazioni.listaSmell()) {
if(smell.getName().equals("LargeClass")) {
largeClassBV = true;
largeClassSG = gestoreImpostazioni.getSoglia(GestoreImpostazioni.LargeClass, 1);
}
if(smell.getName().equals("LongParameterList")) {
longParListBV = true;
longParListSG = gestoreImpostazioni.getSoglia(GestoreImpostazioni.LongParameterList, 1);
}
if(smell.getName().equals("LongMethod")) {
longMethodBV = true;
longMethodSG = gestoreImpostazioni.getSoglia(GestoreImpostazioni.LongMethod, 1);
}
}
Set<Granularita> granularitaSet = new HashSet<Granularita>();
if (largeClassBV) {
System.out.println("Prepare Large Class Agent");
numSmells++;
granularitaSet.add(LargeClassAgent.getGranularita());
}
if (longParListBV) {
System.out.println("Prepare Long Parameter List Agent");
numSmells++;
granularitaSet.add(LongParameterListAgent.getGranularita());
}
if (longMethodBV) {
System.out.println("Prepare Long Method Agent");
numSmells++;
granularitaSet.add(LongMethodAgent.getGranularita());
}
if(numSmells == 0)
return;
/* Calcolo le posizioni coerenti in base ai livelli di granularità */
calcolaPosizioni(granularitaSet);
ExecutorService pool = Executors.newFixedThreadPool(numSmells);
if(posizioni != null) {
for(Posizione posizione : posizioni) {
if (largeClassBV) {
if(posizione.getGranularita() == LargeClassAgent.getGranularita()) {
System.out.println("run Large Class Agent with "+ largeClassSG);
largeClassAgent = new LargeClassAgent(calcolatoreMetriche);
largeClassAgent.setSoglia(largeClassSG);
largeClassAgent.setPosizione(posizione);
pool.execute(largeClassAgent.getJob());
}
}
if (longParListBV) {
if(posizione.getGranularita() == LongParameterListAgent.getGranularita()) {
System.out.println("run Long Parameter List with "+ longParListSG);
longParameterListAgent = new LongParameterListAgent(calcolatoreMetriche);
longParameterListAgent.setSoglia(longParListSG);
longParameterListAgent.setPosizione(posizione);
pool.execute(longParameterListAgent.getJob());
}
}
if (longMethodBV) {
if(posizione.getGranularita() == LongParameterListAgent.getGranularita()) {
System.out.println("run Long Method with "+ longMethodSG);
longMethodAgent = new LongMethodAgent(calcolatoreMetriche);
longMethodAgent.setSoglia(longMethodSG);
longMethodAgent.setPosizione(posizione);
pool.execute(longMethodAgent.getJob());
}
}
if (largeClassBV) {
if(posizione.getGranularita() == LargeClassAgent.getGranularita()) {
OccorrenzaSmell occorrenzaSmell = largeClassAgent.getJob().get();
if(occorrenzaSmell.getName() != null) {
occorrenzaSmells.add(occorrenzaSmell);
System.out.println("LargeClassAgent aggiunge "+occorrenzaSmell);
}
}
}
if (longParListBV) {
if(posizione.getGranularita() == LongParameterListAgent.getGranularita()) {
OccorrenzaSmell occorrenzaSmell = longParameterListAgent.getJob().get();
if(occorrenzaSmell.getName() != null) {
occorrenzaSmells.add(occorrenzaSmell);
System.out.println("LongParameterListAgent aggiunge "+occorrenzaSmell);
}
}
}
if (longMethodBV) {
if(posizione.getGranularita() == LongMethodAgent.getGranularita()) {
OccorrenzaSmell occorrenzaSmell = longMethodAgent.getJob().get();
if(occorrenzaSmell.getName() != null) {
occorrenzaSmells.add(occorrenzaSmell);
System.out.println("LongMethodAgent aggiunge "+occorrenzaSmell);
}
}
}
}
}
pool.shutdown(); // Disable new tasks from being submitted
try {
// Wait a while for existing tasks to terminate
if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
pool.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
if (!pool.awaitTermination(60, TimeUnit.SECONDS))
System.err.println("Pool did not terminate");
avviata = false;
}
} catch (InterruptedException ie) {
// (Re-)Cancel if current thread also interrupted
pool.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
}
calcolatoreMetriche.shutdown();
}
private void resetPosizioni() {
posizioni = new ArrayList<Posizione>();
}
private void resetOccorrenzeSmell() {
occorrenzaSmells = new ArrayList<OccorrenzaSmell>();
}
private void calcolaPosizioni(Set<Granularita> granularitaSet) {
for (Entry<File, CompilationUnit> unit : project.getCompilationUnits().entrySet()) {
Iterator<Granularita> granIterator = granularitaSet.iterator();
while(granIterator.hasNext()) {
Granularita gran = granIterator.next();
if(gran == Granularita.CLASS) {
ClassVisitor visitor = new ClassVisitor();
unit.getValue().accept(visitor);
for (TypeDeclaration node : visitor.getClasses()) {
Posizione posizione = new Posizione(node, Granularita.CLASS);
posizioni.add(posizione);
}
}
if(gran == Granularita.METHOD) {
MethodVisitor visitor = new MethodVisitor();
unit.getValue().accept(visitor);
for (MethodDeclaration node : visitor.getMethods()) {
Posizione posizione = new Posizione(node, Granularita.METHOD);
posizioni.add(posizione);
}
}
}
}
}
public List<OccorrenzaSmell> listaRisultati() {
return occorrenzaSmells;
}
public List<Posizione> listaPosizioni() {
return posizioni;
}
public synchronized void interrompiAnalisi() {
//TODO
}
public synchronized boolean controllaAnalisiCorrente() {
return avviata;
}
public static void main(String args[]) throws Exception {
String projectpath = "../test-artefatto";
JavaProject project = new JavaProject(projectpath);
GestoreImpostazioni gestoreImpostazioni = new GestoreImpostazioni();
gestoreImpostazioni.aggiungiSmell(GestoreImpostazioni.LargeClass);
gestoreImpostazioni.modificaSoglia(GestoreImpostazioni.LargeClass, 1, 50);
gestoreImpostazioni.aggiungiSmell(GestoreImpostazioni.LongParameterList);
gestoreImpostazioni.modificaSoglia(GestoreImpostazioni.LongParameterList, 1, 3);
gestoreImpostazioni.aggiungiSmell(GestoreImpostazioni.LongMethod);
gestoreImpostazioni.modificaSoglia(GestoreImpostazioni.LongMethod, 1, 10);
CalcolatoreMetriche calcolatoreMetriche = new CalcolatoreMetriche();
GestoreAnalisi GestoreAnalisi = new GestoreAnalisi(gestoreImpostazioni, calcolatoreMetriche);
GestoreAnalisi.avviaAnalisi(project);
GestoreRisultati gestoreRisultati = new GestoreRisultati();
for(OccorrenzaSmell occorrenzaSmell : GestoreAnalisi.listaRisultati()) {
gestoreRisultati.restituisciRisultato(occorrenzaSmell);
}
System.out.println("gestoreRisultati.restituisciRisultati: "+gestoreRisultati.restituisciRisultati(true));
}
}