Skip to content

Commit bb81f25

Browse files
authored
Add MatcherOperatorRegistry and MatcherOperatorRetriever (#1237)
1 parent 06e81c3 commit bb81f25

File tree

12 files changed

+304
-113
lines changed

12 files changed

+304
-113
lines changed

fixture-monkey-api/src/main/java/com/navercorp/fixturemonkey/api/introspector/JavaArbitraryIntrospector.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@
3030

3131
import com.navercorp.fixturemonkey.api.arbitrary.JavaTypeArbitraryGeneratorSet;
3232
import com.navercorp.fixturemonkey.api.generator.ArbitraryGeneratorContext;
33-
import com.navercorp.fixturemonkey.api.introspector.ArbitraryIntrospector;
34-
import com.navercorp.fixturemonkey.api.introspector.ArbitraryIntrospectorResult;
3533
import com.navercorp.fixturemonkey.api.matcher.Matcher;
3634
import com.navercorp.fixturemonkey.api.property.Property;
3735
import com.navercorp.fixturemonkey.api.type.Types;

fixture-monkey-api/src/main/java/com/navercorp/fixturemonkey/api/matcher/AssignableTypeMatcher.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,8 @@ public boolean match(Property property) {
3737
Class<?> propertyType = Types.getActualType(property.getType());
3838
return this.type.isAssignableFrom(propertyType);
3939
}
40+
41+
public Class<?> getAnchorType() {
42+
return this.type;
43+
}
4044
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
/*
2+
* Fixture Monkey
3+
*
4+
* Copyright (c) 2021-present NAVER Corp.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
20+
package com.navercorp.fixturemonkey.api.matcher;
21+
22+
import java.util.ArrayList;
23+
import java.util.Collections;
24+
import java.util.Comparator;
25+
import java.util.HashMap;
26+
import java.util.List;
27+
import java.util.Map;
28+
import java.util.concurrent.atomic.AtomicInteger;
29+
import java.util.stream.Collectors;
30+
31+
import com.navercorp.fixturemonkey.api.property.Property;
32+
import com.navercorp.fixturemonkey.api.type.Types;
33+
import com.navercorp.fixturemonkey.api.type.Types.UnidentifiableType;
34+
35+
public final class DefaultMatcherOperatorContainer<T>
36+
implements MatcherOperatorRegistry<T>, MatcherOperatorRetriever<T> {
37+
private final AtomicInteger sequenceIssuer = new AtomicInteger(0);
38+
private final List<PriorityMatcherOperator<T>> typeUnknownIntrospectors = new ArrayList<>();
39+
private final Map<Class<?>, List<PriorityMatcherOperator<T>>> typeAwareIntrospectors = new HashMap<>();
40+
private final Map<Class<?>, List<PriorityMatcherOperator<T>>> typeAssignableIntrospectors = new HashMap<>();
41+
42+
@Override
43+
public void addFirst(MatcherOperator<T> matcherOperator) {
44+
addInternal(matcherOperator, true);
45+
}
46+
47+
@Override
48+
public void addLast(MatcherOperator<T> matcherOperator) {
49+
addInternal(matcherOperator, false);
50+
}
51+
52+
@Override
53+
public List<MatcherOperator<T>> getListByProperty(Property property) {
54+
Class<?> propertyType = Types.getActualType(property.getType());
55+
List<PriorityMatcherOperator<T>> acc = new ArrayList<>(typeUnknownIntrospectors);
56+
57+
if (propertyType != UnidentifiableType.class) {
58+
for (Map.Entry<Class<?>, List<PriorityMatcherOperator<T>>> e : typeAssignableIntrospectors.entrySet()) {
59+
Class<?> anchorType = e.getKey();
60+
if (anchorType.isAssignableFrom(propertyType)) {
61+
acc.addAll(e.getValue());
62+
}
63+
}
64+
65+
acc.addAll(typeAwareIntrospectors.getOrDefault(propertyType, Collections.emptyList()));
66+
}
67+
68+
return acc.stream()
69+
.sorted(Comparator.comparingInt(PriorityMatcherOperator::getPriority))
70+
.map(op -> (MatcherOperator<T>)op)
71+
.collect(Collectors.toList());
72+
}
73+
74+
@Override
75+
public List<MatcherOperator<T>> getList() {
76+
List<PriorityMatcherOperator<T>> acc = new ArrayList<>(typeUnknownIntrospectors);
77+
typeAwareIntrospectors.values().forEach(acc::addAll);
78+
typeAssignableIntrospectors.values().forEach(acc::addAll);
79+
80+
return acc.stream()
81+
.sorted(Comparator.comparingInt(PriorityMatcherOperator::getPriority))
82+
.map(op -> (MatcherOperator<T>)op)
83+
.collect(Collectors.toList());
84+
}
85+
86+
private void addInternal(MatcherOperator<T> matcherOperator, boolean prepend) {
87+
int seq = sequenceIssuer.incrementAndGet();
88+
int sequence = prepend ? -seq : seq;
89+
90+
Matcher matcher = matcherOperator.getMatcher();
91+
T operator = matcherOperator.getOperator();
92+
93+
PriorityMatcherOperator<T> priorityMatcherOperator = new PriorityMatcherOperator<>(
94+
matcher,
95+
operator,
96+
sequence
97+
);
98+
99+
if (matcher instanceof ExactTypeMatcher) {
100+
Class<?> type = ((ExactTypeMatcher)matcher).getType();
101+
typeAwareIntrospectors.computeIfAbsent(type, k -> new ArrayList<>()).add(priorityMatcherOperator);
102+
} else if (matcher instanceof AssignableTypeMatcher) {
103+
Class<?> anchorType = ((AssignableTypeMatcher)matcher).getAnchorType();
104+
typeAssignableIntrospectors.computeIfAbsent(anchorType, k -> new ArrayList<>())
105+
.add(priorityMatcherOperator);
106+
} else {
107+
typeUnknownIntrospectors.add(priorityMatcherOperator);
108+
}
109+
}
110+
}

fixture-monkey-api/src/main/java/com/navercorp/fixturemonkey/api/matcher/ExactTypeMatcher.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ public ExactTypeMatcher(Class<?> type) {
3232
this.type = type;
3333
}
3434

35+
public Class<?> getType() {
36+
return this.type;
37+
}
38+
3539
@Override
3640
public boolean match(Property property) {
3741
return this.type == Types.getActualType(property.getType());
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Fixture Monkey
3+
*
4+
* Copyright (c) 2021-present NAVER Corp.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
package com.navercorp.fixturemonkey.api.matcher;
20+
21+
import static org.apiguardian.api.API.Status.EXPERIMENTAL;
22+
23+
import org.apiguardian.api.API;
24+
25+
@API(since = "1.1.16", status = EXPERIMENTAL)
26+
public interface MatcherOperatorRegistry<T> {
27+
28+
void addFirst(MatcherOperator<T> matcherOperator);
29+
30+
void addLast(MatcherOperator<T> matcherOperator);
31+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Fixture Monkey
3+
*
4+
* Copyright (c) 2021-present NAVER Corp.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
package com.navercorp.fixturemonkey.api.matcher;
20+
21+
import java.util.List;
22+
23+
import com.navercorp.fixturemonkey.api.property.Property;
24+
25+
public interface MatcherOperatorRetriever<T> {
26+
27+
List<MatcherOperator<T>> getList();
28+
29+
List<MatcherOperator<T>> getListByProperty(Property property);
30+
}

fixture-monkey-api/src/main/java/com/navercorp/fixturemonkey/api/matcher/PriorityMatcherOperator.java

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,11 @@
2424

2525
/**
2626
* A class that represents a matcher operator with a priority.
27+
* Priority may be negative or positive. {@link DefaultMatcherOperatorContainer}
2728
* This class extends {@link MatcherOperator} and adds a priority field.
2829
* This class is intended for internal use only.
2930
*
31+
*
3032
* @param <T> the type of the operator
3133
* @since 1.1.15
3234
*/
@@ -40,7 +42,6 @@ public PriorityMatcherOperator(
4042
int priority
4143
) {
4244
super(matcher, operator);
43-
checkPriority(priority);
4445
this.priority = priority;
4546
}
4647

@@ -52,16 +53,4 @@ public PriorityMatcherOperator(
5253
public int getPriority() {
5354
return priority;
5455
}
55-
56-
/**
57-
* Checks if the priority is valid.
58-
*
59-
* @param priority the priority to be checked
60-
* @throws IllegalArgumentException if the priority is less than 0
61-
*/
62-
private void checkPriority(int priority) {
63-
if (priority < 0) {
64-
throw new IllegalArgumentException("Priority must be greater than or equal to 0");
65-
}
66-
}
6756
}

0 commit comments

Comments
 (0)