Commit b23b5eed authored by Johannes Salentin's avatar Johannes Salentin
Browse files

new smells

minor improvements
parent f0e6a95a
Pipeline #158642 passed with stages
in 1 minute and 28 seconds
......@@ -11,11 +11,35 @@
<element identifier="id-ab882019-9db1-4442-800f-c106b05d143c" xsi:type="BusinessService">
<name xml:lang="de">S3</name>
</element>
<element identifier="id-f442ba6e-4c3f-440f-b521-2762740c00d8" xsi:type="BusinessService">
<name xml:lang="de">C1</name>
</element>
<element identifier="id-499673e2-c9d3-482b-bc19-36fb83ba537b" xsi:type="BusinessService">
<name xml:lang="de">C2</name>
</element>
<element identifier="id-dc88773c-fea9-4519-89a0-dd6c2830e125" xsi:type="BusinessService">
<name xml:lang="de">C3</name>
</element>
<element identifier="id-01bf8e8f-e3cd-4f51-a5c2-882ad299a192" xsi:type="BusinessService">
<name xml:lang="de">Cloop</name>
</element>
<element identifier="id-dd08665e-23f5-4f67-8568-39adfb7d4b98" xsi:type="BusinessService">
<name xml:lang="de">C4</name>
</element>
<element identifier="id-9ec14be6-d4d3-4579-9c54-ca67519c005e" xsi:type="BusinessService">
<name xml:lang="de">C0</name>
</element>
</elements>
<relationships>
<relationship identifier="id-db86487d-18d5-44ad-93ab-6033c0483e44" source="id-c75917ca-5c20-4fc1-be7d-8756eef684b0" target="id-435bc94c-32fc-48fb-8677-e2ff74eb32c8" xsi:type="Serving" />
<relationship identifier="id-85ef5ebb-0cf3-4a6f-ae84-96db26374e54" source="id-435bc94c-32fc-48fb-8677-e2ff74eb32c8" target="id-ab882019-9db1-4442-800f-c106b05d143c" xsi:type="Serving" />
<relationship identifier="id-3331e143-5efe-47af-b2a1-90334bcb736e" source="id-ab882019-9db1-4442-800f-c106b05d143c" target="id-c75917ca-5c20-4fc1-be7d-8756eef684b0" xsi:type="Serving" />
<relationship identifier="id-3a2e5d9c-12cf-479d-bae4-ac1db53026dd" source="id-f442ba6e-4c3f-440f-b521-2762740c00d8" target="id-499673e2-c9d3-482b-bc19-36fb83ba537b" xsi:type="Serving" />
<relationship identifier="id-d302afe9-4d65-45cf-ba4a-e0503bcd4c0e" source="id-499673e2-c9d3-482b-bc19-36fb83ba537b" target="id-dc88773c-fea9-4519-89a0-dd6c2830e125" xsi:type="Serving" />
<relationship identifier="id-5100a2a8-5cea-46ff-aa48-02b8f3cadbd5" source="id-01bf8e8f-e3cd-4f51-a5c2-882ad299a192" target="id-499673e2-c9d3-482b-bc19-36fb83ba537b" xsi:type="Serving" />
<relationship identifier="id-930a5f35-b0c1-48a3-b04a-20dffbbd80d7" source="id-dc88773c-fea9-4519-89a0-dd6c2830e125" target="id-01bf8e8f-e3cd-4f51-a5c2-882ad299a192" xsi:type="Serving" />
<relationship identifier="id-b456a11c-ee1a-4748-990a-8152e9075b14" source="id-dc88773c-fea9-4519-89a0-dd6c2830e125" target="id-dd08665e-23f5-4f67-8568-39adfb7d4b98" xsi:type="Serving" />
<relationship identifier="id-4b404cbe-5eb3-465d-a526-9d0ee64bc717" source="id-9ec14be6-d4d3-4579-9c54-ca67519c005e" target="id-f442ba6e-4c3f-440f-b521-2762740c00d8" xsi:type="Serving" />
</relationships>
<views>
<diagrams>
......@@ -48,6 +72,60 @@
</font>
</style>
</node>
<node identifier="id-d287b6c8-3aee-4088-adf9-015242f852bd" elementRef="id-f442ba6e-4c3f-440f-b521-2762740c00d8" xsi:type="Element" x="732" y="288" w="73" h="49">
<style>
<fillColor r="255" g="255" b="181" a="100" />
<lineColor r="92" g="92" b="92" />
<font name="Segoe UI" size="9">
<color r="0" g="0" b="0" />
</font>
</style>
</node>
<node identifier="id-89e707de-54f9-45d1-bdf6-cc45dcfc0e00" elementRef="id-499673e2-c9d3-482b-bc19-36fb83ba537b" xsi:type="Element" x="828" y="288" w="73" h="37">
<style>
<fillColor r="255" g="255" b="181" a="100" />
<lineColor r="92" g="92" b="92" />
<font name="Segoe UI" size="9">
<color r="0" g="0" b="0" />
</font>
</style>
</node>
<node identifier="id-81001117-4bcb-424d-bfb0-59fb5239b208" elementRef="id-dc88773c-fea9-4519-89a0-dd6c2830e125" xsi:type="Element" x="924" y="300" w="85" h="49">
<style>
<fillColor r="255" g="255" b="181" a="100" />
<lineColor r="92" g="92" b="92" />
<font name="Segoe UI" size="9">
<color r="0" g="0" b="0" />
</font>
</style>
</node>
<node identifier="id-71cc1dfe-b2ba-428f-b510-47f6ec721790" elementRef="id-01bf8e8f-e3cd-4f51-a5c2-882ad299a192" xsi:type="Element" x="660" y="384" w="109" h="49">
<style>
<fillColor r="255" g="255" b="181" a="100" />
<lineColor r="92" g="92" b="92" />
<font name="Segoe UI" size="9">
<color r="0" g="0" b="0" />
</font>
</style>
</node>
<node identifier="id-9497bc7d-9795-4708-a666-6be25b458a25" elementRef="id-dd08665e-23f5-4f67-8568-39adfb7d4b98" xsi:type="Element" x="840" y="432" w="109" h="61">
<style>
<fillColor r="255" g="255" b="181" a="100" />
<lineColor r="92" g="92" b="92" />
<font name="Segoe UI" size="9">
<color r="0" g="0" b="0" />
</font>
</style>
</node>
<node identifier="id-5a234dfe-0529-489e-b93e-c033f5915425" elementRef="id-9ec14be6-d4d3-4579-9c54-ca67519c005e" xsi:type="Element" x="612" y="288" w="85" h="49">
<style>
<fillColor r="255" g="255" b="181" a="100" />
<lineColor r="92" g="92" b="92" />
<font name="Segoe UI" size="9">
<color r="0" g="0" b="0" />
</font>
</style>
</node>
<connection identifier="id-d08a21eb-2c62-4f01-8a4c-9b060b0fa6b2" relationshipRef="id-db86487d-18d5-44ad-93ab-6033c0483e44" xsi:type="Relationship" source="id-47063029-f542-4d37-b937-0a4bc8aa66aa" target="id-63ae4155-ef68-4f1b-9d0e-5ecf07b22f26">
<style>
<lineColor r="0" g="0" b="0" />
......@@ -72,6 +150,54 @@
</font>
</style>
</connection>
<connection identifier="id-d16a726d-7c21-476a-9473-56fa2f836f78" relationshipRef="id-3a2e5d9c-12cf-479d-bae4-ac1db53026dd" xsi:type="Relationship" source="id-d287b6c8-3aee-4088-adf9-015242f852bd" target="id-89e707de-54f9-45d1-bdf6-cc45dcfc0e00">
<style>
<lineColor r="0" g="0" b="0" />
<font name="Segoe UI" size="9">
<color r="0" g="0" b="0" />
</font>
</style>
</connection>
<connection identifier="id-a04a88bb-3f55-4245-bf34-57262b261bee" relationshipRef="id-d302afe9-4d65-45cf-ba4a-e0503bcd4c0e" xsi:type="Relationship" source="id-89e707de-54f9-45d1-bdf6-cc45dcfc0e00" target="id-81001117-4bcb-424d-bfb0-59fb5239b208">
<style>
<lineColor r="0" g="0" b="0" />
<font name="Segoe UI" size="9">
<color r="0" g="0" b="0" />
</font>
</style>
</connection>
<connection identifier="id-4155db53-e7a7-4605-bd40-731c48a074f1" relationshipRef="id-930a5f35-b0c1-48a3-b04a-20dffbbd80d7" xsi:type="Relationship" source="id-81001117-4bcb-424d-bfb0-59fb5239b208" target="id-71cc1dfe-b2ba-428f-b510-47f6ec721790">
<style>
<lineColor r="0" g="0" b="0" />
<font name="Segoe UI" size="9">
<color r="0" g="0" b="0" />
</font>
</style>
</connection>
<connection identifier="id-05422691-da83-4e90-a427-e2d263082657" relationshipRef="id-b456a11c-ee1a-4748-990a-8152e9075b14" xsi:type="Relationship" source="id-81001117-4bcb-424d-bfb0-59fb5239b208" target="id-9497bc7d-9795-4708-a666-6be25b458a25">
<style>
<lineColor r="0" g="0" b="0" />
<font name="Segoe UI" size="9">
<color r="0" g="0" b="0" />
</font>
</style>
</connection>
<connection identifier="id-41148795-42c6-45bd-a091-b6311c66188a" relationshipRef="id-5100a2a8-5cea-46ff-aa48-02b8f3cadbd5" xsi:type="Relationship" source="id-71cc1dfe-b2ba-428f-b510-47f6ec721790" target="id-89e707de-54f9-45d1-bdf6-cc45dcfc0e00">
<style>
<lineColor r="0" g="0" b="0" />
<font name="Segoe UI" size="9">
<color r="0" g="0" b="0" />
</font>
</style>
</connection>
<connection identifier="id-a75f7912-b43e-4acf-807a-067c1868d785" relationshipRef="id-4b404cbe-5eb3-465d-a526-9d0ee64bc717" xsi:type="Relationship" source="id-5a234dfe-0529-489e-b93e-c033f5915425" target="id-d287b6c8-3aee-4088-adf9-015242f852bd">
<style>
<lineColor r="0" g="0" b="0" />
<font name="Segoe UI" size="9">
<color r="0" g="0" b="0" />
</font>
</style>
</connection>
</view>
</diagrams>
</views>
......
......@@ -17,6 +17,8 @@ public class EASmellDetector {
detectors.add(new Documentation());
detectors.add(new Duplication());
detectors.add(new HubLikeModularization());
detectors.add(new LazyComponent());
detectors.add(new MessageChain());
detectors.add(new SharedPersistency());
detectors.add(new StrictLayersViolation());
detectors.add(new WeakenedModularity());
......
......@@ -145,6 +145,8 @@ public class ModelAdapter {
List<OrganizationType> l = model.getOrganizations().get(0).getItem().stream().filter(e -> e.getLabelGroup().get(0).getValue().toLowerCase().contains(layer.toLowerCase())).collect(Collectors.toList());
if (l.isEmpty()) {
return new ArrayList<>();
} else if (l.get(0).getItem().isEmpty()) {
return new ArrayList<>();
} else {
l = l.get(0).getItem();
List<ElementType> res = new ArrayList<>();
......
......@@ -11,6 +11,8 @@ class Constants {
static final int LARGE_FAN_IN = 10;
static final int LARGE_FAN_OUT = 10;
static final int MAX_SERVICE_CHAIN_LENGTH = 4;
static final double MODULARITY_RATIO = 1;
}
......@@ -24,6 +24,10 @@ public class CyclicDependency extends Detector {
int currentSize = 0;
Set<ElementType> referencedElements = new HashSet<>(model.getReferencedElementsOf(element));
while (referencedElements.size() > currentSize) {
if (referencedElements.contains(element)) {
addToSmells(new EASmell(getSmellName(), element));
break;
}
currentSize = referencedElements.size();
Set<ElementType> additionalElements = new HashSet<>();
for (ElementType e : referencedElements) {
......@@ -31,9 +35,5 @@ public class CyclicDependency extends Detector {
}
referencedElements.addAll(additionalElements);
}
if (referencedElements.contains(element)) {
EASmell cd = new EASmell(getSmellName(), element);
addToSmells(cd);
}
}
}
package de.example.smells;
import de.example.model.ElementType;
import de.example.model.LangStringType;
import java.util.List;
import java.util.stream.Collectors;
public class LazyComponent extends Detector {
public LazyComponent() {
super("Lazy Component");
}
public List<EASmell> detect() {
String[] lazyNames = {"controller", "manager"};
List<ElementType> lazyElements = model.getElements().stream().filter(e -> {
for (LangStringType name : e.getNameGroup()) {
for (String lazyName : lazyNames) {
if (name.getValue().contains(lazyName)) {
return true;
}
}
}
return false;
}).collect(Collectors.toList());
for (ElementType lazyElement : lazyElements) {
addToSmells(new EASmell(getSmellName(), lazyElement));
}
return result;
}
}
package de.example.smells;
import de.example.model.ElementType;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import static de.example.smells.Constants.MAX_SERVICE_CHAIN_LENGTH;
public class MessageChain extends Detector {
public MessageChain() {
super("Message Chain");
}
public List<EASmell> detect() {
List<ElementType> elements = model.getElements().stream().filter(e -> e.getClass().getSimpleName().contains("Service")).collect(Collectors.toList());
//remove cycles
for (ElementType element : elements) {
List<ElementType> current = new ArrayList<>();
current.add(element);
List<ElementType> chain = getServiceChain(element, current);
if (chain.size() > MAX_SERVICE_CHAIN_LENGTH) {
StringBuilder elementsInChain = new StringBuilder();
for (ElementType e : chain) {
elementsInChain.append(e.getNameGroup().get(0).getValue());
elementsInChain.append(", ");
}
addToSmells(new EASmell(getSmellName(), element, " with a chain length of " + chain.size() + " and the elements: " + elementsInChain));
}
}
return result;
}
private List<ElementType> getServiceChain(ElementType start, List<ElementType> current) {
List<ElementType> referencedServiceElements = model.getReferencedElementsOf(start).stream().filter(e -> e.getClass().getSimpleName().contains("Service")).collect(Collectors.toList());
List<ElementType> res = new ArrayList<>();
if (referencedServiceElements.isEmpty()) {
res.add(start);
return res;
} else {
for (ElementType element : referencedServiceElements) {
if (current.contains(element)) {
// loop in chain
break;
}
current.add(element);
List<ElementType> additionalElements = getServiceChain(element, current);
current.remove(element);
if (additionalElements.size() > res.size()) {
res = additionalElements;
}
}
res.add(0, start);
return res;
}
}
}
......@@ -14,7 +14,7 @@ public class SharedPersistency extends Detector {
public List<EASmell> detect() {
List<ElementType> databaseElements = model.getElements().stream().filter(e -> e.getClass().getSimpleName().equals("SystemSoftware") && (e.getNameGroup().get(0).getValue().contains("database") || e.getNameGroup().get(0).getValue().contains("DBMS"))).collect(Collectors.toList());
for (ElementType databaseElement : databaseElements) {
String[] types = {"Association"};
String[] types = {"Association", "Realization", "Assignment"};
List<ElementType> referencedElements = model.getReferencedElementsOf(databaseElement, types);
referencedElements.addAll(model.getElementsWithReferenceTo(databaseElement, types));
if (referencedElements.size() > 1) {
......
......@@ -19,6 +19,6 @@ class TestCyclicDependency {
@Test
void test() {
assertEquals(detector.detect().size(), 3);
assertEquals(detector.detect().size(), 6);
}
}
package de.example.smells;
import de.example.main.ModelAdapter;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
class TestLazyComponent {
private LazyComponent detector;
@BeforeAll
void init() {
ModelAdapter model = new ModelAdapter("CentralModel.xml", null);
Detector.setModel(model);
detector = new LazyComponent();
}
@Test
void test() {
assertEquals(detector.detect().size(), 1);
}
}
package de.example.smells;
import de.example.main.ModelAdapter;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
class TestMessageChain {
private MessageChain detector;
@BeforeAll
void init() {
ModelAdapter model = new ModelAdapter("Test.xml", null);
Detector.setModel(model);
detector = new MessageChain();
}
@Test
void test() {
assertEquals(detector.detect().size(), 1);
}
}
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