Test coverage report for AbstractProcedure.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.Collection;
import com.sdmetrics.math.ExpressionNode;
import com.sdmetrics.model.MetaModel;
import com.sdmetrics.model.MetaModelElement;
import com.sdmetrics.model.Model;
import com.sdmetrics.model.ModelElement;
/**
* Base class for metric, set, and rule procedures as well as scalar, boolean,
* and set operations.
*/
public class AbstractProcedure {
/** The name of the procedure in the metric definition file. */
private String name;
/** The metrics engine for calculation of the procedure. */
private MetricsEngine metricsEngine;
// Methods for use by specializations
/**
* Gets the metrics engine to use for calculations.
*
* @return Metrics engine for this procedure
*/
protected MetricsEngine getMetricsEngine() {
return metricsEngine;
}
/**
* Gets the element set specified by a "relation" or "relset" attribute.
*
* @param element Element for which to retrieve the set.
* @param attributes Attributes of the procedure definition.
* @param vars Variables for the evaluation of expressions
* @return The set specified by the "relation" or "relset" attribute.
* @throws SDMetricsException Neither "relation" nor "relset" attribute was
* specified.
*/
@SuppressWarnings("unchecked")
protected Collection<ModelElement> getRelationOrSet(ModelElement element,
ProcedureAttributes attributes, Variables vars)
throws SDMetricsException {
// Check "relation attribute"
String relation = attributes.getStringValue("relation");
if (relation != null) {
return element.getRelations(relation);
}
// Check "relset" attribute
ExpressionNode setExpr = attributes.getExpression("relset");
if (setExpr == null) {
throw new SDMetricsException(element, null,
"Neither 'relation' nor 'relset' attribute specified.");
}
return (Collection<ModelElement>) metricsEngine.evalSetExpression(
element, setExpr, vars);
}
/**
* Creates a new filter attribute processing object.
*
* @param attributes Attributes of the procedure definition
* @return Filter attribute processor for this procedure
* @throws SDMetricsException One of the filter attributes contains illegal
* values
*/
protected FilterAttributeProcessor getFilterAttributeProcessor(
ProcedureAttributes attributes) throws SDMetricsException {
return new FilterAttributeProcessor(getMetricsEngine(), attributes);
}
/**
* Gets the model for which this calculation takes place.
*
* @return The model for this calculation.
*/
protected Model getModel() {
return metricsEngine.getModel();
}
/**
* Gets the metamodel for which this calculation takes place.
*
* @return The metamodel for this calculation
*/
protected MetaModel getMetaModel() {
return metricsEngine.getMetaModel();
}
/**
* Calculates the value of a metric expression for a model element.
*
* @param element The model element to evaluate the expression for.
* @param node Root node of the expression to evaluate
* @param vars Variables for the expression evaluation
* @return The resulting metric value of the expression
* @throws SDMetricsException a problem occurred during the evaluation
*/
protected Object evalExpression(ModelElement element, ExpressionNode node,
Variables vars) throws SDMetricsException {
return metricsEngine.evalExpression(element, node, vars);
}
/**
* Calculates the value of a boolean expression for a model element.
*
* @param element The model element to evaluate the expression for.
* @param node Root node of the expression to evaluate
* @param vars Variables for the expression evaluation
* @return The resulting boolean value of the expression
* @throws SDMetricsException a problem occurred during the evaluation
*/
protected boolean evalBooleanExpression(ModelElement element,
ExpressionNode node, Variables vars) throws SDMetricsException {
return metricsEngine.evalBooleanExpression(element, node, vars);
}
/**
* Calculates a set expression for a model element.
*
* @param element The model element to evaluate the expression for.
* @param node Root node of the expression to evaluate
* @param vars Variables for the expression evaluation
* @return the result set of the evaluation
* @throws SDMetricsException a problem occurred during the evaluation
*/
protected Collection<?> evalSetExpression(ModelElement element,
ExpressionNode node, Variables vars) throws SDMetricsException {
return metricsEngine.evalSetExpression(element, node, vars);
}
/**
* Calculates a set expression that returns a set of model elements.
*
* @param element The model element to evaluate the expression for.
* @param node Root node of the expression to evaluate
* @param vars Variables for the expression evaluation
* @return the resulting element set
* @throws SDMetricsException a problem occurred during the evaluation
*/
@SuppressWarnings("unchecked")
protected Collection<ModelElement> evalElementSetExpression(
ModelElement element, ExpressionNode node, Variables vars)
throws SDMetricsException {
return (Collection<ModelElement>) metricsEngine.evalSetExpression(
element, node, vars);
}
/**
* Checks if a metric or set can be applied to a related element. Used for
* recursive or nesting metrics/sets. If the metric or set is not
* inheritable, the related element must be of the same type as the element
* for which the metric is being calculated. If the metric or set is
* inheritable, the related element must be an ancestor or descendant for
* which the metric is also available.
*
* @param element The element for which the metric/set/rule is calculated.
* @param metric The metric, set, or rule to be checked.
* @param candidate The related element to check.
* @return <code>true</code> if the metric/set/rule can be applied to the
* candidate element, else <code>false</code>
* @since 2.3
*/
protected boolean isCompatible(ModelElement element, MetricEntry metric,
ModelElement candidate) {
MetaModelElement elType = element.getType();
MetaModelElement candType = candidate.getType();
if (elType == candType) {
return true;
}
if (metric.isInheritable()) {
return (candType.specializes(elType) || elType
.specializes(candType))
&& metricsEngine.getMetricStore().getMetric(candType,
metric.getName()) != null;
}
return false;
}
// Package internal house keeping methods
/**
* Sets the name of this procedure from the metric definition file.
*
* @param name The name of the procedure.
*/
void setName(String name) {
this.name = name;
}
/**
* Gets the name of this procedure.
*
* @return name The name of the procedure.
*
*/
String getName() {
return name;
}
/**
* Sets the metrics engine for this procedure.
*
* @param engine The metrics engine
*/
void setMetricsEngine(MetricsEngine engine) {
this.metricsEngine = engine;
}
/**
* Clears the procedure for reuse.
* <p>
* Deletes the reference to the metrics engine.
*/
void clear() {
metricsEngine = null;
}
}