com.puresoltechnologies.purifinity.server.metrics.cocomo.basic.BasicCoCoMoEvaluator Maven / Gradle / Ivy
/***************************************************************************
*
* CoCoMo.java
* -------------------
* copyright : (c) 2009 by PureSol-Technologies
* author : Rick-Rainer Ludwig
* email : [email protected]
*
***************************************************************************/
package com.puresoltechnologies.purifinity.server.metrics.cocomo.basic;
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 com.puresoltechnologies.commons.domain.ConfigurationParameter;
import com.puresoltechnologies.commons.domain.LevelOfMeasurement;
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.CodeAnalysis;
import com.puresoltechnologies.purifinity.analysis.domain.CodeRange;
import com.puresoltechnologies.purifinity.analysis.domain.CodeRangeType;
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.cocomo.basic.db.BasicCoCoMoEvaluatorDAO;
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;
/**
* This class calculates the CoCoMo for a set number of sloc and a given average
* salary and complexity.
*
* @author Rick-Rainer Ludwig
*
*/
@Stateless
@Remote(Evaluator.class)
public class BasicCoCoMoEvaluator extends AbstractMetricEvaluator {
public static final String ID = BasicCoCoMoEvaluator.class.getName();
public static final String NAME = "Basic COst COnstruction MOdel";
public static final Version PLUGIN_VERSION = new Version(1, 0, 0);
public static final String DESCRIPTION = "The Basic COst COnstruction MOdel is a simple way "
+ "to estimate the construction costs of a "
+ "software project by couting the physical lines of code.";
public static final Set EVALUATED_QUALITY_CHARACTERISTICS = new HashSet<>();
public static final Set DEPENDENCIES = new HashSet<>();
static {
DEPENDENCIES.add(SLOCMetricCalculator.ID);
}
private static final String COMPLEXITY_PROPERTY = "evaluator.cocomo.basic.complexity";
private static final String SALARY_PROPERTY = "evaluator.cocomo.basic.salary";
private static final String CURRENCY_PROPERTY = "evaluator.cocomo.basic.currency";
public static final List> PARAMETERS = new ArrayList<>();
static {
PARAMETERS
.add(new ConfigurationParameter(
"Complexity",
"",
LevelOfMeasurement.NOMINAL,
"Specifies the complexity of the project. Valid values: LOW, MEDIUM, HIGH",
String.class, COMPLEXITY_PROPERTY, "/", "LOW"));
PARAMETERS
.add(new ConfigurationParameter(
"Yearly Salary",
"currency",
LevelOfMeasurement.RATIO,
"Specifies the average yearly salary for a single developer for cost calculation.",
Integer.class, SALARY_PROPERTY, "/", 56286));
PARAMETERS.add(new ConfigurationParameter("Currency", "",
LevelOfMeasurement.NOMINAL, "Currency for cost calculation.",
String.class, CURRENCY_PROPERTY, "/", "USD"));
}
private SoftwareProject complexity = SoftwareProject.LOW;
private int averageSalary = 56286;
private String currency = "USD";
@Inject
private BasicCoCoMoEvaluatorDAO basicCoCoMoEvaluatorDAO;
@Inject
private SLOCMetricEvaluatorDAO slocMetricEvaluatorDAO;
public BasicCoCoMoEvaluator() {
super(ID, NAME, PLUGIN_VERSION, DESCRIPTION);
}
@Override
public List> getConfigurationParameters() {
return PARAMETERS;
}
@Override
public Set> getParameters() {
return BasicCoCoMoEvaluatorParameter.ALL;
}
public SoftwareProject getComplexity() {
return complexity;
}
public int getAverageSalary() {
return averageSalary;
}
public String getCurrency() {
return currency;
}
public void setComplexity(SoftwareProject complexity) {
this.complexity = complexity;
}
public void setAverageSalary(int averageSalary) {
this.averageSalary = averageSalary;
}
public void setCurrency(String currency) {
this.currency = currency;
}
/**
* {@inheritDoc}
*/
@Override
public Set getEvaluatedQualityCharacteristics() {
return EVALUATED_QUALITY_CHARACTERISTICS;
}
@Override
protected FileMetrics processFile(AnalysisRun analysisRun,
CodeAnalysis analysis) throws EvaluationStoreException {
HashId hashId = analysis.getAnalysisInformation().getHashId();
if (slocMetricEvaluatorDAO.hasFileResults(hashId)) {
List slocResults = slocMetricEvaluatorDAO
.readFileResults(hashId);
SourceCodeLocation sourceCodeLocation = analysisRun.findTreeNode(
hashId).getSourceCodeLocation();
for (SLOCResult results : slocResults) {
if (results.getCodeRangeType() == CodeRangeType.FILE) {
int phyLoc = results.getSLOCMetric().getPhyLOC();
BasicCoCoMoFileResults fileResults = new BasicCoCoMoFileResults(
BasicCoCoMoEvaluator.ID,
BasicCoCoMoEvaluator.PLUGIN_VERSION, hashId,
sourceCodeLocation, new Date());
fileResults.setAverageSalary(averageSalary, currency);
fileResults.setComplexity(complexity);
fileResults.setSloc(phyLoc);
CodeRange codeRange = new CodeRange(
results.getCodeRangeName(),
results.getCodeRangeName(),
results.getCodeRangeType(),
analysis.getUniversalSyntaxTree());
basicCoCoMoEvaluatorDAO.storeFileResults(hashId,
sourceCodeLocation, codeRange, fileResults);
return fileResults;
}
}
}
return null;
}
@Override
protected DirectoryMetrics processDirectory(AnalysisRun analysisRun,
AnalysisFileTree directory) throws InterruptedException,
EvaluationStoreException {
int phyLoc = 0;
for (AnalysisFileTree child : directory.getChildren()) {
HashId hashId = child.getHashId();
if (child.isFile()) {
if (slocMetricEvaluatorDAO.hasFileResults(hashId)) {
List fileResults = slocMetricEvaluatorDAO
.readFileResults(hashId);
for (SLOCResult metrics : fileResults) {
if (metrics.getCodeRangeType().equals(
CodeRangeType.FILE)) {
phyLoc += metrics.getSLOCMetric().getPhyLOC();
break;
}
}
}
} else {
if (slocMetricEvaluatorDAO.hasDirectoryResults(hashId)) {
SLOCResult directoryResults = slocMetricEvaluatorDAO
.readDirectoryResults(hashId);
phyLoc += directoryResults.getSLOCMetric().getPhyLOC();
}
}
}
HashId hashId = directory.getHashId();
BasicCoCoMoDirectoryResults directoryResults = new BasicCoCoMoDirectoryResults(
BasicCoCoMoEvaluator.ID, BasicCoCoMoEvaluator.PLUGIN_VERSION,
hashId, new Date());
directoryResults.setAverageSalary(averageSalary, currency);
directoryResults.setComplexity(complexity);
directoryResults.setSloc(phyLoc);
basicCoCoMoEvaluatorDAO.storeDirectoryResults(hashId, directoryResults);
return directoryResults;
}
@Override
protected DirectoryMetrics processProject(AnalysisRun analysisRun,
boolean enableReevaluation) throws InterruptedException,
EvaluationStoreException {
AnalysisFileTree directory = analysisRun.getFileTree();
return processDirectory(analysisRun, directory);
}
@Override
public void setConfigurationParameter(ConfigurationParameter> parameter,
Object value) {
if (COMPLEXITY_PROPERTY.equals(parameter.getPropertyKey())) {
setComplexity(SoftwareProject.valueOf((String) value));
} else if (SALARY_PROPERTY.equals(parameter.getPropertyKey())) {
setAverageSalary(averageSalary);
} else if (CURRENCY_PROPERTY.equals(parameter.getPropertyKey())) {
setCurrency((String) value);
} else {
throw new IllegalArgumentException("Parameter '" + parameter
+ "' is unknown.");
}
}
@Override
public Object getConfigurationParameter(ConfigurationParameter> parameter) {
if (COMPLEXITY_PROPERTY.equals(parameter.getPropertyKey())) {
return getComplexity().name();
} else if (SALARY_PROPERTY.equals(parameter.getPropertyKey())) {
return Integer.valueOf(getAverageSalary());
} else if (CURRENCY_PROPERTY.equals(parameter.getPropertyKey())) {
return getCurrency();
} else {
throw new IllegalArgumentException("Parameter '" + parameter
+ "' is unknown.");
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy