All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.puresoltechnologies.purifinity.server.metrics.maintainability.MaintainabilityIndexEvaluator Maven / Gradle / Ivy

package com.puresoltechnologies.purifinity.server.metrics.maintainability;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.inject.Inject;

import org.slf4j.Logger;

import com.puresoltechnologies.commons.domain.ConfigurationParameter;
import com.puresoltechnologies.commons.misc.hash.HashId;
import com.puresoltechnologies.parsers.source.SourceCodeLocation;
import com.puresoltechnologies.purifinity.analysis.api.AnalysisRun;
import com.puresoltechnologies.purifinity.analysis.domain.AnalysisFileTree;
import com.puresoltechnologies.purifinity.analysis.domain.AnalysisInformation;
import com.puresoltechnologies.purifinity.analysis.domain.CodeAnalysis;
import com.puresoltechnologies.purifinity.analysis.domain.CodeRange;
import com.puresoltechnologies.purifinity.evaluation.api.EvaluationStoreException;
import com.puresoltechnologies.purifinity.evaluation.api.Evaluator;
import com.puresoltechnologies.purifinity.evaluation.api.iso9126.QualityCharacteristic;
import com.puresoltechnologies.purifinity.evaluation.domain.metrics.DirectoryMetrics;
import com.puresoltechnologies.purifinity.evaluation.domain.metrics.FileMetrics;
import com.puresoltechnologies.purifinity.evaluation.domain.metrics.MetricParameter;
import com.puresoltechnologies.purifinity.server.metrics.AbstractMetricEvaluator;
import com.puresoltechnologies.purifinity.server.metrics.halstead.HalsteadMetric;
import com.puresoltechnologies.purifinity.server.metrics.halstead.HalsteadMetricResult;
import com.puresoltechnologies.purifinity.server.metrics.halstead.HalsteadResult;
import com.puresoltechnologies.purifinity.server.metrics.halstead.db.HalsteadMetricsEvaluatorDAO;
import com.puresoltechnologies.purifinity.server.metrics.maintainability.db.MaintainabilityIndexEvaluatorDAO;
import com.puresoltechnologies.purifinity.server.metrics.mccabe.McCabeMetric;
import com.puresoltechnologies.purifinity.server.metrics.mccabe.McCabeMetricResult;
import com.puresoltechnologies.purifinity.server.metrics.mccabe.db.McCabeMetricEvaluatorDAO;
import com.puresoltechnologies.purifinity.server.metrics.sloc.SLOCMetric;
import com.puresoltechnologies.purifinity.server.metrics.sloc.SLOCMetricCalculator;
import com.puresoltechnologies.purifinity.server.metrics.sloc.SLOCResult;
import com.puresoltechnologies.purifinity.server.metrics.sloc.db.SLOCMetricEvaluatorDAO;
import com.puresoltechnologies.versioning.Version;

@Stateless
@Remote(Evaluator.class)
public class MaintainabilityIndexEvaluator extends AbstractMetricEvaluator {

	public static final String ID = MaintainabilityIndexEvaluator.class
			.getName();
	public static final String NAME = "Maintainability Index";
	public static final Version PLUGIN_VERSION = new Version(1, 0, 0);
	public static final String DESCRIPTION = "Maintainability Index calculation.";
	public static final List> PARAMETERS = new ArrayList<>();
	public static final Set EVALUATED_QUALITY_CHARACTERISTICS = new HashSet();
	static {
		EVALUATED_QUALITY_CHARACTERISTICS
				.add(QualityCharacteristic.ANALYSABILITY);
		EVALUATED_QUALITY_CHARACTERISTICS
				.add(QualityCharacteristic.CHANGEABILITY);
		EVALUATED_QUALITY_CHARACTERISTICS
				.add(QualityCharacteristic.TESTABILITY);
	}
	public static final Set DEPENDENCIES = new HashSet<>();
	static {
		DEPENDENCIES.add(SLOCMetricCalculator.ID);
		DEPENDENCIES.add(McCabeMetric.ID);
		DEPENDENCIES.add(HalsteadMetric.ID);
	}

	@Inject
	private Logger logger;

	@Inject
	private SLOCMetricEvaluatorDAO slocMetricEvaluatorDAO;

	@Inject
	private McCabeMetricEvaluatorDAO mcCabeMetricEvaluatorDAO;

	@Inject
	private HalsteadMetricsEvaluatorDAO halsteadMetricsEvaluatorDAO;

	@Inject
	private MaintainabilityIndexEvaluatorDAO maintainabilityIndexEvaluatorDAO;

	public MaintainabilityIndexEvaluator() {
		super(ID, NAME, PLUGIN_VERSION, DESCRIPTION);
	}

	@Override
	public List> getConfigurationParameters() {
		return PARAMETERS;
	}

	@Override
	public Set> getParameters() {
		return MaintainabilityIndexEvaluatorParameter.ALL;
	}

	@Override
	protected FileMetrics processFile(AnalysisRun analysisRun,
			CodeAnalysis analysis) throws InterruptedException,
			EvaluationStoreException {
		AnalysisInformation analysisInformation = analysis
				.getAnalysisInformation();
		AnalysisInformation analyzedFile = analysisInformation;
		HashId hashId = analyzedFile.getHashId();
		SourceCodeLocation sourceCodeLocation = analysisRun
				.findTreeNode(hashId).getSourceCodeLocation();

		MaintainabilityIndexFileResults results = new MaintainabilityIndexFileResults(
				MaintainabilityIndexEvaluator.ID,
				MaintainabilityIndexEvaluator.PLUGIN_VERSION, hashId,
				sourceCodeLocation, new Date());

		List slocFileResults = slocMetricEvaluatorDAO
				.readFileResults(hashId);
		List mcCabeFileResults = mcCabeMetricEvaluatorDAO
				.readFileResults(hashId);
		List halsteadFileResults = halsteadMetricsEvaluatorDAO
				.readFileResults(hashId);

		for (CodeRange codeRange : analysis.getAnalyzableCodeRanges()) {
			SLOCResult slocCodeRangeResult = findSLOCMetricResult(
					slocFileResults, codeRange);
			if (slocCodeRangeResult == null) {
				logger.warn("No SLOC result available for '" + hashId
						+ "', yet.");
				continue;
			}
			McCabeMetricResult mcCabeCodeRangeResult = findMcCabeMetricResult(
					mcCabeFileResults, codeRange);
			if (mcCabeCodeRangeResult == null) {
				logger.warn("No McCabe Metric result available for '" + hashId
						+ "', yet.");
				continue;
			}
			HalsteadMetricResult halsteadCodeRangeResult = findHalsteadMetricResult(
					halsteadFileResults, codeRange);
			if (halsteadCodeRangeResult == null) {
				logger.warn("No Halstead Metric result available for '"
						+ hashId + "', yet.");
				continue;
			}

			SLOCMetric slocMetric = slocCodeRangeResult.getSLOCMetric();
			int phyLOC = slocMetric.getPhyLOC();
			int comLOC = slocMetric.getComLOC();
			int vG = mcCabeCodeRangeResult.getCyclomaticComplexity();
			HalsteadResult halsteadResult = halsteadCodeRangeResult
					.getHalsteadResult();
			double hv = halsteadResult.getHalsteadVolume();
			double MIwoc = 171.0 - 5.2 * Math.log(hv) - 0.23 * vG - 16.2
					* Math.log(phyLOC * 100.0 / 171.0);
			double MIcw = 50 * Math.sin(Math.sqrt(2.4 * comLOC / phyLOC));
			MaintainabilityIndexResult result = new MaintainabilityIndexResult(
					MIwoc, MIcw);
			MaintainabilityIndexFileResult fileResult = new MaintainabilityIndexFileResult(
					sourceCodeLocation, codeRange.getType(),
					codeRange.getCanonicalName(), result);
			maintainabilityIndexEvaluatorDAO.storeFileResults(hashId,
					sourceCodeLocation, codeRange, fileResult);
			results.add(fileResult);
		}
		return results;
	}

	private SLOCResult findSLOCMetricResult(List slocFileResults,
			CodeRange codeRange) {
		if (slocFileResults != null) {
			for (SLOCResult t : slocFileResults) {
				if ((t.getCodeRangeType() == codeRange.getType())
						&& (t.getCodeRangeName().equals(codeRange
								.getSimpleName()))) {
					return t;
				}
			}
		}
		return null;
	}

	private McCabeMetricResult findMcCabeMetricResult(
			List mcCabeFileResults, CodeRange codeRange) {
		if (mcCabeFileResults != null) {
			for (McCabeMetricResult t : mcCabeFileResults) {
				if ((t.getCodeRangeType() == codeRange.getType())
						&& (t.getCodeRangeName().equals(codeRange
								.getSimpleName()))) {
					return t;
				}
			}
		}
		return null;
	}

	private HalsteadMetricResult findHalsteadMetricResult(
			List halsteadFileResults, CodeRange codeRange) {
		if (halsteadFileResults != null) {
			for (HalsteadMetricResult t : halsteadFileResults) {
				if ((t.getCodeRangeType() == codeRange.getType())
						&& (t.getCodeRangeName().equals(codeRange
								.getSimpleName()))) {
					return t;
				}
			}
		}
		return null;
	}

	@Override
	public Set getEvaluatedQualityCharacteristics() {
		return EVALUATED_QUALITY_CHARACTERISTICS;
	}

	@Override
	protected DirectoryMetrics processDirectory(AnalysisRun analysisRun,
			AnalysisFileTree directory) throws InterruptedException,
			EvaluationStoreException {
		MaintainabilityIndexDirectoryResults finalResults = new MaintainabilityIndexDirectoryResults(
				MaintainabilityIndexEvaluator.ID,
				MaintainabilityIndexEvaluator.PLUGIN_VERSION,
				directory.getHashId(), new Date());
		return finalResults;
	}

	@Override
	protected DirectoryMetrics processProject(AnalysisRun analysisRun,
			boolean enableReevaluation) throws InterruptedException,
			EvaluationStoreException {
		return processDirectory(analysisRun, analysisRun.getFileTree());
	}

	@Override
	public void setConfigurationParameter(ConfigurationParameter parameter,
			Object value) {
		// Intentionally left empty.
		throw new IllegalArgumentException("Parameter '" + parameter
				+ "' is unknown.");
	}

	@Override
	public Object getConfigurationParameter(ConfigurationParameter parameter) {
		// Intentionally left empty.
		throw new IllegalArgumentException("Parameter '" + parameter
				+ "' is unknown.");
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy