Skip to content

Commit 5ddbe82

Browse files
committed
refactored DynamicRelationsPrintService
1 parent b6c17c4 commit 5ddbe82

3 files changed

Lines changed: 75 additions & 66 deletions

File tree

dynamic-relations/src/main/java/at/drm/factory/RelationDaoFactory.java

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,14 @@
22

33
import at.drm.dao.RelationDao;
44
import at.drm.exception.NoRelationDaoFoundException;
5-
import lombok.RequiredArgsConstructor;
6-
import org.springframework.context.ApplicationContext;
7-
import org.springframework.core.ResolvableType;
8-
import org.springframework.stereotype.Component;
9-
105
import java.lang.reflect.Field;
116
import java.util.HashSet;
127
import java.util.Map;
138
import java.util.Set;
9+
import lombok.RequiredArgsConstructor;
10+
import org.springframework.context.ApplicationContext;
11+
import org.springframework.core.ResolvableType;
12+
import org.springframework.stereotype.Component;
1413

1514
@Component
1615
@RequiredArgsConstructor
@@ -20,18 +19,17 @@ public class RelationDaoFactory {
2019

2120
public RelationDao getDaoFromSourceObjectClass(Class dynamicRelactionClass) {
2221
Map<String, RelationDao> beansOfType = applicationContext.getBeansOfType(RelationDao.class);
23-
RelationDao relationDao = beansOfType.values().stream()
24-
.filter(dao -> {
25-
ResolvableType resolvableType = ResolvableType.forClass(dao.getClass())
26-
.as(RelationDao.class);
27-
ResolvableType generic = resolvableType.getGeneric(0);
28-
Class<?> resolve = generic.resolve();
29-
assert resolve != null;
30-
Field sourceObject = getDeclaredField(resolve, "sourceObject");
31-
Class<?> type = sourceObject.getType();
32-
return type.equals(dynamicRelactionClass);
33-
}).findFirst().orElseThrow(() -> new NoRelationDaoFoundException("No DynamicRelationDao was found!"));
34-
return relationDao;
22+
return beansOfType.values().stream()
23+
.filter(dao -> {
24+
ResolvableType resolvableType = ResolvableType.forClass(dao.getClass())
25+
.as(RelationDao.class);
26+
ResolvableType generic = resolvableType.getGeneric(0);
27+
Class<?> resolve = generic.resolve();
28+
assert resolve != null;
29+
Field sourceObject = getDeclaredField(resolve, "sourceObject");
30+
Class<?> type = sourceObject.getType();
31+
return type.equals(dynamicRelactionClass);
32+
}).findFirst().orElseThrow(() -> new NoRelationDaoFoundException("No DynamicRelationDao was found!"));
3533
}
3634

3735
public Set<RelationDao> getAllDaos() {

dynamic-relations/src/main/java/at/drm/service/DynamicRelationsPrintService.java

Lines changed: 50 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@
1010
import java.lang.reflect.Modifier;
1111
import java.util.ArrayDeque;
1212
import java.util.Collection;
13+
import java.util.Collections;
1314
import java.util.Deque;
1415
import java.util.HashSet;
1516
import java.util.LinkedList;
16-
import java.util.List;
1717
import java.util.Map;
1818
import java.util.Set;
1919
import java.util.function.Function;
@@ -32,95 +32,103 @@ public class DynamicRelationsPrintService {
3232

3333
private final EntityManager entityManager;
3434
private final RelationService relationService;
35-
3635
private Map<String, Class<RelationIdentity>> classBySimpleName;
3736

3837
public String printRelations(RelationIdentity relationIdentity) {
39-
TreeNodeRelationIdentity root = new TreeNodeRelationIdentity(relationIdentity, new LinkedList<>());
40-
createTree(root);
41-
return printTree(root);
38+
TreeNodeRelationIdentity tree = createTree(relationIdentity);
39+
return printTree(tree);
40+
}
41+
42+
@PostConstruct
43+
public void configure() {
44+
Set<Class<RelationIdentity>> classesImplementingInterface = findClassesImplementingInterface();
45+
classBySimpleName = classesImplementingInterface.stream()
46+
.collect(Collectors.toMap(clazz -> clazz.getSimpleName() + "Type", Function.identity()));
4247
}
4348

4449
private String printTree(TreeNodeRelationIdentity root) {
4550
Deque<Map.Entry<TreeNodeRelationIdentity, Integer>> stack = new ArrayDeque<>();
4651
stack.push(Map.entry(root, 0));
47-
4852
StringBuilder result = new StringBuilder();
4953
while (!stack.isEmpty()) {
5054
var entry = stack.pop();
5155
var node = entry.getKey();
5256
int level = entry.getValue();
53-
5457
result.append(" ".repeat(level))
5558
.append(node.object().getType())
5659
.append("\n");
57-
5860
for (var child : node.childObjects()) {
5961
stack.push(Map.entry(child, level + 1));
6062
}
6163
}
6264
return result.toString();
6365
}
6466

65-
private void createTree(TreeNodeRelationIdentity root) {
66-
Set<Relation> visited = new HashSet<>();
67+
private TreeNodeRelationIdentity createTree(RelationIdentity relationIdentity) {
68+
TreeNodeRelationIdentity root = new TreeNodeRelationIdentity(relationIdentity, new LinkedList<>());
6769
Deque<TreeNodeRelationIdentity> stack = new ArrayDeque<>();
6870
stack.push(root);
71+
createTreeNodes(stack);
72+
return root;
73+
}
74+
75+
private void createTreeNodes(Deque<TreeNodeRelationIdentity> stack) {
76+
Set<Relation> visited = new HashSet<>();
6977
while (!stack.isEmpty()) {
70-
var parentObject = stack.poll();
78+
TreeNodeRelationIdentity parentObject = stack.poll();
7179
Collection<RelationLink> relations = tryGetSourceObjectRelations(parentObject);
72-
TreeNodeRelationIdentity childObject;
73-
for (RelationLink relation : relations) {
74-
var entityClass = classBySimpleName.get(relation.getTargetType());
75-
var childRelationIdentity = entityManager.find(entityClass, relation.getTargetId());
76-
childObject = new TreeNodeRelationIdentity(childRelationIdentity, new LinkedList<>());
77-
var r = new Relation(parentObject.object(), childObject.object());
78-
if (!visited.contains(r)) {
79-
parentObject.childObjects().add(childObject);
80-
visited.add(r);
81-
stack.add(childObject);
82-
}
83-
}
80+
relations.forEach(relation -> addNode(stack, relation, parentObject, visited));
8481
}
8582
}
8683

87-
@PostConstruct
88-
public void configure() {
89-
Set<Class<RelationIdentity>> classesImplementingInterface = findClassesImplementingInterface();
90-
classBySimpleName = classesImplementingInterface.stream()
91-
.collect(Collectors.toMap(clazz -> clazz.getSimpleName() + "Type", Function.identity()));
84+
private void addNode(Deque<TreeNodeRelationIdentity> stack, RelationLink relation,
85+
TreeNodeRelationIdentity parentObject, Set<Relation> visited) {
86+
RelationIdentity childRelationIdentity = getChildRelationIdentity(relation);
87+
TreeNodeRelationIdentity childObject = new TreeNodeRelationIdentity(childRelationIdentity, new LinkedList<>());
88+
Relation parentRelation = new Relation(parentObject.object(), childObject.object());
89+
if (!visited.contains(parentRelation)) {
90+
parentObject.childObjects().add(childObject);
91+
visited.add(parentRelation);
92+
stack.add(childObject);
93+
}
9294
}
9395

96+
private RelationIdentity getChildRelationIdentity(RelationLink relation) {
97+
Class<RelationIdentity> entityClass = classBySimpleName.get(relation.getTargetType());
98+
return entityManager.find(entityClass, relation.getTargetId());
99+
}
94100

95101
private <T> Set<Class<T>> findClassesImplementingInterface() {
96102
Set<Class<T>> classes = new HashSet<>();
97-
98103
ClassPathScanningCandidateComponentProvider scanner =
99104
new ClassPathScanningCandidateComponentProvider(false);
100-
101105
scanner.addIncludeFilter(new AssignableTypeFilter(RelationIdentity.class));
102106
Set<BeanDefinition> candidates = scanner.findCandidateComponents("*");
103107
for (BeanDefinition candidate : candidates) {
104-
try {
105-
Class<T> clazz = (Class<T>) Class.forName(candidate.getBeanClassName());
106-
if (!clazz.isInterface() && !Modifier.isAbstract(clazz.getModifiers())) {
107-
classes.add(clazz);
108-
}
109-
} catch (ClassNotFoundException e) {
110-
log.error("Class not found: {}", candidate.getBeanClassName());
111-
throw new RuntimeException("Class is not found. Finding classes is ended");
112-
}
108+
findRelationIdentities(candidate, classes);
113109
}
114-
115110
return classes;
116111
}
117112

113+
private <T> void findRelationIdentities(BeanDefinition candidate, Set<Class<T>> classes) {
114+
try {
115+
Class<T> clazz = (Class<T>) Class.forName(candidate.getBeanClassName());
116+
if (!clazz.isInterface() && !Modifier.isAbstract(clazz.getModifiers())) {
117+
classes.add(clazz);
118+
}
119+
} catch (ClassNotFoundException e) {
120+
log.error("Class not found: {}", candidate.getBeanClassName());
121+
throw new RuntimeException("Class is not found. Finding classes is ended");
122+
}
123+
}
124+
118125
private Collection<RelationLink> tryGetSourceObjectRelations(TreeNodeRelationIdentity root) {
119126
try {
120127
return relationService.findRelationBySourceObject(root.object());
121128
} catch (NoRelationDaoFoundException e) {
122-
log.info("No relations found for root with id {} and type {}", root.object().getId(), root.object().getType());
123-
return List.of();
129+
log.info("No relations found for root with id {} and type {}", root.object().getId(),
130+
root.object().getType());
131+
return Collections.emptyList();
124132
}
125133
}
126134

testing/src/test/java/at/test/drm/ApplicationIntegrationTest.java

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -131,13 +131,16 @@ void shouldPrintRelations() {
131131
relationService.createRelation(first, third);
132132
relationService.createRelation(second, third);
133133

134-
Assertions.assertThat(dynamicRelationsPrintService.printRelations(first)).isEqualTo("""
134+
String actual = dynamicRelationsPrintService.printRelations(first);
135+
System.out.println(actual);
136+
Assertions.assertThat(actual).isEqualTo("""
135137
AnnotationTestType
136138
AnnotationTest3Type
137139
AnnotationTest2Type
138140
AnnotationTest3Type
139141
""");
140142
}
143+
141144
@Test
142145
void shouldPrintRelationsWithCyclicRelations() {
143146
var first = new AnnotationTest();
@@ -153,11 +156,11 @@ void shouldPrintRelationsWithCyclicRelations() {
153156
relationService.createRelation(third, second);
154157

155158
Assertions.assertThat(dynamicRelationsPrintService.printRelations(first)).isEqualTo("""
156-
AnnotationTestType
157-
AnnotationTest3Type
158-
AnnotationTest2Type
159-
AnnotationTest2Type
160-
AnnotationTest3Type
161-
""");
159+
AnnotationTestType
160+
AnnotationTest3Type
161+
AnnotationTest2Type
162+
AnnotationTest2Type
163+
AnnotationTest3Type
164+
""");
162165
}
163166
}

0 commit comments

Comments
 (0)