Commit 32f30627 authored by Johannes Salentin's avatar Johannes Salentin
Browse files

improved dead component detection

now relies on isolated cluster of elements
parent e5092836
Pipeline #159593 passed with stages
in 1 minute and 21 seconds
......@@ -39,6 +39,8 @@ public class EASmellDetector {
String totalTime = calculateTimeConsumption(startTotalTime);
System.out.println("\nFinished detection in " + totalTime);
System.out.println(model.getCluster(model.getElementByIdentifier("id-7281a6e6-6586-4fa5-8d27-6cb69cfc1e93")));
}
private static void printSmells(List<EASmell> smells) {
......
......@@ -5,9 +5,7 @@ import org.xml.sax.SAXException;
import javax.xml.bind.JAXBException;
import javax.xml.namespace.QName;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
public class ModelAdapter {
......@@ -162,4 +160,40 @@ public class ModelAdapter {
return model.getViews().getDiagrams().getView();
}
// a cluster is in one layer and is related with structural relations to each other
public Set<ElementType> getCluster(ElementType element) {
Set<ElementType> elementAsSet = new HashSet<>();
elementAsSet.add(element);
List<ElementType> businessElements = getElementsInLayer("Business");
if (businessElements.contains(element)) {
return getCluster(elementAsSet, businessElements);
} else {
List<ElementType> applicationElements = getElementsInLayer("Application");
if (applicationElements.contains(element)) {
return getCluster(elementAsSet, applicationElements);
} else {
List<ElementType> technologyElements = getElementsInLayer("Technology");
if (technologyElements.contains(element)) {
return getCluster(elementAsSet, technologyElements);
}
return elementAsSet;
}
}
}
private Set<ElementType> getCluster(Set<ElementType> elements, List<ElementType> elementsInSameLayer) {
Set<ElementType> res = new HashSet<>(elements);
String[] structuralRelationsOut = {"Aggregation", "Realization", "Composition"};
String[] structuralRelationsIn = {"Assignment"};
for (ElementType element : elements) {
Set<ElementType> children = new HashSet<>(getReferencedElementsOf(element, structuralRelationsOut));
children.addAll(getElementsWithReferenceTo(element, structuralRelationsIn));
children = children.stream().filter(elementsInSameLayer::contains).collect(Collectors.toSet());
if (!children.isEmpty()) {
res.addAll(getCluster(children, elementsInSameLayer));
}
}
return res;
}
}
package de.example.smells;
import de.example.model.ElementType;
import de.example.model.RelationshipType;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class DeadComponent extends Detector {
......@@ -16,64 +15,22 @@ public class DeadComponent extends Detector {
public List<EASmell> detect() {
List<ElementType> elements = model.getElements();
for (ElementType element : elements) {
// no incoming and outgoing relations
if (model.getReferencedElementsOf(element).isEmpty() && model.getElementsWithReferenceTo(element).isEmpty()) {
Set<ElementType> cluster = model.getCluster(element);
boolean used = false;
for (RelationshipType relationship : model.getRelationships()) {
ElementType target = (ElementType) relationship.getTarget();
ElementType source = (ElementType) relationship.getSource();
// relationship to element outside the cluster -> so it is used
if ((cluster.contains(source) && !cluster.contains(target)) || (cluster.contains(target) && !cluster.contains(source))) {
used = true;
break;
}
}
if (!used) {
addToSmells(new EASmell(getSmellName(), element));
}
}
return result;
}
// public List<EASmell> detect() {
// List<ElementType> elements = model.getElements();
// for (ElementType element : elements) {
// for (ElementType root : getPossibleRoots(element)) {
// System.out.println(element.getNameGroup().get(0).getValue() + ": " + root.getNameGroup().get(0).getValue());
// // element or its root element have no incoming and outgoing relations (except structural ones)
// String[] relationships = {"Influence", "Access", "Serving", "Triggering", "Flow", "Specialization", "Association", "Realization", "Composition"};
// if (model.getElementsWithReferenceTo(root, relationships).isEmpty() && model.getReferencedElementsOf(root, relationships).isEmpty()) {
// addToSmells(new EASmell(getSmellName(), element));
// }
// }
// }
// return result;
// }
private Set<ElementType> getPossibleRoots(ElementType element) {
Set<ElementType> elementAsSet = new HashSet<>();
elementAsSet.add(element);
List<ElementType> businessElements = model.getElementsInLayer("Business");
if (businessElements.contains(element)) {
return getPossibleRoots(elementAsSet, businessElements);
} else {
List<ElementType> applicationElements = model.getElementsInLayer("Application");
if (applicationElements.contains(element)) {
return getPossibleRoots(elementAsSet, applicationElements);
} else {
List<ElementType> technologyElements = model.getElementsInLayer("Technology");
if (technologyElements.contains(element)) {
return getPossibleRoots(elementAsSet, technologyElements);
}
return new HashSet<>();
}
}
}
private Set<ElementType> getPossibleRoots(Set<ElementType> elements, List<ElementType> elementsInSameLayer) {
Set<ElementType> res = new HashSet<>();
String[] structuralRelationsIn = {"Aggregation", "Realization", "Composition"};
String[] structuralRelationsOut = {"Assignment"};
for (ElementType element : elements) {
Set<ElementType> parents = new HashSet<>(model.getElementsWithReferenceTo(element, structuralRelationsIn));
parents.addAll(model.getReferencedElementsOf(element, structuralRelationsOut));
// filter parents to only contain elements of same layer
parents = parents.stream().filter(elementsInSameLayer::contains).collect(Collectors.toSet());
if (parents.isEmpty()) {
res.add(element);
} else {
res.addAll(getPossibleRoots(parents, elementsInSameLayer));
}
}
return res;
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment