Skip to content

Commit 9cd92d0

Browse files
committed
Ensure invariants for the abstract base restrictions
1 parent ef8c8e6 commit 9cd92d0

File tree

6 files changed

+325
-7
lines changed

6 files changed

+325
-7
lines changed

config/pmd/pmd.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,11 @@
139139
</property>
140140
</properties>
141141
</rule>
142+
<rule ref="category/java/design.xml/TooManyMethods">
143+
<properties>
144+
<property name="maxmethods" value="15"/>
145+
</properties>
146+
</rule>
142147
<rule ref="category/java/documentation.xml"/>
143148
<rule ref="category/java/documentation.xml/CommentSize">
144149
<properties>

config/spotbugs/spotbugs-exclude.xml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,20 @@
6464
<Bug pattern="BC_UNCONFIRMED_CAST"/>
6565
</Match>
6666

67+
<Match>
68+
<Or>
69+
<Class name="net.kautler.command.api.restriction.javacord.ChannelJavacord"/>
70+
<Class name="net.kautler.command.api.restriction.javacord.RoleJavacord"/>
71+
<Class name="net.kautler.command.api.restriction.javacord.ServerJavacord"/>
72+
<Class name="net.kautler.command.api.restriction.javacord.UserJavacord"/>
73+
</Or>
74+
<Or>
75+
<Method name="ensureAtLeastOneConditionIsSet" params="" returns="void"/>
76+
<Method name="ensureCaseSensitiveIfNameIsNotSet" params="" returns="void"/>
77+
</Or>
78+
<Bug pattern="WEM_WEAK_EXCEPTION_MESSAGING"/>
79+
</Match>
80+
6781
<Match>
6882
<Or>
6983
<And>

src/main/java/net/kautler/command/api/restriction/javacord/ChannelJavacord.java

Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,11 @@
2121
import org.javacord.api.entity.message.Message;
2222

2323
import javax.enterprise.context.ApplicationScoped;
24+
import java.util.StringJoiner;
2425
import java.util.regex.Pattern;
2526

2627
import static java.lang.Boolean.FALSE;
28+
import static java.lang.String.format;
2729

2830
/**
2931
* A restriction that allows a command in certain channels and is evaluated by the Javacord command handler.
@@ -100,16 +102,89 @@ protected ChannelJavacord(Pattern channelPattern) {
100102
* @param channelPattern the pattern against which the channel name is matched
101103
* to determine where a command should be allowed
102104
*/
103-
private ChannelJavacord(long channelId, String channelName, boolean caseSensitive, Pattern channelPattern) {
105+
private ChannelJavacord(long channelId, String channelName,
106+
boolean caseSensitive, Pattern channelPattern) {
104107
this.channelId = channelId;
105108
this.channelName = channelName;
106109
this.caseSensitive = caseSensitive;
107110
this.channelPattern = channelPattern;
111+
ensureInvariants();
112+
}
113+
114+
/**
115+
* Checks the invariants of this instance and raises
116+
* an {@link IllegalStateException} if they are violated.
117+
*/
118+
private void ensureInvariants() {
119+
ensureAtMostOneConditionIsSet();
120+
ensureAtLeastOneConditionIsSet();
121+
ensureCaseSensitiveIfNameIsNotSet();
122+
}
123+
124+
/**
125+
* Checks that at most one condition is set and raises an {@link IllegalStateException} otherwise.
126+
*/
127+
private void ensureAtMostOneConditionIsSet() {
128+
boolean channelIdSet = channelId != 0;
129+
boolean channelNameSet = channelName != null;
130+
boolean channelPatternSet = channelPattern != null;
131+
132+
boolean channelNamelySet = channelNameSet || channelPatternSet;
133+
boolean channelIdAndNamelySet = channelIdSet && channelNamelySet;
134+
boolean bothChannelNamelySet = channelNameSet && channelPatternSet;
135+
boolean multipleConditionsSet = channelIdAndNamelySet || bothChannelNamelySet;
136+
137+
if (multipleConditionsSet) {
138+
StringJoiner stringJoiner = new StringJoiner(", ");
139+
if (channelIdSet) {
140+
stringJoiner.add("channelId");
141+
}
142+
if (channelNameSet) {
143+
stringJoiner.add("channelName");
144+
}
145+
if (channelPatternSet) {
146+
stringJoiner.add("channelPattern");
147+
}
148+
throw new IllegalStateException(format(
149+
"Only one of channelId, channelName and channelPattern should be given (%s)",
150+
stringJoiner));
151+
}
152+
}
153+
154+
/**
155+
* Checks that at least one condition is set and raises an {@link IllegalStateException} otherwise.
156+
*/
157+
private void ensureAtLeastOneConditionIsSet() {
158+
boolean channelIdSet = channelId != 0;
159+
boolean channelNameSet = channelName != null;
160+
boolean channelPatternSet = channelPattern != null;
161+
162+
boolean channelNamelySet = channelNameSet || channelPatternSet;
163+
164+
boolean atLeastOneConditionSet = channelIdSet || channelNamelySet;
165+
166+
if (!atLeastOneConditionSet) {
167+
throw new IllegalStateException(
168+
"One of channelId, channelName and channelPattern should be given");
169+
}
170+
}
171+
172+
/**
173+
* Checks that {@link #caseSensitive} is {@code true} if {@link #channelName}
174+
* is not set and raises an {@link IllegalStateException} otherwise.
175+
*/
176+
private void ensureCaseSensitiveIfNameIsNotSet() {
177+
if ((channelName == null) && !caseSensitive) {
178+
throw new IllegalStateException(
179+
"If channelName is not set, caseSensitive should be true");
180+
}
108181
}
109182

110183
@Override
111184
public boolean allowCommand(Message message) {
112-
return channelName == null && channelPattern == null ? allowCommandByChannelId(message) : allowCommandByChannelName(message);
185+
return ((channelName == null) && (channelPattern == null))
186+
? allowCommandByChannelId(message)
187+
: allowCommandByChannelName(message);
113188
}
114189

115190
/**

src/main/java/net/kautler/command/api/restriction/javacord/RoleJavacord.java

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,12 @@
2424

2525
import javax.enterprise.context.ApplicationScoped;
2626
import java.util.Collection;
27+
import java.util.StringJoiner;
2728
import java.util.regex.Pattern;
2829
import java.util.stream.Stream;
2930

3031
import static java.lang.Boolean.FALSE;
32+
import static java.lang.String.format;
3133
import static java.util.Comparator.naturalOrder;
3234

3335
/**
@@ -166,11 +168,83 @@ private RoleJavacord(boolean exact, long roleId, String roleName, boolean caseSe
166168
this.roleName = roleName;
167169
this.caseSensitive = caseSensitive;
168170
this.rolePattern = rolePattern;
171+
ensureInvariants();
172+
}
173+
174+
/**
175+
* Checks the invariants of this instance and raises
176+
* an {@link IllegalStateException} if they are violated.
177+
*/
178+
private void ensureInvariants() {
179+
ensureAtMostOneConditionIsSet();
180+
ensureAtLeastOneConditionIsSet();
181+
ensureCaseSensitiveIfNameIsNotSet();
182+
}
183+
184+
/**
185+
* Checks that at most one condition is set and raises an {@link IllegalStateException} otherwise.
186+
*/
187+
private void ensureAtMostOneConditionIsSet() {
188+
boolean roleIdSet = roleId != 0;
189+
boolean roleNameSet = roleName != null;
190+
boolean rolePatternSet = rolePattern != null;
191+
192+
boolean roleNamelySet = roleNameSet || rolePatternSet;
193+
boolean roleIdAndNamelySet = roleIdSet && roleNamelySet;
194+
boolean bothRoleNamelySet = roleNameSet && rolePatternSet;
195+
boolean multipleConditionsSet = roleIdAndNamelySet || bothRoleNamelySet;
196+
197+
if (multipleConditionsSet) {
198+
StringJoiner stringJoiner = new StringJoiner(", ");
199+
if (roleIdSet) {
200+
stringJoiner.add("roleId");
201+
}
202+
if (roleNameSet) {
203+
stringJoiner.add("roleName");
204+
}
205+
if (rolePatternSet) {
206+
stringJoiner.add("rolePattern");
207+
}
208+
throw new IllegalStateException(format(
209+
"Only one of roleId, roleName and rolePattern should be given (%s)",
210+
stringJoiner));
211+
}
212+
}
213+
214+
/**
215+
* Checks that at least one condition is set and raises an {@link IllegalStateException} otherwise.
216+
*/
217+
private void ensureAtLeastOneConditionIsSet() {
218+
boolean roleIdSet = roleId != 0;
219+
boolean roleNameSet = roleName != null;
220+
boolean rolePatternSet = rolePattern != null;
221+
222+
boolean roleNamelySet = roleNameSet || rolePatternSet;
223+
224+
boolean atLeastOneConditionSet = roleIdSet || roleNamelySet;
225+
226+
if (!atLeastOneConditionSet) {
227+
throw new IllegalStateException(
228+
"One of roleId, roleName and rolePattern should be given");
229+
}
230+
}
231+
232+
/**
233+
* Checks that {@link #caseSensitive} is {@code true} if {@link #roleName}
234+
* is not set and raises an {@link IllegalStateException} otherwise.
235+
*/
236+
private void ensureCaseSensitiveIfNameIsNotSet() {
237+
if ((roleName == null) && !caseSensitive) {
238+
throw new IllegalStateException(
239+
"If roleName is not set, caseSensitive should be true");
240+
}
169241
}
170242

171243
@Override
172244
public boolean allowCommand(Message message) {
173-
return roleName == null && rolePattern == null ? allowCommandByRoleId(message) : allowCommandByRoleName(message);
245+
return ((roleName == null) && (rolePattern == null))
246+
? allowCommandByRoleId(message)
247+
: allowCommandByRoleName(message);
174248
}
175249

176250
/**

src/main/java/net/kautler/command/api/restriction/javacord/ServerJavacord.java

Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@
2222
import org.javacord.api.entity.message.Message;
2323

2424
import javax.enterprise.context.ApplicationScoped;
25+
import java.util.StringJoiner;
2526
import java.util.regex.Pattern;
2627

2728
import static java.lang.Boolean.FALSE;
29+
import static java.lang.String.format;
2830

2931
/**
3032
* A restriction that allows a command in certain servers and is evaluated by the Javacord command handler.
@@ -101,16 +103,89 @@ protected ServerJavacord(Pattern serverPattern) {
101103
* @param serverPattern the pattern against which the server name is matched
102104
* to determine where a command should be allowed
103105
*/
104-
private ServerJavacord(long serverId, String serverName, boolean caseSensitive, Pattern serverPattern) {
106+
private ServerJavacord(long serverId, String serverName,
107+
boolean caseSensitive, Pattern serverPattern) {
105108
this.serverId = serverId;
106109
this.serverName = serverName;
107110
this.caseSensitive = caseSensitive;
108111
this.serverPattern = serverPattern;
112+
ensureInvariants();
113+
}
114+
115+
/**
116+
* Checks the invariants of this instance and raises
117+
* an {@link IllegalStateException} if they are violated.
118+
*/
119+
private void ensureInvariants() {
120+
ensureAtMostOneConditionIsSet();
121+
ensureAtLeastOneConditionIsSet();
122+
ensureCaseSensitiveIfNameIsNotSet();
123+
}
124+
125+
/**
126+
* Checks that at most one condition is set and raises an {@link IllegalStateException} otherwise.
127+
*/
128+
private void ensureAtMostOneConditionIsSet() {
129+
boolean serverIdSet = serverId != 0;
130+
boolean serverNameSet = serverName != null;
131+
boolean serverPatternSet = serverPattern != null;
132+
133+
boolean serverNamelySet = serverNameSet || serverPatternSet;
134+
boolean serverIdAndNamelySet = serverIdSet && serverNamelySet;
135+
boolean bothServerNamelySet = serverNameSet && serverPatternSet;
136+
boolean multipleConditionsSet = serverIdAndNamelySet || bothServerNamelySet;
137+
138+
if (multipleConditionsSet) {
139+
StringJoiner stringJoiner = new StringJoiner(", ");
140+
if (serverIdSet) {
141+
stringJoiner.add("serverId");
142+
}
143+
if (serverNameSet) {
144+
stringJoiner.add("serverName");
145+
}
146+
if (serverPatternSet) {
147+
stringJoiner.add("serverPattern");
148+
}
149+
throw new IllegalStateException(format(
150+
"Only one of serverId, serverName and serverPattern should be given (%s)",
151+
stringJoiner));
152+
}
153+
}
154+
155+
/**
156+
* Checks that at least one condition is set and raises an {@link IllegalStateException} otherwise.
157+
*/
158+
private void ensureAtLeastOneConditionIsSet() {
159+
boolean serverIdSet = serverId != 0;
160+
boolean serverNameSet = serverName != null;
161+
boolean serverPatternSet = serverPattern != null;
162+
163+
boolean serverNamelySet = serverNameSet || serverPatternSet;
164+
165+
boolean atLeastOneConditionSet = serverIdSet || serverNamelySet;
166+
167+
if (!atLeastOneConditionSet) {
168+
throw new IllegalStateException(
169+
"One of serverId, serverName and serverPattern should be given");
170+
}
171+
}
172+
173+
/**
174+
* Checks that {@link #caseSensitive} is {@code true} if {@link #serverName}
175+
* is not set and raises an {@link IllegalStateException} otherwise.
176+
*/
177+
private void ensureCaseSensitiveIfNameIsNotSet() {
178+
if ((serverName == null) && !caseSensitive) {
179+
throw new IllegalStateException(
180+
"If serverName is not set, caseSensitive should be true");
181+
}
109182
}
110183

111184
@Override
112185
public boolean allowCommand(Message message) {
113-
return serverName == null && serverPattern == null ? allowCommandByServerId(message) : allowCommandByServerName(message);
186+
return ((serverName == null) && (serverPattern == null))
187+
? allowCommandByServerId(message)
188+
: allowCommandByServerName(message);
114189
}
115190

116191
/**

0 commit comments

Comments
 (0)