Skip to content

Commit c1f4170

Browse files
committed
Refactor AssociationLinkerType to include ancestor path logic
1 parent 4b7eb5c commit c1f4170

File tree

11 files changed

+109
-79
lines changed

11 files changed

+109
-79
lines changed

doma-core/src/main/java/org/seasar/doma/jdbc/aggregate/AbstractAggregateStrategyType.java

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
*/
1616
package org.seasar.doma.jdbc.aggregate;
1717

18-
import java.util.Comparator;
1918
import java.util.List;
2019
import java.util.Objects;
2120
import org.seasar.doma.jdbc.entity.EntityType;
@@ -34,22 +33,7 @@ protected AbstractAggregateStrategyType(
3433
this.root = Objects.requireNonNull(root);
3534
this.tableAlias = Objects.requireNonNull(tableAlias);
3635
Objects.requireNonNull(associationLinkerTypes);
37-
this.associationLinkerTypes = sortAssociationLinkerTypes(associationLinkerTypes);
38-
}
39-
40-
/**
41-
* Sorts a list of {@code AssociationLinkerType} objects in descending order based on their depth.
42-
*
43-
* @param associationLinkerTypes the list of {@code AssociationLinkerType} objects to be sorted
44-
* @return a sorted list of {@code AssociationLinkerType} objects in descending order of their
45-
* depth
46-
*/
47-
private static List<AssociationLinkerType<?, ?>> sortAssociationLinkerTypes(
48-
List<AssociationLinkerType<?, ?>> associationLinkerTypes) {
49-
Comparator<AssociationLinkerType<?, ?>> reversedComparator =
50-
Comparator.<AssociationLinkerType<?, ?>>comparingInt(AssociationLinkerType::getDepth)
51-
.reversed();
52-
return associationLinkerTypes.stream().sorted(reversedComparator).toList();
36+
this.associationLinkerTypes = associationLinkerTypes;
5337
}
5438

5539
@Override

doma-core/src/main/java/org/seasar/doma/jdbc/aggregate/AggregateCommand.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,8 @@ private void associate(
9090
Map<String, LinkableEntity> associationCandidate) {
9191
for (AssociationLinkerType<?, ?> linkerType :
9292
aggregateStrategyType.getAssociationLinkerTypes()) {
93-
LinkableEntity source = associationCandidate.get(linkerType.getSourceName());
94-
LinkableEntity target = associationCandidate.get(linkerType.getTargetName());
93+
LinkableEntity source = associationCandidate.get(linkerType.getAncestorPath());
94+
LinkableEntity target = associationCandidate.get(linkerType.getPropertyPath());
9595
if (source == null || target == null) {
9696
continue;
9797
}
@@ -106,7 +106,7 @@ private void associate(
106106
if (newEntity != null) {
107107
cache.replace(source.key(), newEntity);
108108
associationCandidate.replace(
109-
linkerType.getSourceName(), new LinkableEntity(source.key(), newEntity));
109+
linkerType.getAncestorPath(), new LinkableEntity(source.key(), newEntity));
110110
}
111111
combinations.add(keyPair);
112112
}

doma-core/src/main/java/org/seasar/doma/jdbc/aggregate/AssociationLinkerType.java

Lines changed: 25 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,8 @@
1515
*/
1616
package org.seasar.doma.jdbc.aggregate;
1717

18-
import java.util.Arrays;
1918
import java.util.Objects;
2019
import java.util.function.BiFunction;
21-
import java.util.stream.Collectors;
2220
import org.seasar.doma.jdbc.entity.EntityType;
2321

2422
/**
@@ -32,29 +30,26 @@ public class AssociationLinkerType<S, T> {
3230
private final String propertyPath;
3331
private final String tableAlias;
3432
private final EntityType<S> source;
35-
private final String sourceName;
33+
private final String ancestorPath;
3634
private final EntityType<T> target;
37-
private final String targetName;
38-
private final int depth;
35+
private final int propertyPathDepth;
3936
private final BiFunction<S, T, S> linker;
4037

4138
private AssociationLinkerType(
39+
String ancestorPath,
4240
String propertyPath,
41+
int propertyPathDepth,
4342
String tableAlias,
4443
EntityType<S> source,
45-
String sourceName,
4644
EntityType<T> target,
47-
String targetName,
48-
int depth,
4945
BiFunction<S, T, S> linker) {
50-
this.propertyPath = Objects.requireNonNull(propertyPath);
51-
this.tableAlias = Objects.requireNonNull(tableAlias);
52-
this.source = Objects.requireNonNull(source);
53-
this.sourceName = Objects.requireNonNull(sourceName);
54-
this.target = Objects.requireNonNull(target);
55-
this.targetName = Objects.requireNonNull(targetName);
56-
this.depth = depth;
57-
this.linker = Objects.requireNonNull(linker);
46+
this.ancestorPath = ancestorPath;
47+
this.propertyPath = propertyPath;
48+
this.propertyPathDepth = propertyPathDepth;
49+
this.tableAlias = tableAlias;
50+
this.source = source;
51+
this.target = target;
52+
this.linker = linker;
5853
}
5954

6055
public String getPropertyPath() {
@@ -69,47 +64,37 @@ public EntityType<S> getSource() {
6964
return source;
7065
}
7166

72-
public String getSourceName() {
73-
return sourceName;
67+
public String getAncestorPath() {
68+
return ancestorPath;
7469
}
7570

7671
public EntityType<T> getTarget() {
7772
return target;
7873
}
7974

80-
public String getTargetName() {
81-
return targetName;
82-
}
83-
84-
public int getDepth() {
85-
return depth;
75+
public int getPropertyPathDepth() {
76+
return propertyPathDepth;
8677
}
8778

8879
public BiFunction<S, T, S> getLinker() {
8980
return linker;
9081
}
9182

9283
public static <S, T> AssociationLinkerType<S, T> of(
84+
String ancestorPath,
9385
String propertyPath,
86+
int propertyPathDepth,
9487
String tableAlias,
9588
EntityType<S> source,
9689
EntityType<T> target,
97-
BiFunction<S, T, S> function) {
98-
99-
String sourceName;
100-
String[] segments = propertyPath.split("\\.");
101-
102-
if (segments.length == 0) {
103-
throw new IllegalArgumentException("propertyPath");
104-
} else if (segments.length == 1) {
105-
sourceName = "";
106-
} else {
107-
sourceName = Arrays.stream(segments, 0, segments.length - 1).collect(Collectors.joining("."));
108-
}
109-
110-
int depth = segments.length;
111-
90+
BiFunction<S, T, S> linker) {
91+
Objects.requireNonNull(ancestorPath);
92+
Objects.requireNonNull(propertyPath);
93+
Objects.requireNonNull(tableAlias);
94+
Objects.requireNonNull(source);
95+
Objects.requireNonNull(target);
96+
Objects.requireNonNull(linker);
11297
return new AssociationLinkerType<>(
113-
propertyPath, tableAlias, source, sourceName, target, propertyPath, depth, function);
98+
ancestorPath, propertyPath, propertyPathDepth, tableAlias, source, target, linker);
11499
}
115100
}

doma-core/src/main/java/org/seasar/doma/jdbc/aggregate/LinkableEntityPoolProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ private void collectColumnNames(
142142
collectColumnNames(
143143
map,
144144
associationLinkerType.getTarget(),
145-
associationLinkerType.getTargetName(),
145+
associationLinkerType.getPropertyPath(),
146146
associationLinkerType.getTableAlias());
147147
}
148148
}

doma-core/src/main/java/org/seasar/doma/message/Message.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -994,6 +994,8 @@ public enum Message implements MessageResource {
994994
DOMA4486(
995995
"The field \"{0}\" in class \"{1}\" was found, but it is not annotated with @Association."),
996996
DOMA4487("An element annotated with @AggregateStrategy must not extend other interfaces."),
997+
DOMA4488(
998+
"To specify propertyPath=\"{0}\", a separate definition of @AssociationLinker(propertyPath=\"{1}\") is required."),
997999

9981000
// other
9991001
DOMA5001(

doma-processor/src/main/java/org/seasar/doma/internal/apt/generator/AggregateStrategyTypeGenerator.java

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -85,14 +85,16 @@ private void printConstructor() {
8585
while (iter.hasNext()) {
8686
AssociationLinkerMeta linkerMeta = iter.next();
8787
iprint(
88-
"%1$s.of(\"%2$s\", \"%3$s\", %4$s, %5$s, %6$s.%7$s)",
89-
AssociationLinkerType.class,
90-
linkerMeta.propertyPath(),
91-
linkerMeta.tableAlias(),
92-
linkerMeta.source().getTypeCode(),
93-
linkerMeta.target().getTypeCode(),
94-
linkerMeta.classElement(),
95-
linkerMeta.filedElement());
88+
"%1$s.of(\"%2$s\", \"%3$s\", %4$s, \"%5$s\", %6$s, %7$s, %8$s.%9$s)",
89+
/* 1 */ AssociationLinkerType.class,
90+
/* 2 */ linkerMeta.ancestorPath(),
91+
/* 3 */ linkerMeta.propertyPath(),
92+
/* 4 */ linkerMeta.propertyPathDepth(),
93+
/* 5 */ linkerMeta.tableAlias(),
94+
/* 6 */ linkerMeta.source().getTypeCode(),
95+
/* 7 */ linkerMeta.target().getTypeCode(),
96+
/* 8 */ linkerMeta.classElement(),
97+
/* 9 */ linkerMeta.filedElement());
9698
if (iter.hasNext()) {
9799
print(",");
98100
}

doma-processor/src/main/java/org/seasar/doma/internal/apt/meta/entity/AggregateStrategyMetaFactory.java

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,16 @@
1616
package org.seasar.doma.internal.apt.meta.entity;
1717

1818
import java.util.ArrayList;
19+
import java.util.Comparator;
1920
import java.util.HashSet;
2021
import java.util.LinkedList;
2122
import java.util.List;
23+
import java.util.Map;
2224
import java.util.Objects;
2325
import java.util.Optional;
2426
import java.util.Set;
27+
import java.util.function.Function;
28+
import java.util.stream.Collectors;
2529
import javax.lang.model.element.Modifier;
2630
import javax.lang.model.element.TypeElement;
2731
import javax.lang.model.element.VariableElement;
@@ -75,12 +79,31 @@ public AggregateStrategyMeta createTypeElementMeta(TypeElement typeElement) {
7579
}
7680
List<AssociationLinkerMeta> associationLinkerMetas =
7781
findAssociationLinkerMetas(typeElement, root);
78-
validateTableAliases(aggregateStrategyAnnot.getTableAliasValue(), associationLinkerMetas);
82+
validateAllPropertyPaths(associationLinkerMetas);
83+
validateAllTableAliases(aggregateStrategyAnnot.getTableAliasValue(), associationLinkerMetas);
7984
return new AggregateStrategyMeta(
8085
root, aggregateStrategyAnnot.getTableAliasValue(), associationLinkerMetas);
8186
}
8287

83-
private void validateTableAliases(
88+
private void validateAllPropertyPaths(List<AssociationLinkerMeta> associationLinkerMetas) {
89+
Map<String, AssociationLinkerMeta> map =
90+
associationLinkerMetas.stream()
91+
.collect(Collectors.toMap(AssociationLinkerMeta::propertyPath, Function.identity()));
92+
List<AssociationLinkerMeta> validationTargets =
93+
associationLinkerMetas.stream().filter(it -> it.propertyPathDepth() > 1).toList();
94+
for (AssociationLinkerMeta linkerMeta : validationTargets) {
95+
if (!map.containsKey(linkerMeta.ancestorPath())) {
96+
throw new AptException(
97+
Message.DOMA4488,
98+
linkerMeta.filedElement(),
99+
linkerMeta.associationLinkerAnnot().getAnnotationMirror(),
100+
linkerMeta.associationLinkerAnnot().getPropertyPath(),
101+
new Object[] {linkerMeta.propertyPath(), linkerMeta.ancestorPath()});
102+
}
103+
}
104+
}
105+
106+
private void validateAllTableAliases(
84107
String rootTableAlias, List<AssociationLinkerMeta> associationLinkerMetas) {
85108
Set<String> seen = new HashSet<>(1 + associationLinkerMetas.size());
86109
seen.add(rootTableAlias);
@@ -118,9 +141,13 @@ private List<AssociationLinkerMeta> findAssociationLinkerMetas(
118141
Message.DOMA4469,
119142
aggregateStrategyElement,
120143
new Object[] {aggregateStrategyElement});
144+
return associationLinkerMetas;
121145
}
122146

123-
return associationLinkerMetas;
147+
Comparator<AssociationLinkerMeta> reversedComparator =
148+
Comparator.comparingInt(AssociationLinkerMeta::propertyPathDepth).reversed();
149+
150+
return associationLinkerMetas.stream().sorted(reversedComparator).toList();
124151
}
125152

126153
private AssociationLinkerAnnot getAssociationLinkerAnnot(VariableElement linkerElement) {
@@ -275,8 +302,22 @@ private AssociationLinkerMeta createAssociationLinkerMeta(
275302
AssociationLinkerAnnot associationLinkerAnnot,
276303
BiFunctionMeta biFunctionMeta,
277304
TypeElement aggregateStrategyElement) {
305+
String propertyPath = associationLinkerAnnot.getPropertyPathValue();
306+
String[] segments = propertyPath.split("\\.");
307+
int propertyPathDepth = segments.length;
308+
String ancestorPath;
309+
if (propertyPathDepth == 0) {
310+
throw new AptIllegalStateException("propertyPath=" + propertyPath);
311+
} else if (propertyPathDepth == 1) {
312+
ancestorPath = "";
313+
} else {
314+
ancestorPath = propertyPath.substring(0, propertyPath.lastIndexOf('.'));
315+
}
278316
return new AssociationLinkerMeta(
317+
associationLinkerAnnot,
318+
ancestorPath,
279319
associationLinkerAnnot.getPropertyPathValue(),
320+
propertyPathDepth,
280321
associationLinkerAnnot.getTableAliasValue(),
281322
biFunctionMeta.source,
282323
biFunctionMeta.target,

doma-processor/src/main/java/org/seasar/doma/internal/apt/meta/entity/AssociationLinkerMeta.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,30 @@
1515
*/
1616
package org.seasar.doma.internal.apt.meta.entity;
1717

18+
import java.util.Objects;
1819
import javax.lang.model.element.TypeElement;
1920
import javax.lang.model.element.VariableElement;
21+
import org.seasar.doma.internal.apt.annot.AssociationLinkerAnnot;
2022
import org.seasar.doma.internal.apt.cttype.EntityCtType;
2123

2224
public record AssociationLinkerMeta(
25+
AssociationLinkerAnnot associationLinkerAnnot,
26+
String ancestorPath,
2327
String propertyPath,
28+
int propertyPathDepth,
2429
String tableAlias,
2530
EntityCtType source,
2631
EntityCtType target,
2732
TypeElement classElement,
28-
VariableElement filedElement) {}
33+
VariableElement filedElement) {
34+
35+
public AssociationLinkerMeta {
36+
Objects.requireNonNull(associationLinkerAnnot);
37+
Objects.requireNonNull(propertyPath);
38+
Objects.requireNonNull(tableAlias);
39+
Objects.requireNonNull(source);
40+
Objects.requireNonNull(target);
41+
Objects.requireNonNull(classElement);
42+
Objects.requireNonNull(filedElement);
43+
}
44+
}

doma-processor/src/test/resources/org/seasar/doma/internal/apt/processor/aggregate/AggregateStrategyProcessorTest_ChildEntityStrategy.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ public final class _ChildEntityStrategy extends org.seasar.doma.jdbc.aggregate.A
1212

1313
private _ChildEntityStrategy() {
1414
super(org.seasar.doma.internal.apt.processor.aggregate._ChildEntity.getSingletonInternal(), "c", java.util.List.of(
15-
org.seasar.doma.jdbc.aggregate.AssociationLinkerType.of("dept", "d", org.seasar.doma.internal.apt.processor.aggregate._ChildEntity.getSingletonInternal(), org.seasar.doma.internal.apt.processor.aggregate._Dept.getSingletonInternal(), org.seasar.doma.internal.apt.processor.aggregate.ChildEntityStrategy.dept),
16-
org.seasar.doma.jdbc.aggregate.AssociationLinkerType.of("emp", "e", org.seasar.doma.internal.apt.processor.aggregate._ChildEntity.getSingletonInternal(), org.seasar.doma.internal.apt.processor.aggregate._Emp.getSingletonInternal(), org.seasar.doma.internal.apt.processor.aggregate.ChildEntityStrategy.emp)
15+
org.seasar.doma.jdbc.aggregate.AssociationLinkerType.of("", "dept", 1, "d", org.seasar.doma.internal.apt.processor.aggregate._ChildEntity.getSingletonInternal(), org.seasar.doma.internal.apt.processor.aggregate._Dept.getSingletonInternal(), org.seasar.doma.internal.apt.processor.aggregate.ChildEntityStrategy.dept),
16+
org.seasar.doma.jdbc.aggregate.AssociationLinkerType.of("", "emp", 1, "e", org.seasar.doma.internal.apt.processor.aggregate._ChildEntity.getSingletonInternal(), org.seasar.doma.internal.apt.processor.aggregate._Emp.getSingletonInternal(), org.seasar.doma.internal.apt.processor.aggregate.ChildEntityStrategy.emp)
1717
));
1818
}
1919

doma-processor/src/test/resources/org/seasar/doma/internal/apt/processor/aggregate/AggregateStrategyProcessorTest_DeptStrategy.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ public final class _DeptStrategy extends org.seasar.doma.jdbc.aggregate.Abstract
1212

1313
private _DeptStrategy() {
1414
super(org.seasar.doma.internal.apt.processor.aggregate._Dept.getSingletonInternal(), "d", java.util.List.of(
15-
org.seasar.doma.jdbc.aggregate.AssociationLinkerType.of("employees", "e", org.seasar.doma.internal.apt.processor.aggregate._Dept.getSingletonInternal(), org.seasar.doma.internal.apt.processor.aggregate._Emp.getSingletonInternal(), org.seasar.doma.internal.apt.processor.aggregate.DeptStrategy.dept),
16-
org.seasar.doma.jdbc.aggregate.AssociationLinkerType.of("employees.address", "a", org.seasar.doma.internal.apt.processor.aggregate._Emp.getSingletonInternal(), org.seasar.doma.internal.apt.processor.aggregate._Address.getSingletonInternal(), org.seasar.doma.internal.apt.processor.aggregate.DeptStrategy.address)
15+
org.seasar.doma.jdbc.aggregate.AssociationLinkerType.of("employees", "employees.address", 2, "a", org.seasar.doma.internal.apt.processor.aggregate._Emp.getSingletonInternal(), org.seasar.doma.internal.apt.processor.aggregate._Address.getSingletonInternal(), org.seasar.doma.internal.apt.processor.aggregate.DeptStrategy.address),
16+
org.seasar.doma.jdbc.aggregate.AssociationLinkerType.of("", "employees", 1, "e", org.seasar.doma.internal.apt.processor.aggregate._Dept.getSingletonInternal(), org.seasar.doma.internal.apt.processor.aggregate._Emp.getSingletonInternal(), org.seasar.doma.internal.apt.processor.aggregate.DeptStrategy.dept)
1717
));
1818
}
1919

0 commit comments

Comments
 (0)