Package ch.hortis.sonar.core.batch

Source Code of ch.hortis.sonar.core.batch.ProjectAnalyserTask

/*
* This program is copyright (c) 2007 Hortis-GRC SA.
*
* This file is part of Sonar.
* Sonar is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Sonar 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 General Public License
* along with Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
package ch.hortis.sonar.core.batch;

import ch.hortis.sonar.core.service.AbstractService;
import ch.hortis.sonar.core.service.AvgCalculator;
import ch.hortis.sonar.core.service.CodeCoverageCalculator;
import ch.hortis.sonar.core.service.ErrorRciCalculator;
import ch.hortis.sonar.core.service.MissingUnitTestsService;
import ch.hortis.sonar.core.service.RuleErrorsCountCalculator;
import ch.hortis.sonar.core.service.RuleWarningsCountCalculator;
import ch.hortis.sonar.core.service.Service;
import ch.hortis.sonar.core.service.SnapshotProcessor;
import ch.hortis.sonar.core.service.SourcesHighlighterService;
import ch.hortis.sonar.core.service.SumCalculator;
import ch.hortis.sonar.core.service.TendencyCalculator;
import ch.hortis.sonar.core.service.TransactionalSnapshotProcessor;
import ch.hortis.sonar.core.service.WarningRciCalculator;
import ch.hortis.sonar.model.JdbcData;
import ch.hortis.sonar.model.Metrics;
import ch.hortis.sonar.model.SnapshotGroup;
import ch.hortis.sonar.service.MavenProjectService;
import ch.hortis.sonar.service.SnapshotGroupService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;

import javax.persistence.FlushModeType;
import javax.persistence.Query;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

public class ProjectAnalyserTask extends DatabaseTask {
  private static final Logger LOG = LoggerFactory.getLogger(ProjectAnalyserTask.class);

  public ProjectAnalyserTask(JdbcData jdbcData) {
    super(jdbcData);
  }
 
  protected List<Service> getTaskServices() {
    List<ch.hortis.sonar.service.Service> dbServices =
      Collections.unmodifiableList(ch.hortis.sonar.service.Service.getAllServices(getEntityManager()));
   
    List<Service> services = new ArrayList<Service>();
    services.add(new MissingUnitTestsService());
    services.add(new SumCalculator(Metrics.CHANGELOG_COMMITS));
    services.add(new SumCalculator(Metrics.CHANGELOG_FILE_COMMITS));
    services.add(new SumCalculator(Metrics.NCSS_CLASSES));
    services.add(new SumCalculator(Metrics.CYCLOMATIC_COMPLEXITY));
    services.add(new SumCalculator(Metrics.NCSS_FUNCTIONS));
    services.add(new SumCalculator(Metrics.NCSS_NCSS));
    services.add(new SumCalculator(Metrics.NCSS_PACKAGES));
    services.add(new SumCalculator(Metrics.PMD_DUPLICATED_LINES));
    services.add(new SumCalculator(Metrics.PMD_DUPLICATED_TOKENS));
    services.add(new SumCalculator(Metrics.PMD_DUPLICATION));
    services.add(new SumCalculator(Metrics.SUREFIRE_TESTS));
    services.add(new SumCalculator(Metrics.SUREFIRE_TIME));
    services.add(new AvgCalculator(Metrics.CYCLOMATIC_COMPLEXITY_AVG_CLASS, Metrics.CYCLOMATIC_COMPLEXITY, Metrics.NCSS_CLASSES));
    services.add(new AvgCalculator(Metrics.CYCLOMATIC_COMPLEXITY_AVG_FUNCTION, Metrics.CYCLOMATIC_COMPLEXITY, Metrics.NCSS_FUNCTIONS));
    services.add(new CodeCoverageCalculator());
    services.add(new RuleErrorsCountCalculator());
    services.add(new RuleWarningsCountCalculator());
    services.add(new ErrorRciCalculator());
    services.add(new WarningRciCalculator());
    services.add(new SourcesHighlighterService());
    services.add(new TendencyCalculator(Metrics.tendencyableMetrics()));

    for (Service service : services) {
      if (service instanceof AbstractService) {
        ((AbstractService) service).setDatabaseServices(dbServices);
      }
    }
    return services;
  }

  public void execute() {
    long startTime = System.currentTimeMillis();
    Collection<SnapshotGroup> groups = getGroupsToProcess();
    int processed = 0;
    MavenProjectService projectService = new MavenProjectService(getEntityManager());
    SnapshotGroupService snapshotGroupService = new SnapshotGroupService(getEntityManager());
    for (Iterator<SnapshotGroup> i = groups.iterator(); i.hasNext();) {
      SnapshotGroup group = i.next();
      if (!snapshotGroupService.isReadyToCalculateMeasures(group, projectService)) {
        i.remove();
      }
    }
    // removing all references to snaphsots from the entitymanager VERY important to clean memory
    createNewEntityManager();
    LOG.info(groups.size() + " snapshots to process");
    for (Iterator<SnapshotGroup> i = groups.iterator(); i.hasNext(); ) {
      SnapshotGroup group = i.next();
      // since SnapshotGroup are now detached must reload them to put them under the entitymanager control
      LOG.info("Reloading snapshot group " + group.getId());
      group = getEntityManager().find(SnapshotGroup.class, group.getId());
      try {
        long snapshotGroupStartTime = System.currentTimeMillis();
        MDC.put("group", group.getId().toString());
        LOG.info("Process snapshot group");
        processGroup(group);
        long timeTaken = System.currentTimeMillis() - snapshotGroupStartTime;
        LOG.info("Processed snapshot group in " + (timeTaken) + " ms");
        processed++;
      } catch (Throwable e) {
        LOG.error("Cannot process the snapshot group", e);
        removeInvalidGroup(group);
      } finally {
        MDC.clear();
      }
      // cleaning memory
      i.remove();
      createNewEntityManager();
    }
    if (processed > 0) {
      long timeTaken = System.currentTimeMillis() - startTime;
      LOG.info(processed + " snapshots processed in " + (timeTaken) + " ms");
    }
  }

  protected Collection<SnapshotGroup> getGroupsToProcess() {
    Query query = getEntityManager().createQuery("SELECT g FROM SnapshotGroup g WHERE g.processed=false ORDER BY g.createdAt asc");
    query.setFlushMode( FlushModeType.COMMIT );
    return query.getResultList();
  }

  protected void processGroup(SnapshotGroup group) throws Throwable {
    // each snapshots of the group will be processed within their own transaction
    SnapshotProcessor snapshotProcessor = new TransactionalSnapshotProcessor(getEntityManager(), getTaskServices());
    snapshotProcessor.process(group.getRootSnapshot());
    getEntityManager().getTransaction().begin();
    try {
      group.setProcessed(true);
      Query query = getEntityManager().createQuery("SELECT g FROM SnapshotGroup g WHERE g.mavenProject = :project AND g.last=true AND g.processed=true");
      query.setParameter("project", group.getMavenProject());
      Collection<SnapshotGroup> lastGroups = query.getResultList();
      for (SnapshotGroup lastGroup : lastGroups) {
        lastGroup.setLast(Boolean.FALSE);
        getEntityManager().merge(lastGroup);
      }
      group.setLast(true);
      getEntityManager().merge(group);
      getEntityManager().getTransaction().commit();
    } catch ( Throwable t ) {
      getEntityManager().getTransaction().rollback();
      throw t;
    }
  }

  private void removeInvalidGroup(SnapshotGroup group) {
    //Remove invalid groups
    getEntityManager().clear();
    getEntityManager().getTransaction().begin();
    Query query = getEntityManager().createQuery("DELETE FROM Snapshot WHERE snapshotGroup.id=:groupId");
    query.setParameter("groupId", group.getId());
    query.executeUpdate();
    query = getEntityManager().createQuery("DELETE FROM SnapshotGroup WHERE id=:groupId");
    query.setParameter("groupId", group.getId());
    query.executeUpdate();
    LOG.info("Remove SnapshotGroup with id=" + group.getId());
    getEntityManager().getTransaction().commit();
  }
}
TOP

Related Classes of ch.hortis.sonar.core.batch.ProjectAnalyserTask

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.