/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package br.uff.ic.oceano.polvo.service; import br.uff.ic.oceano.core.factory.ObjectFactory; import br.uff.ic.oceano.core.model.Branch; import br.uff.ic.oceano.core.model.BranchingMetric; import br.uff.ic.oceano.core.model.BranchingModel; import br.uff.ic.oceano.core.model.SoftwareProject; import br.uff.ic.oceano.core.model.ProjectUser; import br.uff.ic.oceano.core.tools.vcs.SVN_By_CommandLineInterface; import br.uff.ic.oceano.core.tools.vcs.SVN_By_SVNKit; import br.uff.ic.oceano.util.file.FileUtils; import br.uff.ic.oceano.ourico.rcs.Subversion; import br.uff.ic.oceano.ourico.util.Casting; import br.uff.ic.oceano.ourico.verificacao.build.Maven; import br.uff.ic.oceano.polvo.controle.Constantes; import br.uff.ic.oceano.polvo.util.MetricBranch; import br.uff.ic.oceano.polvo.util.BranchUtil; import java.io.File; import java.util.List; import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.wc.SVNRevision; /** * * @author Rafael */ public class PolvoBranchService { private SVN_By_SVNKit svnBySVNKit = ObjectFactory.getObjectWithDataBaseDependencies(SVN_By_SVNKit.class); private SVN_By_CommandLineInterface svnByCLI = ObjectFactory.getObjectWithDataBaseDependencies(SVN_By_CommandLineInterface.class); public String compareBranchTime(SoftwareProject project, Branch mainBranch, Branch secondaryBranch, BranchingModel branchingModel, BranchingMetric branchingMetric, long beginRevision) throws Exception { ProjectUser projectUser = BranchUtil.getProjectUser(project); projectUser.setProject(project); String nodesGraph = ""; MetricBranch metricBranch; Long numberOfHEADRevision = svnByCLI.getNumberOfHEADRevision(projectUser); System.out.println("numberOfHEADRevision="+numberOfHEADRevision); int numberOfInterval = 10; long interval = (numberOfHEADRevision - beginRevision)/numberOfInterval; long numberRevision; metricBranch = compareBranch(project, mainBranch, secondaryBranch, branchingModel, branchingMetric, numberOfHEADRevision); nodesGraph = addNodesGraph(nodesGraph, numberOfHEADRevision, metricBranch.getQtdMetrica()); for (int i = 1; i < numberOfInterval; i++){ numberRevision = numberOfHEADRevision - (interval * i); metricBranch = compareBranch(project, mainBranch, secondaryBranch, branchingModel, branchingMetric, numberRevision); nodesGraph = addNodesGraph(nodesGraph, numberRevision, metricBranch.getQtdMetrica()); } int iniGrafico = 0; long idBranchingMetric = branchingMetric.getId().longValue(); if (idBranchingMetric == Constantes.METR_RAMIF_ARQ_COBERTURA || idBranchingMetric == Constantes.METR_RAMIF_ARQ_PRECISAO) { iniGrafico = 100; } nodesGraph = addNodesGraph(nodesGraph, beginRevision, iniGrafico); /* metricBranch = compareBranch(project, mainBranch, secondaryBranch, branchingModel, branchingMetric, numberOfHEADRevision); nodesGraph = addNodesGraph(nodesGraph, numberOfHEADRevision, metricBranch.getQtdMetrica()); metricBranch = compareBranch(project, mainBranch, secondaryBranch, branchingModel, branchingMetric, ((beginRevision + numberOfHEADRevision)/2)); nodesGraph = addNodesGraph(nodesGraph, (beginRevision + numberOfHEADRevision)/2, metricBranch.getQtdMetrica()); nodesGraph = addNodesGraph(nodesGraph, beginRevision, 0); */ return nodesGraph; } private String addNodesGraph(String nodesGraph, long revision, int metrica) { //Calendar calendar = Calendar.getInstance(); //calendar.setTime(dateRevision); if (!nodesGraph.equals("")) { nodesGraph += ":"; } //nodesGraph += (calendar.get(calendar.MONTH) + 1) + "," + calendar.get(calendar.YEAR) + "," + metrica; nodesGraph += revision + "," + metrica; System.out.println("nodesGraph="+nodesGraph); return nodesGraph; } public MetricBranch compareBranch(SoftwareProject project, Branch mainBranch, Branch secondaryBranch, BranchingModel branchingModel, BranchingMetric branchingMetric) throws Exception { ProjectUser projectUser = BranchUtil.getProjectUser(project); projectUser.setProject(project); Long numberOfHEADRevision = svnByCLI.getNumberOfHEADRevision(projectUser); System.out.println("numberOfHEADRevision="+numberOfHEADRevision); MetricBranch metricBranch = compareBranch(project, mainBranch, secondaryBranch, branchingModel, branchingMetric, numberOfHEADRevision); metricBranch.setRevision(numberOfHEADRevision); return metricBranch; } public MetricBranch compareBranch(SoftwareProject project, Branch mainBranch, Branch secondaryBranch, BranchingModel branchingModel, BranchingMetric branchingMetric, Long numberRevision) throws Exception { MetricBranch metricBranch = new MetricBranch(); String urlMainBranch = BranchUtil.getUrl(project, mainBranch); String urlSecondaryBranch = BranchUtil.getUrl(project, secondaryBranch); System.out.println("urlMainBranch="+urlMainBranch); System.out.println("urlSecondaryBranch="+urlSecondaryBranch); //OceanoUserDao oceanoUserDao = ObjectFactory.getObj(OceanoUserDaoImpl.class); // TODO pegar do usuario logado //OceanoUser userRafaelOceano = oceanoUserDao.getByLogin("rafaelss"); //PolvoMetricService polvoMetricService = ObjectFactory.getObj(PolvoMetricService.class); //MetricValue metricValue = polvoMetricService.extractMetricFromRevision(project, userRafaelOceano); // total de arquivos do ramo principal //int qtdArqRamoPrincipal; // total de arquivos do ramo secundario //int qtdArqRamoSecundario; // getAllFiles nao esta funcionando para o repositorio de teste //qtdArqRamoPrincipal = getAllFiles(urlMainBranch, project).size(); //qtdArqRamoSecundario = getAllFiles(urlSecondaryBranch, project).size(); String ws = "c:\\checkout\\" + project.getConfigurationItem().getName() + "\\" + BranchUtil.getLastValuePath(urlMainBranch); String ws2 = ""; // work around para o oceano-core if (urlSecondaryBranch.contains("Oceano-Core-Peixe-Espada")){ ws2 = "c:\\checkout\\" + project.getConfigurationItem().getName() + "\\Oceano-Core-Peixe-Espada"; } else { ws2 = "c:\\checkout\\" + project.getConfigurationItem().getName() + "\\" + BranchUtil.getLastValuePath(urlSecondaryBranch); } // metricas com o calculo feito no servidor (nao necessitam de checkout) long idBranchingMetric = branchingMetric.getId().longValue(); System.out.println("idBranchingMetric=" + idBranchingMetric); if (idBranchingMetric == Constantes.METR_RAMIF_ARQ_COBERTURA || idBranchingMetric == Constantes.METR_RAMIF_ARQ_PRECISAO || idBranchingMetric >= Constantes.METR_RAMIF_CONFL_FISICOS) { checkout_update(ws, urlMainBranch, numberRevision); checkout_update(ws2, urlSecondaryBranch, numberRevision); } // total de arquivos do ramo principal int qtdArqRamoPrincipal = contarArquivos(ws); //int qtdArqRamoPrincipal = 1; // total de arquivos do ramo secundario int qtdArqRamoSecundario = contarArquivos(ws2); //int qtdArqRamoSecundario = 1; System.out.println("qtdArqRamoPrincipal=" + qtdArqRamoPrincipal); System.out.println("qtdArqRamoSecundario=" + qtdArqRamoSecundario); metricBranch.setQtdArqRamoPrincipal(qtdArqRamoPrincipal); metricBranch.setQtdArqRamoSecundario(qtdArqRamoSecundario); //String diffString = diffBranch(project, urlMainBranch, urlSecondaryBranch, numberRevision); //metricBranch = metricDiverg(diffString, metricBranch); if (idBranchingMetric < Constantes.METR_RAMIF_CONFL_FISICOS) { String diffString = diffBranch(project, urlMainBranch, urlSecondaryBranch, numberRevision); metricBranch = metricDiff(diffString, metricBranch, branchingMetric); } else { //String ws = "c:\\checkout\\" + project.getConfigurationItem().getName() + "\\" + BranchUtil.getLastValuePath(urlMainBranch) + "\\"; String wsTmp = "c:\\checkout\\tmp\\"; //checkout_update(ws, urlMainBranch, numberRevision); try{ FileUtils.deleteDirectory(new File(wsTmp)); System.out.println("c:\\checkout\\tmp\\ deletado"); } catch (Exception ex) { System.out.println("c:\\checkout\\tmp\\ não encontrado!"); } FileUtils.copyDirectory(new File(ws), new File(wsTmp)); ProjectUser projectUser = BranchUtil.getProjectUser(project); int qtdConfFisico = svnByCLI.doMerge(projectUser, urlSecondaryBranch, wsTmp, numberRevision); System.out.println("qtdConfFisico=" + qtdConfFisico); if (idBranchingMetric == Constantes.METR_RAMIF_CONFL_FISICOS) { metricBranch.setQtdMetrica(qtdConfFisico); } else { if (qtdConfFisico > 0) { // Sera tratado para informar ao usuario que nao será possivel analisar o merge sintatico, pois há conflitos fisicos metricBranch.setQtdMetrica(-1); } else { String pathSettings = "c:\\Users\\Rafael\\.m2\\settings.xml"; String repositorioLocal = "c:\\Users\\Rafael\\.m2\\repository"; Maven mvn = new Maven(); mvn.setPathSettings(pathSettings); mvn.setRepositorioLocal(repositorioLocal); mvn.setUrlProjeto(wsTmp); String ret; int qtdConfSintatico = 0; try{ List<Throwable> listSintatico = mvn.compila(); System.out.println(listSintatico); ret = Casting.ListTrowableToString(listSintatico).toString(); System.out.println("retSintatico=" + ret); } catch(NullPointerException ne){ qtdConfSintatico = 0; } catch(Exception ex){ ex.printStackTrace(); } System.out.println("qtdSintatico=" + qtdConfSintatico); if (idBranchingMetric == Constantes.METR_RAMIF_CONFL_SINTATICOS) { metricBranch.setQtdMetrica(qtdConfSintatico); } else { if (qtdConfSintatico > 0) { // Sera tratado para informar ao usuario que nao será possivel analisar o merge semantico, pois há conflitos sintaticos metricBranch.setQtdMetrica(-2); } else { int qtdConfSemantico = 0; try{ List<Throwable> listSemantico = mvn.testa(); ret = Casting.ListTrowableToString(listSemantico).toString(); System.out.println("retSemantico=" + ret); }catch(NullPointerException ne){ qtdConfSemantico = 0; } catch(Exception ex){ ex.printStackTrace(); } System.out.println("qtdSemantico=" + qtdConfSemantico); } } } } } return metricBranch; } private static int contarArquivos(String path) throws Exception { //System.out.println(path); int contArq = 0; File file=new File(path); for(File arq:file.listFiles()){ //condição para pegar só os arquivos, e nao diretórios if(arq.isFile()){ contArq++; //System.out.println("Arquivo "+(contArq)+": "+arq.getName()); } else { contArq = contArq + contarArquivos(path + "\\" + arq.getName()); } } return contArq; } private MetricBranch metricDiverg(String diffString, MetricBranch metricBranch) { //System.out.println("diffString="+diffString); int qtd = 0; boolean newFile = false; String[] lines = diffString.split("\n"); for (String line : lines) { if (line.startsWith("+++")) { newFile = true; } if (newFile && line.startsWith("@@")) { if (!line.contains("-0,0")) { qtd++; } newFile = false; } } System.out.println("Qtd Diverg=" + qtd); if (metricBranch.getQtdDivergencia() == 0) { float calcDiverg = new Integer(metricBranch.getQtdArqRamoPrincipal() - qtd).floatValue() / new Integer(metricBranch.getQtdArqRamoPrincipal()).floatValue(); metricBranch.setQtdDivergencia(new Float(calcDiverg * 100).intValue()); System.out.println("Metrica Diverg=" + metricBranch.getQtdDivergencia()); } return metricBranch; } private void checkout_update(String ws, String urlMainBranch, Long numberRevision) throws SVNException { Subversion svn = new Subversion(); if (!(new File(ws)).exists()) { svn.iniciaRepositorio(urlMainBranch); long revCheckout = svn.checkout(urlMainBranch, ws); System.out.println("revCheckout=" + revCheckout); } else { svn.update(ws, SVNRevision.create(numberRevision.longValue())); System.out.println("revUpdate=" + numberRevision); } } private String diffBranch(SoftwareProject project, String urlMainBranch, String urlSecondaryBranch, Long numberRevision) throws Exception { String diffString = null; ProjectUser projectUser = BranchUtil.getProjectUser(project); projectUser.setProject(project); diffString = svnBySVNKit.doDiff(projectUser, urlMainBranch, urlSecondaryBranch, numberRevision).toString(); return diffString; } private MetricBranch metricDiff(String diffString, MetricBranch metricBranch, BranchingMetric branchingMetric) { //System.out.println("diffString="+diffString); int qtd = 0; int ret = 0; long idBranchingMetric = branchingMetric.getId().longValue(); String[] lines = diffString.split("\n"); //Metrica Qtd Arq Alterados LP qtd = metricQtdFileUpdateMB(lines); System.out.println("Quantidade de Artefatos Modificados na Linha Principal=" + qtd); if (idBranchingMetric == Constantes.METR_RAMIF_ARQ_ALTERADOS_RP) { ret = qtd; } //Metrica Qtd Arq Alterados Ramo int qtdFileUpdateSB = metricQtdFileUpdateSB(lines); System.out.println("Quantidade de Artefatos Modificados no Ramo=" + qtdFileUpdateSB); if (idBranchingMetric == Constantes.METR_RAMIF_ARQ_ALTERADOS_RS) { ret = qtdFileUpdateSB; } //Metrica Qtd Arq modificados em comum qtd = 0; boolean newFile = true; for (String line : lines) { if (line.startsWith("Index")) { newFile = true; } if (newFile && line.startsWith("@@")) { if (!line.contains("0,0")) { qtd++; } newFile = false; } } System.out.println("Quantidade de Artefatos Modificados em Comum=" + qtd); if (idBranchingMetric == Constantes.METR_RAMIF_ARQ_MODIF_EM_COMUM) { ret = qtd; } //Metrica Qtd Arq Conflito // qtd = 0; // if (flagAllMetric || idBranchingMetric == Constantes.METR_RAMIF_ARQ_CONFLITOS) { // boolean flag = false; // for (String line : lines) { // if (flag && line.startsWith("+") && !line.startsWith("+++")) { // qtd++; // } // flag = false; // // if (line.startsWith("-") && !line.startsWith("---")) { // flag = true; // } // } // System.out.println("Quantidade de Blocos de Linhas Alteradas em Comum=" + qtd); // } //Metrica Cobertura por Arq int qtdFileNewSB = metricQtdFileNewSB(lines); int qtdFileDeletedSB = metricQtdFileDeletedSB(lines); // qtd de arq antes da criação do ramo int qtdFileOrig = metricBranch.getQtdArqRamoSecundario() - qtdFileNewSB + qtdFileDeletedSB; System.out.println("Qtd Arq no inicio do ramo=" + qtdFileOrig); // qtd de arq alterados em ambos int qtdFileUpdBoth = metricQtdFileUpdateBoth(lines); // qtd arq na criacao do ramo que nao foram modificados int qtdInters = qtdFileOrig - qtdFileUpdBoth; System.out.println("Qtd INTERSECAO=" + qtdInters); qtd = (qtdInters) * 100 / metricBranch.getQtdArqRamoPrincipal(); System.out.println("Cobertura por Quantidade de Artefatos (%)=" + qtd); if (idBranchingMetric == Constantes.METR_RAMIF_ARQ_COBERTURA) { ret = qtd; } //Metrica Precisao por Arq qtd = (qtdInters) * 100 / metricBranch.getQtdArqRamoSecundario(); System.out.println("Precisão por Quantidade de Artefatos (%)=" + qtd); if (idBranchingMetric == Constantes.METR_RAMIF_ARQ_PRECISAO) { ret = qtd; } //Metrica Qtd Linhas Diferentes LP qtd = 0; for (String line : lines) { if (line.startsWith("-") && !line.startsWith("---")) { qtd++; } } System.out.println("Quantidade de Linhas Diferentes na Linha Principal=" + qtd); if (idBranchingMetric == Constantes.METR_RAMIF_LINHAS_ALTERADAS_RP) { ret = qtd; } //Metrica Qtd Linhas Diferentes no Ramo qtd = 0; for (String line : lines) { if (line.startsWith("+") && !line.startsWith("+++")) { qtd++; } } System.out.println("Quantidade de Linhas Diferentes no Ramo=" + qtd); if (idBranchingMetric == Constantes.METR_RAMIF_LINHAS_ALTERADAS_RS) { ret = qtd; } metricBranch.setQtdMetrica(ret); return metricBranch; } private int metricQtdFileUpdate(String[] lines) { int qtd = 0; for (String line : lines) { if (line.startsWith("Index")) { qtd++; } } System.out.println("Qtd Arq Alterados =" + qtd); return qtd; } private int metricQtdFileUpdateMB(String[] lines) { int qtd = 0; boolean newFile = true; for (String line : lines) { if (line.startsWith("Index")) { newFile = true; } if (newFile && line.startsWith("@@")) { if (!line.contains("-0,0")) { qtd++; } newFile = false; } } //System.out.println("Qtd Arq Alterados RP=" + qtd); return qtd; } private int metricQtdFileUpdateSB(String[] lines) { int qtd = 0; boolean newFile = true; for (String line : lines) { if (line.startsWith("Index")) { newFile = true; } if (newFile && line.startsWith("@@")) { if (!line.contains("+0,0")) { qtd++; } newFile = false; } } //System.out.println("Qtd Arq Alterados RS=" + qtd); return qtd; } private static int metricQtdFileNewSB(String[] lines) { int qtd = 0; boolean newFile = true; for (String line : lines) { if (line.startsWith("Index")) { newFile = true; } if (newFile && line.startsWith("---") && !line.contains("(revision 0)")){ newFile = false; } if (newFile && line.startsWith("@@")) { if (line.contains("-0,0")) { qtd++; } newFile = false; } } System.out.println("Qtd Arq Novos RS=" + qtd); return qtd; } private static int metricQtdFileDeletedSB(String[] lines) { int qtd = 0; boolean newFile = true; for (String line : lines) { if (line.startsWith("Index")) { newFile = true; } if (newFile && line.startsWith("+++") && line.contains("(revision 0)")){ newFile = false; } if (newFile && line.startsWith("@@")) { if (line.contains("+0,0")) { qtd++; } newFile = false; } } System.out.println("Qtd Arq Deletados RS=" + qtd); return qtd; } private int metricQtdFileUpdateBoth(String[] lines) { int qtd = 0; boolean newFile = true; for (String line : lines) { if (line.startsWith("Index")) { newFile = true; } if (newFile && line.startsWith("@@")) { if (!line.contains("-0,0") || !line.contains("+0,0")) { qtd++; } newFile = false; } } System.out.println("Qtd Arq Alterados Ambos=" + qtd); return qtd; } public List<String> getBranches(SoftwareProject project) throws Exception { ProjectUser projectUser = BranchUtil.getProjectUser(project); return svnBySVNKit.getBranches(project, projectUser); } public List<String> getAllFiles(String url, SoftwareProject project) throws Exception { ProjectUser projectUser = BranchUtil.getProjectUser(project); return svnByCLI.getAllFiles(url, projectUser); } }