Test coverage report for MatrixEngine.java - www.sdmetrics.com
/*
* SDMetrics Open Core for UML design measurement
* Copyright (c) Juergen Wuest
* To contact the author, see <http://www.sdmetrics.com/Contact.html>.
*
* This file is part of the SDMetrics Open Core.
*
* SDMetrics Open Core is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
* SDMetrics Open Core 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with SDMetrics Open Core. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.sdmetrics.metrics;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import com.sdmetrics.math.ExpressionNode;
import com.sdmetrics.math.IntegerMatrix;
import com.sdmetrics.model.MetaModel;
import com.sdmetrics.model.MetaModelElement;
import com.sdmetrics.model.Model;
import com.sdmetrics.model.ModelElement;
/**
* Calculates relation matrices.
*/
public class MatrixEngine {
/** Metrics engine to use. */
private final MetricsEngine engine;
/** The model with all available elements. */
private final Model model;
/** Set to calculate the set definition procedures for the matrices. */
private final Set proxy;
/**
* Creates a new matrix engine.
*
* @param me The metrics engine to be used for the calculation.
*/
public MatrixEngine(MetricsEngine me) {
this.engine = me;
model = me.getModel();
proxy = new Set("dummy", me.getMetaModel().getType(
MetaModel.BASE_ELEMENT));
proxy.setMultiSet(true);
}
/**
* Returns the metrics engine that this matrix engine uses.
*
* @return Metrics engine of the matrix engine.
*/
public MetricsEngine getMetricsEngine() {
return engine;
}
/**
* Calculates a relation matrix.
*
* @param matrix Definition of the matrix to calculate.
* @return The matrix
* @throws SDMetricsException An error occurred during the calculation of
* the matrix.
*/
public MatrixData calculate(Matrix matrix) throws SDMetricsException {
// create lists of accepted row and column elements
final List<ModelElement> rows = getElementList(matrix.getRowType(),
matrix.getRowCondition());
final List<ModelElement> columns = getElementList(matrix.getColumnType(),
matrix.getColumnCondition());
// create a mapping from the column elements to their column index
HashMap<Object, Integer> colIndices = new HashMap<>();
for (int i = 0; i < columns.size(); i++) {
colIndices.put(columns.get(i), Integer.valueOf(i));
}
ProcedureAttributes attributes = matrix.getAttributes();
proxy.setAttributes(attributes);
// set the procedure name, for backwards compatibility, replace
// deprecated "setoperation" with the current "compoundset"
String procName = matrix.getProcedureName();
if ("setoperation".equals(procName)) {
procName = "compoundset";
}
proxy.setProcedureName(procName);
// Calculate the contents of the matrix
IntegerMatrix values = new IntegerMatrix();
for (int row = 0; row < rows.size(); row++) {
Collection<?> set = engine.computeSet(rows.get(row), proxy);
for (Object colElement : set) {
Integer colIndex = colIndices.get(colElement);
if (colIndex != null) {
values.increment(row, colIndex.intValue());
}
}
}
return new MatrixData(matrix, rows, columns, values);
}
/**
* Returns the list of elements of a type that satisfy a given condition.
*
* @param type Type of the elements to return
* @param condition The condition for the elements to return,
* <code>null</code> to return all elements.
* @return List of matching elements
* @throws SDMetricsException Error evaluating the condition
*/
private List<ModelElement> getElementList(MetaModelElement type,
ExpressionNode condition) throws SDMetricsException {
List<ModelElement> candidateElements = model.getAcceptedElements(type);
if (condition == null) {
return candidateElements;
}
List<ModelElement> result = new ArrayList<>();
for (ModelElement elem : candidateElements) {
if (engine.evalBooleanExpression(elem, condition, null)) {
result.add(elem);
}
}
return result;
}
}