Skip to content
Snippets Groups Projects
Commit 4708b508 authored by Eddie Groh's avatar Eddie Groh
Browse files

Added lines of codes, comments and nesting level metrics

Issue-Ref: 4310
Issue-Url: af3#4310



Signed-off-by: default avatarEddie Groh <groh@fortiss.org>
parent 52f37bd5
No related branches found
No related tags found
1 merge request!210Setting up Metric extraction plugin for AF3 : Issue 4310
......@@ -5,27 +5,15 @@
<?import javafx.scene.chart.NumberAxis?>
<?import javafx.scene.chart.PieChart?>
<?import javafx.scene.chart.ScatterChart?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ChoiceBox?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.control.Tab?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.BorderPane?>
<SplitPane fx:id="metricsSplitPane" dividerPositions="0.07035175879396985" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" orientation="VERTICAL" prefHeight="400.0" prefWidth="1035.0" xmlns="http://javafx.com/javafx/20.0.1" xmlns:fx="http://javafx.com/fxml/1">
<SplitPane fx:id="metricsSplitPane" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" orientation="VERTICAL" prefHeight="400.0" prefWidth="1035.0" xmlns="http://javafx.com/javafx/20.0.1" xmlns:fx="http://javafx.com/fxml/1">
<items>
<BorderPane maxHeight="-Infinity" minHeight="-Infinity" prefHeight="25.0" prefWidth="626.0">
<center>
<Label fx:id="topLabel" alignment="CENTER" contentDisplay="CENTER" prefHeight="51.0" prefWidth="500.0" textAlignment="CENTER" BorderPane.alignment="CENTER" />
</center>
<left>
<Button fx:id="refreshButton" mnemonicParsing="false" onAction="#onRefreshMetricsSubmit" text="Refresh Metrics" BorderPane.alignment="CENTER" />
</left>
<top>
<SplitPane BorderPane.alignment="CENTER" />
</top>
</BorderPane>
<TabPane prefHeight="200.0" prefWidth="200.0" tabClosingPolicy="UNAVAILABLE">
<tabs>
<Tab text="Pie and Spider">
......@@ -34,7 +22,14 @@
<children>
<SplitPane dividerPositions="0.5" layoutX="56.0" layoutY="-19.0" prefHeight="134.0" prefWidth="1033.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<items>
<PieChart fx:id="pieChart" prefHeight="184.0" prefWidth="1033.0" />
<BorderPane prefHeight="200.0" prefWidth="200.0">
<center>
<PieChart fx:id="pieChart" prefHeight="184.0" prefWidth="1033.0" BorderPane.alignment="CENTER" />
</center>
<top>
<ChoiceBox fx:id="choiceBox" onAction="#onChoiceBoxChange" prefWidth="150.0" BorderPane.alignment="CENTER" />
</top>
</BorderPane>
<BorderPane fx:id="borderPane" prefHeight="158.0" prefWidth="81.0" />
</items>
</SplitPane>
......
......@@ -28,8 +28,6 @@ import static org.fortiss.tooling.kernel.ui.util.SelectionUtils.checkAndPickFirs
import static org.fortiss.tooling.kernel.utils.EcoreUtils.getFirstParentWithType;
import java.text.DecimalFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import org.eclipse.emf.ecore.EObject;
......@@ -41,6 +39,7 @@ import org.fortiss.tooling.common.ui.javafx.layout.CompositeFXControllerBase;
import org.fortiss.tooling.common.ui.javafx.style.FillStyle;
import org.fortiss.tooling.common.ui.javafx.style.FontStyle;
import org.fortiss.tooling.common.ui.javafx.style.LineStyle;
import org.fortiss.tooling.ext.quality.data.MetricDataManager;
import org.fortiss.tooling.ext.quality.data.MetricKey;
import org.fortiss.tooling.ext.quality.data.MetricTreeNode;
import org.fortiss.tooling.ext.quality.service.ModelQualityService;
......@@ -59,8 +58,7 @@ import javafx.scene.Node;
import javafx.scene.chart.PieChart;
import javafx.scene.chart.ScatterChart;
import javafx.scene.chart.XYChart;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.SplitPane;
import javafx.scene.layout.BorderPane;
......@@ -77,13 +75,9 @@ public class ModelQualityFXController extends CompositeFXControllerBase<SplitPan
/** The {@link IProjectRootElement} in which the selected element is contained in. */
private IProjectRootElement currentRootElement;
/** The refresh {@link Button} to refresh the metrics. */
/** a choiceBox */
@FXML
private Button refreshButton;
/** The central top {@link Label} to display short messages. */
@FXML
private Label topLabel;
private ChoiceBox<MetricKey> choiceBox;
/** The bottom {@link BorderPane} for the spiderchart */
@FXML
......@@ -97,9 +91,6 @@ public class ModelQualityFXController extends CompositeFXControllerBase<SplitPan
@FXML
private ScatterChart<Number, Number> scatterChart;
/** Time format when displaying updating time. */
private final DateTimeFormatter timeFormat = DateTimeFormatter.ofPattern("HH:mm:ss");
/** {@inheritDoc} */
@Override
public String getFXMLLocation() {
......@@ -109,9 +100,15 @@ public class ModelQualityFXController extends CompositeFXControllerBase<SplitPan
/** {@inheritDoc} */
@Override
public void initialize() {
// Not used
choiceBox.getItems().addAll(MetricKey.values());
}
/**
* The last IHierachicElement which the user has clicked. Might be null when no or invalid
* Object is selected
*/
private IHierarchicElement lastSelectedElement;
/** {@inheritDoc} */
@Override
public void selectionChanged(IWorkbenchPart part, ISelection selection) {
......@@ -119,15 +116,15 @@ public class ModelQualityFXController extends CompositeFXControllerBase<SplitPan
ModelQualityService.getInstance();
var manager = ModelQualityService.metricDataManagerInstance;
if(manager == null) {
topLabel.setText(
"No Metrics were available at " + timeFormat.format(LocalDateTime.now()));
// topLabel.setText("No Metrics were available at " +
// timeFormat.format(LocalDateTime.now()));
return;
}
EObject selected = checkAndPickFirst(selection, EObject.class);
if(selected == null) {
topLabel.setText("Nothing selected");
// topLabel.setText("Nothing selected");
return;
}
......@@ -140,12 +137,12 @@ public class ModelQualityFXController extends CompositeFXControllerBase<SplitPan
if(currentRootElement == null) {
// There was no root element for the selected element. (Usually should be the
// FileProject.) This is not displayed here.
topLabel.setText("No root found");
// topLabel.setText("No root found");
return;
}
if(!(currentRootElement instanceof IHierarchicElement)) {
topLabel.setText("Root is not an IHierarchicElement");
// topLabel.setText("Root is not an IHierarchicElement");
return;
}
......@@ -153,15 +150,36 @@ public class ModelQualityFXController extends CompositeFXControllerBase<SplitPan
var root_provider = manager.getRootNodes().get(currentRootElement);
if(root_provider == null) {
topLabel.setText("No Metric found for this project, did you export metrics?");
// topLabel.setText("No Metric found for this project, did you export metrics?");
return;
}
var element = (IHierarchicElement)selected;
var node = manager.getHierarchicLookupTable().get(element);
lastSelectedElement = (IHierarchicElement)selected;
} else {
// topLabel.setText("Selected is not an IHierarchicElement");
}
updateCharts();
}
/**
* Is triggered when the refresh button is pressed.
*/
public void onChoiceBoxChange() {
updateCharts();
}
/**
* Updates the chart in the metric view
*/
private void updateCharts() {
if(lastSelectedElement != null) {
MetricDataManager manager = ModelQualityService.metricDataManagerInstance;
MetricTreeNode node = manager.getHierarchicLookupTable().get(lastSelectedElement);
if(node != null) {
topLabel.setText("Text");
// topLabel.setText("Text");
if(!node.getChildren().isEmpty()) {
......@@ -171,9 +189,7 @@ public class ModelQualityFXController extends CompositeFXControllerBase<SplitPan
// Create PieChart and add data
pieChart.getData().clear();
for(var child : node.getChildren()) {
Double value = child.getStoredMetrics()
.get(MetricKey.NUMBER_OF_TOTAL_CODE_CONSTANTS);
Double value = child.getStoredMetrics().get(choiceBox.getValue());
if(value != null) {
PieChart.Data slice = new PieChart.Data(child.getName(), value);
pieChart.getData().add(slice);
......@@ -205,27 +221,16 @@ public class ModelQualityFXController extends CompositeFXControllerBase<SplitPan
}
}
} else {
borderPane.setCenter(null);
pieChart.getData().clear();
// Return, otherwise the data will be cleared
return;
}
} else {
topLabel.setText("Element not in metrics");
// topLabel.setText("Element not in metrics");
}
} else {
topLabel.setText("Selected is not an IHierarchicElement");
}
}
/**
* Is triggered when the refresh button is pressed.
*/
public void onRefreshMetricsSubmit() {
LocalDateTime currentTime = LocalDateTime.now();
topLabel.setText("View was updated at " + timeFormat.format(currentTime));
borderPane.setCenter(null);
pieChart.getData().clear();
}
/**
......
......@@ -38,6 +38,8 @@ public enum MetricKey {
NUMBER_OF_CHANNELS(false),
/** Safety level of the element */
SAFETY_LEVEL(false, true),
/** How deeply nested the corresponding element is */
NESTING_LEVEL(false),
//
// Metrics which are collected over all children nodes
......@@ -64,7 +66,13 @@ public enum MetricKey {
NUMBER_OF_TOTAL_CODE_CONSTANTS(true),
/** Cyclomatic complexity number as sum over all components */
NUMBER_OF_TOTAL_CODE_CYCLOMATIC_COMPLEXITY(true);
NUMBER_OF_TOTAL_CODE_CYCLOMATIC_COMPLEXITY(true),
/** Counts the Lines of Code (LoC) in the component and its sub-components */
NUMBER_OF_TOTAL_CODE_LINES(true),
/** Representation of the total amount of comment blocks in all code specifications */
NUMBER_OF_TOTAL_CODE_COMMENTS(true);
/** Metrics which are a combination from the data of multiple nodes */
private static List<MetricKey> collectorKeys = new ArrayList<>();
......
......@@ -126,7 +126,7 @@ public class ModelQualityService extends EObjectAwareServiceBase<IMetricProvider
// Get first element, there should not be any other elements
IHierarchicElement firstElement = elements.get(0);
MetricTreeNode root_node = new MetricTreeNode();
recursivlyCollectMetrics(root_node, firstElement);
recursivlyCollectMetrics(root_node, firstElement, 0);
root_nodes.put(rootElement, root_node);
}
}
......@@ -139,12 +139,16 @@ public class ModelQualityService extends EObjectAwareServiceBase<IMetricProvider
* to which the data is collected
* @param currentElement
* element to collect the data from
* @param recursionLevel
* parameter which indicates the current recursion level, used for metric
*/
private void recursivlyCollectMetrics(MetricTreeNode node, IHierarchicElement currentElement) {
private void recursivlyCollectMetrics(MetricTreeNode node, IHierarchicElement currentElement,
int recursionLevel) {
var manager = metricDataManagerInstance;
collectMetrics(node, currentElement);
node.getStoredMetrics().put(MetricKey.NESTING_LEVEL, (double)recursionLevel);
// Check if any of the specifications is an IHierarchicElement
// This is for example the case with an StateAutomaton
......@@ -161,9 +165,9 @@ public class ModelQualityService extends EObjectAwareServiceBase<IMetricProvider
// Add reference from the element to this, so the lookups works as expected
manager.getHierarchicLookupTable().put(specificationElement, node);
// Skip the specification element to get a more useful tree structure
recursivlyCollectMetrics(node, containedElements.get(0));
recursivlyCollectMetrics(node, containedElements.get(0), recursionLevel);
} else {
recursivlyCollectMetrics(node, specificationElement);
recursivlyCollectMetrics(node, specificationElement, recursionLevel);
}
// Add reference from the element to this, so the lookups works as expected
manager.getHierarchicLookupTable().put(currentElement, node);
......@@ -173,7 +177,7 @@ public class ModelQualityService extends EObjectAwareServiceBase<IMetricProvider
for(IHierarchicElement containedElement : currentElement.getContainedElements()) {
MetricTreeNode child = new MetricTreeNode();
node.getChildren().add(child);
recursivlyCollectMetrics(child, containedElement);
recursivlyCollectMetrics(child, containedElement, recursionLevel++);
for(MetricKey key : MetricKey.getCollectorKeys()) {
var childMetrics = child.getStoredMetrics();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment