Skip to content

Commit c457e94

Browse files
committed
Replace RestrictionLookup by a Map
Now that the inheritance distance lookup is not necessary anymore, a simple Map is fully sufficient. This also removes the non-API class from the API of the API-classes and makes restriction chains easily testable from downstream code.
1 parent d0c12df commit c457e94

File tree

8 files changed

+63
-410
lines changed

8 files changed

+63
-410
lines changed

src/javacordIntegTest/groovy/net/kautler/command/integ/test/javacord/restriction/ProducedRestrictionIntegTest.groovy

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,19 @@ import javax.enterprise.inject.Produces
2222
import javax.enterprise.inject.Vetoed
2323

2424
import net.kautler.command.api.CommandContext
25+
import net.kautler.command.api.CommandHandler
2526
import net.kautler.command.api.annotation.RestrictedTo
2627
import net.kautler.command.api.event.javacord.CommandNotAllowedEventJavacord
2728
import net.kautler.command.api.restriction.Restriction
2829
import net.kautler.command.integ.test.javacord.PingIntegTest
2930
import net.kautler.command.integ.test.spock.AddBean
30-
import net.kautler.command.restriction.RestrictionLookup
3131
import org.javacord.api.entity.channel.ServerTextChannel
3232
import org.javacord.api.entity.message.Message
3333
import spock.lang.Specification
3434
import spock.lang.Subject
3535
import spock.util.concurrent.BlockingVariable
3636

37-
@Subject(RestrictionLookup)
37+
@Subject(CommandHandler)
3838
class ProducedRestrictionIntegTest extends Specification {
3939
@AddBean(RestrictionProducer)
4040
@AddBean(PingCommand)

src/main/java/net/kautler/command/api/CommandHandler.java

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,16 @@
1616

1717
package net.kautler.command.api;
1818

19-
import net.kautler.command.Internal;
20-
import net.kautler.command.api.CommandContextTransformer.InPhase;
21-
import net.kautler.command.api.CommandContextTransformer.Phase;
22-
import net.kautler.command.api.event.javacord.CommandNotAllowedEventJavacord;
23-
import net.kautler.command.api.event.javacord.CommandNotFoundEventJavacord;
24-
import net.kautler.command.api.parameter.ParameterConverter;
25-
import net.kautler.command.api.restriction.Restriction;
26-
import net.kautler.command.restriction.RestrictionLookup;
27-
import net.kautler.command.util.lazy.LazyReferenceBySupplier;
28-
import org.apache.logging.log4j.Logger;
19+
import java.util.AbstractMap.SimpleImmutableEntry;
20+
import java.util.Collection;
21+
import java.util.Map;
22+
import java.util.Map.Entry;
23+
import java.util.Optional;
24+
import java.util.concurrent.ConcurrentHashMap;
25+
import java.util.concurrent.ExecutorService;
26+
import java.util.concurrent.Executors;
27+
import java.util.regex.Matcher;
28+
import java.util.regex.Pattern;
2929

3030
import javax.annotation.PostConstruct;
3131
import javax.annotation.PreDestroy;
@@ -37,20 +37,21 @@
3737
import javax.enterprise.inject.Instance;
3838
import javax.enterprise.util.TypeLiteral;
3939
import javax.inject.Inject;
40-
import java.util.AbstractMap.SimpleImmutableEntry;
41-
import java.util.Collection;
42-
import java.util.Collections;
43-
import java.util.Map;
44-
import java.util.Map.Entry;
45-
import java.util.Optional;
46-
import java.util.concurrent.ConcurrentHashMap;
47-
import java.util.concurrent.ExecutorService;
48-
import java.util.concurrent.Executors;
49-
import java.util.regex.Matcher;
50-
import java.util.regex.Pattern;
40+
41+
import net.kautler.command.Internal;
42+
import net.kautler.command.api.CommandContextTransformer.InPhase;
43+
import net.kautler.command.api.CommandContextTransformer.Phase;
44+
import net.kautler.command.api.event.javacord.CommandNotAllowedEventJavacord;
45+
import net.kautler.command.api.event.javacord.CommandNotFoundEventJavacord;
46+
import net.kautler.command.api.parameter.ParameterConverter;
47+
import net.kautler.command.api.restriction.Restriction;
48+
import net.kautler.command.util.lazy.LazyReferenceBySupplier;
49+
import org.apache.logging.log4j.Logger;
5150

5251
import static java.lang.String.format;
52+
import static java.util.Collections.emptyMap;
5353
import static java.util.concurrent.CompletableFuture.runAsync;
54+
import static java.util.function.Function.identity;
5455
import static java.util.stream.Collectors.joining;
5556
import static java.util.stream.Collectors.toList;
5657
import static java.util.stream.Collectors.toMap;
@@ -96,7 +97,7 @@ public abstract class CommandHandler<M> {
9697
private LazyReferenceBySupplier<Map<String, Command<? super M>>> commandByAlias =
9798
new LazyReferenceBySupplier<>(() -> {
9899
logger.info("Got no commands injected");
99-
return Collections.emptyMap();
100+
return emptyMap();
100101
});
101102

102103
/**
@@ -108,10 +109,10 @@ public abstract class CommandHandler<M> {
108109
/**
109110
* The available restrictions for this command handler.
110111
*/
111-
private LazyReferenceBySupplier<RestrictionLookup<M>> availableRestrictions =
112+
private LazyReferenceBySupplier<Map<Class<?>, Restriction<? super M>>> availableRestrictions =
112113
new LazyReferenceBySupplier<>(() -> {
113114
logger.info("Got no restrictions injected");
114-
return new RestrictionLookup<>();
115+
return emptyMap();
115116
});
116117

117118
/**
@@ -167,14 +168,14 @@ protected void doSetCommandContextTransformers(
167168
*/
168169
protected void doSetAvailableRestrictions(Instance<Restriction<? super M>> availableRestrictions) {
169170
this.availableRestrictions = new LazyReferenceBySupplier<>(() -> {
170-
RestrictionLookup<M> result = new RestrictionLookup<>();
171-
Collection<Restriction<? super M>> restrictions = availableRestrictions.stream().peek(restriction ->
172-
logger.debug("Got restriction {} injected", () -> restriction.getClass().getName())
173-
).collect(toList());
174-
result.addAllRestrictions(restrictions);
171+
Map<Class<?>, Restriction<? super M>> result = availableRestrictions
172+
.stream()
173+
.peek(restriction ->
174+
logger.debug("Got restriction {} injected", () -> restriction.getRealClass().getName()))
175+
.collect(toMap(Restriction::getRealClass, identity()));
175176
logger.info("Got {} restriction{} injected",
176-
restrictions::size,
177-
() -> restrictions.size() == 1 ? "" : 's');
177+
result::size,
178+
() -> result.size() == 1 ? "" : 's');
178179
return result;
179180
});
180181
}
@@ -568,14 +569,14 @@ private boolean fastForward(CommandContext<M> commandContext, Phase phase) {
568569
}
569570

570571
if (((phase == BEFORE_PREFIX_COMPUTATION) || (phase == BEFORE_ALIAS_AND_PARAMETER_STRING_COMPUTATION))
571-
&& commandContext.getAlias().isPresent()) {
572+
&& commandContext.getAlias().isPresent()) {
572573
logger.debug("Fast forwarding {} to command computation", commandContext);
573574
computeCommand(commandContext);
574575
return true;
575576
}
576577

577578
if ((phase == BEFORE_PREFIX_COMPUTATION)
578-
&& commandContext.getPrefix().isPresent()) {
579+
&& commandContext.getPrefix().isPresent()) {
579580
logger.debug("Fast forwarding {} to alias and parameter string computation", commandContext);
580581
computeAliasAndParameterString(commandContext);
581582
return true;

src/main/java/net/kautler/command/api/restriction/RestrictionChainElement.java

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@
1616

1717
package net.kautler.command.api.restriction;
1818

19-
import net.kautler.command.api.CommandContext;
20-
import net.kautler.command.restriction.RestrictionLookup;
21-
19+
import java.util.Map;
2220
import java.util.Objects;
2321
import java.util.StringJoiner;
2422
import java.util.stream.Stream;
2523

24+
import net.kautler.command.api.CommandContext;
25+
2626
import static java.lang.String.format;
2727
import static java.util.Objects.requireNonNull;
2828

@@ -59,8 +59,9 @@ public RestrictionChainElement(Class<? extends Restriction<?>> restriction) {
5959
* @param <M> the class of the message in the command context
6060
* @return whether the command triggered by the given command context should be allowed or not
6161
*/
62-
public <M> boolean isCommandAllowed(CommandContext<M> commandContext, RestrictionLookup<? super M> availableRestrictions) {
63-
Restriction<? super M> restriction = availableRestrictions.getRestriction(this.restriction);
62+
public <M> boolean isCommandAllowed(CommandContext<M> commandContext,
63+
Map<Class<?>, Restriction<? super M>> availableRestrictions) {
64+
Restriction<? super M> restriction = availableRestrictions.get(this.restriction);
6465
if (restriction == null) {
6566
throw new IllegalArgumentException(format("The restriction '%s' was not found in the given available restrictions '%s'", this.restriction, availableRestrictions));
6667
}
@@ -171,7 +172,8 @@ private AndCombination(RestrictionChainElement left, RestrictionChainElement rig
171172
}
172173

173174
@Override
174-
public <M> boolean isCommandAllowed(CommandContext<M> commandContext, RestrictionLookup<? super M> availableRestrictions) {
175+
public <M> boolean isCommandAllowed(CommandContext<M> commandContext,
176+
Map<Class<?>, Restriction<? super M>> availableRestrictions) {
175177
return Stream.of(left, right)
176178
.allMatch(chainElement -> chainElement.isCommandAllowed(commandContext, availableRestrictions));
177179
}
@@ -185,8 +187,8 @@ public boolean equals(Object obj) {
185187
return false;
186188
}
187189
AndCombination that = (AndCombination) obj;
188-
return Objects.equals(left, that.left) &&
189-
Objects.equals(right, that.right);
190+
return Objects.equals(left, that.left)
191+
&& Objects.equals(right, that.right);
190192
}
191193

192194
@Override
@@ -230,7 +232,8 @@ private OrCombination(RestrictionChainElement left, RestrictionChainElement righ
230232
}
231233

232234
@Override
233-
public <M> boolean isCommandAllowed(CommandContext<M> commandContext, RestrictionLookup<? super M> availableRestrictions) {
235+
public <M> boolean isCommandAllowed(CommandContext<M> commandContext,
236+
Map<Class<?>, Restriction<? super M>> availableRestrictions) {
234237
return Stream.of(left, right)
235238
.anyMatch(chainElement -> chainElement.isCommandAllowed(commandContext, availableRestrictions));
236239
}
@@ -244,8 +247,8 @@ public boolean equals(Object obj) {
244247
return false;
245248
}
246249
OrCombination that = (OrCombination) obj;
247-
return Objects.equals(left, that.left) &&
248-
Objects.equals(right, that.right);
250+
return Objects.equals(left, that.left)
251+
&& Objects.equals(right, that.right);
249252
}
250253

251254
@Override
@@ -281,7 +284,8 @@ private Negation(RestrictionChainElement negated) {
281284
}
282285

283286
@Override
284-
public <M> boolean isCommandAllowed(CommandContext<M> commandContext, RestrictionLookup<? super M> availableRestrictions) {
287+
public <M> boolean isCommandAllowed(CommandContext<M> commandContext,
288+
Map<Class<?>, Restriction<? super M>> availableRestrictions) {
285289
return !negated.isCommandAllowed(commandContext, availableRestrictions);
286290
}
287291

src/main/java/net/kautler/command/restriction/RestrictionLookup.java

Lines changed: 0 additions & 89 deletions
This file was deleted.

src/pitest/java/net/kautler/test/pitest/ExplicitMutationFilter.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public class ExplicitMutationFilter implements MutationInterceptor {
6060
new ExplicitMutationFilterDetails(
6161
"net.kautler.command.api.restriction.RestrictionChainElement",
6262
"isCommandAllowed",
63-
"(Lnet/kautler/command/api/CommandContext;Lnet/kautler/command/restriction/RestrictionLookup;)Z",
63+
"(Lnet/kautler/command/api/CommandContext;Ljava/util/Map;)Z",
6464
"org.pitest.mutationtest.engine.gregor.mutators.InlineConstantMutator",
6565
"Substituted 2 with 3"),
6666
// giving a 3 instead of 2 element array to Objects.hash can be killed, but we do not want to
@@ -94,7 +94,7 @@ public class ExplicitMutationFilter implements MutationInterceptor {
9494
new ExplicitMutationFilterDetails(
9595
"net.kautler.command.api.CommandHandler",
9696
"lambda$doSetAvailableRestrictions",
97-
"(Ljavax/enterprise/inject/Instance;)Lnet/kautler/command/restriction/RestrictionLookup;",
97+
"(Ljavax/enterprise/inject/Instance;)Ljava/util/Map;",
9898
"org.pitest.mutationtest.engine.gregor.mutators.InlineConstantMutator",
9999
"Substituted 2 with 3"),
100100
// giving a 3 instead of 2 element array to logger.info cannot be killed

src/test/groovy/net/kautler/command/api/CommandHandlerTest.groovy

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -210,10 +210,9 @@ class CommandHandlerTest extends Specification {
210210
.findAll { it.level == DEBUG }
211211
availableRestrictions
212212
.stream()
213-
.limit(amount)
214213
.each { restriction ->
215214
assert debugEvents.any {
216-
it.message.formattedMessage == "Got restriction ${restriction.getClass().name} injected"
215+
it.message.formattedMessage == "Got restriction ${restriction.realClass.name} injected"
217216
}
218217
} ?: true
219218

@@ -259,7 +258,6 @@ class CommandHandlerTest extends Specification {
259258
.findAll { it.level == DEBUG }
260259
commands
261260
.stream()
262-
.limit(amount)
263261
.each { command ->
264262
assert debugEvents.any {
265263
it.message.formattedMessage == "Got command ${command.getClass().name} injected"

0 commit comments

Comments
 (0)