diff --git a/bans-api/src/main/java/space/arim/libertybans/api/punish/Punishment.java b/bans-api/src/main/java/space/arim/libertybans/api/punish/Punishment.java index 149cc6d8..feb0973f 100644 --- a/bans-api/src/main/java/space/arim/libertybans/api/punish/Punishment.java +++ b/bans-api/src/main/java/space/arim/libertybans/api/punish/Punishment.java @@ -19,7 +19,6 @@ package space.arim.libertybans.api.punish; -import space.arim.libertybans.api.ConsoleOperator; import space.arim.libertybans.api.Operator; import space.arim.omnibus.util.concurrent.ReactionStage; @@ -148,13 +147,11 @@ default boolean isExpired(Clock clock) { return clock.instant().compareTo(getEndDate()) > 0; } - /** - * Gets undo information about this punishment. - *
- * - * @return If the punishment is active or expired, is empty - */ - Optional undoAttachment(); + Optional getUndoOperator(); + + Optional getUndoReason(); + + Optional getUndoDate(); /** * Enforces this punishment.
@@ -185,21 +182,8 @@ default ReactionStage enforcePunishment() { */ ReactionStage enforcePunishment(EnforcementOptions enforcementOptions); - /** - * Undoes and "unenforces" this punishment assuming it active and in the - * database.
- * If the punishment was active then was removed, the future yields - * {@code true}, else {@code false}.
- *
- * Unenforcement implies purging of this punishment from any local caches. - * Additionally, any relevant broadcast messages will be sent to players. - * - * @return a future which yields {@code true} if this punishment existed and was - * removed and unenforced, {@code false} otherwise - */ - default ReactionStage undoPunishment(Operator operator, String reason) { - return undoPunishment(operator, reason, enforcementOptionsBuilder().build()); - } + //TODO: Write Javadoc + UndoBuilder undo(); /** * Undoes and "unenforces" this punishment assuming it active and in the @@ -209,30 +193,12 @@ default ReactionStage undoPunishment(Operator operator, String reason) *
* Unenforcement implies purging of this punishment from any local caches. * Additionally, any relevant broadcast messages will be sent to players. - * - * @param enforcementOptions the enforcement options. Can be used to disable unenforcement entirely - * @return a future which yields {@code true} if this punishment existed and was - * removed and unenforced, {@code false} otherwise - */ - ReactionStage undoPunishment(Operator operator, String reason, EnforcementOptions enforcementOptions); - - /** - * Undoes and "unenforces" this punishment assuming it active and in the - * database.
- * If the punishment was active then was removed, the future yields - * {@code true}, else {@code false}.
- *
- * Unenforcement implies purging of this punishment from any local caches. - * Additionally, any relevant broadcast messages will be sent to players. - * + * * @return a future which yields {@code true} if this punishment existed and was * removed and unenforced, {@code false} otherwise - * - * @deprecated Use {@link Punishment#undoPunishment(Operator, String)} instead. */ - @Deprecated - default ReactionStage undoPunishment() { - return undoPunishment(ConsoleOperator.INSTANCE, "No information"); + default ReactionStage undoPunishment() { + return undo().enforcementOptions(enforcementOptionsBuilder().build()).undoPunishment(); } /** @@ -247,12 +213,9 @@ default ReactionStage undoPunishment() { * @param enforcementOptions the enforcement options. Can be used to disable unenforcement entirely * @return a future which yields {@code true} if this punishment existed and was * removed and unenforced, {@code false} otherwise - * - * @deprecated Use {@link Punishment#undoPunishment(Operator, String, EnforcementOptions)} instead. */ - @Deprecated - default ReactionStage undoPunishment(EnforcementOptions enforcementOptions) { - return undoPunishment(ConsoleOperator.INSTANCE, "No information", enforcementOptions); + default ReactionStage undoPunishment(EnforcementOptions enforcementOptions) { + return undo().enforcementOptions(enforcementOptions).undoPunishment(); } /** diff --git a/bans-api/src/main/java/space/arim/libertybans/api/punish/PunishmentRevoker.java b/bans-api/src/main/java/space/arim/libertybans/api/punish/PunishmentRevoker.java index da6529f6..76b8d16b 100644 --- a/bans-api/src/main/java/space/arim/libertybans/api/punish/PunishmentRevoker.java +++ b/bans-api/src/main/java/space/arim/libertybans/api/punish/PunishmentRevoker.java @@ -19,7 +19,9 @@ package space.arim.libertybans.api.punish; -import space.arim.libertybans.api.*; +import space.arim.libertybans.api.CompositeVictim; +import space.arim.libertybans.api.PunishmentType; +import space.arim.libertybans.api.Victim; import java.util.List; @@ -32,7 +34,7 @@ * removed. See {@link space.arim.libertybans.api.punish} for a description of * active and historical punishments.
*
- * Note that {@link Punishment#undoPunishment(Operator, String)} should be used instead of a + * Note that {@link Punishment#undoPunishment()} should be used instead of a * revocation order if a punishment instance is already obtained. * * @author A248 @@ -47,18 +49,18 @@ public interface PunishmentRevoker { * @param type the type of the punishment to undo * @return a revocation order using the ID and type */ - RevocationOrder revokeByIdAndType(long id, PunishmentType type, Operator operator, String reason); + RevocationOrder revokeByIdAndType(long id, PunishmentType type); /** * Gets a {@link RevocationOrder} to undo a punishment according to its ID.
*
* When the punishment type is known, - * {@link #revokeByIdAndType(long, PunishmentType, Operator, String)} should be used. + * {@link #revokeByIdAndType(long, PunishmentType)} should be used. * * @param id the id of the punishment to undo * @return a revocation order using the ID */ - RevocationOrder revokeById(long id, Operator operator, String reason); + RevocationOrder revokeById(long id); /** * Gets a {@link RevocationOrder} to undo a punishment by its type and victim. @@ -72,77 +74,9 @@ public interface PunishmentRevoker { * * @param type the punishment type * @param victim the victim whose punishment to undo - * @param operator The undoing operator - * @param reason The undo reason * @return a revocation order using the type and victim */ - RevocationOrder revokeByTypeAndVictim(PunishmentType type, Victim victim, Operator operator, String reason); - - /** - * Gets a {@link RevocationOrder} to undo a punishment by its type and victim, - * trying multiple victims until one of them is found to be punished.
- *
- * The process for undoing the punishment is identical to - * {@link #revokeByTypeAndVictim(PunishmentType, Victim, Operator, String)}, except that multiple - * victims are tried: if the first victim is punished, that punishment is undone, - * if second victim is punished, that punishment is undone, et cetera. - * - * @param type the punishment type - * @param victims the victims, one of whose punishments will be undone - * @return a revocation order using the type and victim - * @throws IllegalArgumentException if the list of victims is empty - */ - RevocationOrder revokeByTypeAndPossibleVictims(PunishmentType type, List victims, Operator operator, String reason); - - /** - * Gets a {@link RevocationOrder} to undo a punishment by its ID and type. - * - * @param id the id of the punishment to undo - * @param type the type of the punishment to undo - * @return a revocation order using the ID and type - * - * @deprecated Use {@link PunishmentRevoker#revokeByIdAndType(long, PunishmentType, Operator, String)} instead. - */ - @Deprecated - default RevocationOrder revokeByIdAndType(long id, PunishmentType type) { - return revokeByIdAndType(id, type, ConsoleOperator.INSTANCE, "No information"); - } - - /** - * Gets a {@link RevocationOrder} to undo a punishment according to its ID.
- *
- * When the punishment type is known, - * - * @param id the id of the punishment to undo - * @return a revocation order using the ID - * - * @deprecated Use {@link PunishmentRevoker#revokeById(long, Operator, String)} instead. - */ - @Deprecated - default RevocationOrder revokeById(long id) { - return revokeById(id, ConsoleOperator.INSTANCE, "No information"); - } - - /** - * Gets a {@link RevocationOrder} to undo a punishment by its type and victim. - * This is commonly be used for singular punishments (bans and mutes), relying on - * the fact that a single victim cannot have more than 1 such punishment.
- *
- * For non-singular punishments, or for a {@code CompositeVictim} with wildcards - * ({@link CompositeVictim#WILDCARD_UUID} or {@link CompositeVictim#WILDCARD_ADDRESS}) - * multiple punishments may match the given criteria. In this case, it is explicitly - * unspecified which punishment is revoked. - * - * @param type the punishment type - * @param victim the victim whose punishment to undo - * @return a revocation order using the type and victim - * - * @deprecated Use {@link PunishmentRevoker#revokeByTypeAndVictim(PunishmentType, Victim, Operator, String)} instead. - */ - @Deprecated - default RevocationOrder revokeByTypeAndVictim(PunishmentType type, Victim victim) { - return revokeByTypeAndVictim(type, victim, ConsoleOperator.INSTANCE, "No information"); - } + RevocationOrder revokeByTypeAndVictim(PunishmentType type, Victim victim); /** * Gets a {@link RevocationOrder} to undo a punishment by its type and victim, @@ -157,13 +91,8 @@ default RevocationOrder revokeByTypeAndVictim(PunishmentType type, Victim victim * @param victims the victims, one of whose punishments will be undone * @return a revocation order using the type and victim * @throws IllegalArgumentException if the list of victims is empty - * - * @deprecated Use {@link PunishmentRevoker#revokeByTypeAndPossibleVictims(PunishmentType, List, Operator, String)} instead. */ - @Deprecated - default RevocationOrder revokeByTypeAndPossibleVictims(PunishmentType type, List victims) { - return revokeByTypeAndPossibleVictims(type, victims, ConsoleOperator.INSTANCE, "No information"); - } + RevocationOrder revokeByTypeAndPossibleVictims(PunishmentType type, List victims); /** * Totally expunges a punishment according to its ID. This uses the most efficient means to completely diff --git a/bans-api/src/main/java/space/arim/libertybans/api/punish/RevocationOrder.java b/bans-api/src/main/java/space/arim/libertybans/api/punish/RevocationOrder.java index e9c7070b..10278269 100644 --- a/bans-api/src/main/java/space/arim/libertybans/api/punish/RevocationOrder.java +++ b/bans-api/src/main/java/space/arim/libertybans/api/punish/RevocationOrder.java @@ -39,20 +39,6 @@ */ public interface RevocationOrder extends EnforcementOptionsFactory { - /** - * Gets the operator who is revoking the punishment - * - * @return the operator responsible for the revocation - */ - Operator getOperator(); - - /** - * Gets the reason for the revocation - * - * @return the reason for the revocation - */ - String getReason(); - /** * Gets the ID of the punishment which will be revoked, or none if no ID is * known @@ -77,6 +63,16 @@ public interface RevocationOrder extends EnforcementOptionsFactory { */ Optional> getVictims(); + Optional getOperator(); + + Optional getReason(); + + RevocationOrder operator(Operator operator); + + RevocationOrder operatorAndReason(Operator operator, String reason); + + RevocationOrder clearOperatorAndReason(); + /** * Revokes the punishment matching this revocation order, and "unenforces" it. *
diff --git a/bans-api/src/main/java/space/arim/libertybans/api/punish/UndoAttachment.java b/bans-api/src/main/java/space/arim/libertybans/api/punish/UndoAttachment.java deleted file mode 100644 index f341cf36..00000000 --- a/bans-api/src/main/java/space/arim/libertybans/api/punish/UndoAttachment.java +++ /dev/null @@ -1,19 +0,0 @@ -package space.arim.libertybans.api.punish; - -import space.arim.libertybans.api.Operator; - -import java.time.Instant; - -/** - * This interface encapsulates additional information present for historical punishments - * that have been undone. - */ -public interface UndoAttachment { - - Operator operator(); - - String reason(); - - Instant time(); - -} diff --git a/bans-api/src/main/java/space/arim/libertybans/api/punish/UndoBuilder.java b/bans-api/src/main/java/space/arim/libertybans/api/punish/UndoBuilder.java new file mode 100644 index 00000000..93e13e0c --- /dev/null +++ b/bans-api/src/main/java/space/arim/libertybans/api/punish/UndoBuilder.java @@ -0,0 +1,26 @@ +package space.arim.libertybans.api.punish; + +import space.arim.libertybans.api.Operator; +import space.arim.omnibus.util.concurrent.ReactionStage; + +import java.time.Instant; + +/** + * This interface encapsulates additional information present for historical punishments + * that have been undone. + */ +public interface UndoBuilder { + + UndoBuilder operator(Operator operator); + + UndoBuilder operatorAndReason(Operator operator, String reason); + + UndoBuilder clearOperatorAndReason(); + + UndoBuilder enforcementOptions(EnforcementOptions enforcementOptions); + + ReactionStage undoPunishment(); + + ReactionStage undoAndGetPunishment(); + +} diff --git a/bans-api/src/test/java/space/arim/libertybans/api/example/WikiExamples.java b/bans-api/src/test/java/space/arim/libertybans/api/example/WikiExamples.java index 219bb23a..ad4cabd8 100644 --- a/bans-api/src/test/java/space/arim/libertybans/api/example/WikiExamples.java +++ b/bans-api/src/test/java/space/arim/libertybans/api/example/WikiExamples.java @@ -98,7 +98,7 @@ public ReactionStage revokeBanFor(UUID bannedPlayer, Operator undoOperator, S PunishmentRevoker revoker = libertyBans.getRevoker(); // Relies on the fact a player victim can only have 1 active ban - RevocationOrder revocationOrder = revoker.revokeByTypeAndVictim(PunishmentType.BAN, PlayerVictim.of(bannedPlayer), undoOperator, reason); + RevocationOrder revocationOrder = revoker.revokeByTypeAndVictim(PunishmentType.BAN, PlayerVictim.of(bannedPlayer)); return revocationOrder.undoPunishment().thenAccept((undone) -> { if (undone) { // ban existed and was undone diff --git a/bans-core/src/main/java/space/arim/libertybans/core/commands/UnpunishCommands.java b/bans-core/src/main/java/space/arim/libertybans/core/commands/UnpunishCommands.java index e3de27ca..c8237894 100644 --- a/bans-core/src/main/java/space/arim/libertybans/core/commands/UnpunishCommands.java +++ b/bans-core/src/main/java/space/arim/libertybans/core/commands/UnpunishCommands.java @@ -175,12 +175,13 @@ private CompletionStage performUndo(Operator operator, String reason sender().sendMessage(((WarnRemoval) section).notANumber().replaceText("%ID_ARG%", idArg)); return completedFuture(null); } - revocationOrder = revoker.revokeByIdAndType(id, type, operator, reason); + revocationOrder = revoker.revokeByIdAndType(id, type) + .operatorAndReason(operator, reason); } else { assert type.isSingular() : type; // Try to revoke this punishment for either the simple victim or composite wildcard victim CompositeVictim compositeWildcard = new AsCompositeWildcard().apply(victim); - revocationOrder = revoker.revokeByTypeAndPossibleVictims(type, List.of(victim, compositeWildcard), operator, reason); + revocationOrder = revoker.revokeByTypeAndPossibleVictims(type, List.of(victim, compositeWildcard)).operatorAndReason(operator, reason); id = -1; } return fireWithTimeout(new PardonEventImpl(operator, victim, type, reason)).thenCompose((event) -> { diff --git a/bans-core/src/main/java/space/arim/libertybans/core/config/Formatter.java b/bans-core/src/main/java/space/arim/libertybans/core/config/Formatter.java index 802e569c..3acc3eec 100644 --- a/bans-core/src/main/java/space/arim/libertybans/core/config/Formatter.java +++ b/bans-core/src/main/java/space/arim/libertybans/core/config/Formatter.java @@ -35,7 +35,7 @@ import space.arim.libertybans.api.Victim; import space.arim.libertybans.api.punish.EscalationTrack; import space.arim.libertybans.api.punish.Punishment; -import space.arim.libertybans.api.punish.UndoAttachment; +import space.arim.libertybans.api.punish.UndoBuilder; import space.arim.libertybans.api.scope.ServerScope; import space.arim.libertybans.core.service.Time; import space.arim.libertybans.core.punish.MiscUtil; @@ -107,7 +107,7 @@ public CentralisedFuture getPunishmentMessage(Punishment punishment) @Override public CentralisedFuture formatWithPunishment(ComponentText componentText, Punishment punishment) { - UndoAttachment undoAttachment = punishment.undoAttachment().orElse(null); + UndoBuilder undoAttachment = punishment.undoAttachment().orElse(null); Map> futureReplacements = new EnumMap<>(FutureReplaceable.class); for (FutureReplaceable futureReplaceable : FutureReplaceable.values()) { if (componentText.contains(futureReplaceable.getVariable())) { @@ -161,7 +161,7 @@ String getVariable() { } } - private Map getSimpleReplacements(Punishment punishment, UndoAttachment undoAttachment) { + private Map getSimpleReplacements(Punishment punishment, UndoBuilder undoAttachment) { MessagesConfig.Formatting formatting = messages().formatting(); Map simpleReplacements = new EnumMap<>(SimpleReplaceable.class); @@ -284,7 +284,7 @@ private CentralisedFuture getFutureReplacement(FutureReplaceable futureR return switch (futureReplaceable) { case VICTIM -> formatVictim(punishment.getVictim()); case OPERATOR -> formatOperator(punishment.getOperator()); - case UNOPERATOR -> formatOperator(punishment.undoAttachment().map(UndoAttachment::operator).orElse(null)); + case UNOPERATOR -> formatOperator(punishment.undoAttachment().map(UndoBuilder::operator).orElse(null)); }; } diff --git a/bans-core/src/main/java/space/arim/libertybans/core/punish/InternalRevoker.java b/bans-core/src/main/java/space/arim/libertybans/core/punish/InternalRevoker.java index 5be886c3..9ae1bda4 100644 --- a/bans-core/src/main/java/space/arim/libertybans/core/punish/InternalRevoker.java +++ b/bans-core/src/main/java/space/arim/libertybans/core/punish/InternalRevoker.java @@ -18,6 +18,7 @@ */ package space.arim.libertybans.core.punish; +import space.arim.libertybans.api.Operator; import space.arim.omnibus.util.concurrent.CentralisedFuture; import space.arim.libertybans.api.punish.Punishment; @@ -25,6 +26,10 @@ public interface InternalRevoker extends PunishmentRevoker { - CentralisedFuture undoPunishment(Punishment punishment, UndoDraft undoDraft); + default CentralisedFuture undoPunishment(Punishment punishment) { + return undoPunishment(punishment, null, null); + } + + CentralisedFuture undoPunishment(Punishment punishment, Operator operator, String reason); } diff --git a/bans-core/src/main/java/space/arim/libertybans/core/punish/PunishmentCreator.java b/bans-core/src/main/java/space/arim/libertybans/core/punish/PunishmentCreator.java index 9df4605b..903068cc 100644 --- a/bans-core/src/main/java/space/arim/libertybans/core/punish/PunishmentCreator.java +++ b/bans-core/src/main/java/space/arim/libertybans/core/punish/PunishmentCreator.java @@ -26,7 +26,6 @@ import space.arim.libertybans.api.Victim; import space.arim.libertybans.api.punish.EscalationTrack; import space.arim.libertybans.api.punish.Punishment; -import space.arim.libertybans.api.punish.UndoAttachment; import space.arim.libertybans.api.scope.ServerScope; import space.arim.libertybans.core.scope.ScopeType; diff --git a/bans-core/src/main/java/space/arim/libertybans/core/punish/RevocationOrderImpl.java b/bans-core/src/main/java/space/arim/libertybans/core/punish/RevocationOrderImpl.java index ed9f5f63..bfc578e5 100644 --- a/bans-core/src/main/java/space/arim/libertybans/core/punish/RevocationOrderImpl.java +++ b/bans-core/src/main/java/space/arim/libertybans/core/punish/RevocationOrderImpl.java @@ -35,34 +35,48 @@ class RevocationOrderImpl implements RevocationOrder, EnforcementOpts.Factory { private final Revoker revoker; - private final Operator operator; - private final String reason; private final long id; private final PunishmentType type; private final List victims; + private final Operator operator; + private final String reason; - private RevocationOrderImpl(Revoker revoker, Operator operator, String reason, long id, PunishmentType type, List victims) { + private RevocationOrderImpl(Revoker revoker, long id, PunishmentType type, List victims, Operator operator, String reason) { this.revoker = revoker; - this.operator = operator; - this.reason = reason; this.id = id; this.type = type; this.victims = victims; + this.operator = operator; + this.reason = reason; + } + + RevocationOrderImpl(Revoker revoker, long id) { + this(revoker, id, null, null, null, null); + assert getApproach() == Approach.ID; } - //TODO: Add requireNonNulls - RevocationOrderImpl(Revoker revoker, Operator operator, String reason, long id) { - this(revoker, operator, reason, id, null, null); + RevocationOrderImpl(Revoker revoker, long id, Operator operator, String reason) { + this(revoker, id, null, null, operator, reason); assert getApproach() == Approach.ID; } - RevocationOrderImpl(Revoker revoker, Operator operator, String reason, long id, PunishmentType type) { - this(revoker, operator, reason, id, Objects.requireNonNull(type, "type"), null); + RevocationOrderImpl(Revoker revoker, long id, PunishmentType type) { + this(revoker, id, Objects.requireNonNull(type, "type"), null, null, null); + assert getApproach() == Approach.ID_TYPE; + } + + RevocationOrderImpl(Revoker revoker, long id, PunishmentType type, Operator operator, String reason) { + this(revoker, id, Objects.requireNonNull(type, "type"), null, operator, reason); assert getApproach() == Approach.ID_TYPE; } - RevocationOrderImpl(Revoker revoker, Operator operator, String reason, PunishmentType type, List victims) { - this(revoker, operator, reason, -1, type, List.copyOf(victims)); + RevocationOrderImpl(Revoker revoker, PunishmentType type, List victims) { + this(revoker, -1, type, List.copyOf(victims), null, null); + assert getApproach() == Approach.TYPE_VICTIM; + } + + RevocationOrderImpl(Revoker revoker, PunishmentType type, List victims, Operator operator, String reason) { + this(revoker, -1, type, List.copyOf(victims), operator, reason); assert getApproach() == Approach.TYPE_VICTIM; } @@ -82,16 +96,6 @@ private Approach getApproach() { return Approach.ID_TYPE; } - @Override - public Operator getOperator() { - return operator; - } - - @Override - public String getReason() { - return reason; - } - @Override public Optional getID() { if (id == -1L) { @@ -110,23 +114,48 @@ public Optional> getVictims() { return Optional.ofNullable(victims); } + @Override + public Optional getOperator() { + return Optional.ofNullable(operator); + } + + @Override + public Optional getReason() { + return Optional.ofNullable(reason); + } + + @Override + public RevocationOrder operator(Operator operator) { + return new RevocationOrderImpl(revoker, id, type, victims, operator, reason); + } + + @Override + public RevocationOrder operatorAndReason(Operator operator, String reason) { + return new RevocationOrderImpl(revoker, id, type, victims, operator, reason); + } + + @Override + public RevocationOrder clearOperatorAndReason() { + return new RevocationOrderImpl(revoker, id, type, victims, null, null); + } + @Override public ReactionStage undoPunishment(EnforcementOptions enforcementOptions) { // Unenforcement needs both an ID and a type return switch (getApproach()) { - case ID -> revoker.undoPunishmentById(id, createUndoDraft()).thenCompose((type) -> { + case ID -> revoker.undoPunishmentById(id, operator, reason).thenCompose((type) -> { if (type == null) { return revoker.futuresFactory().completedFuture(false); } return unenforceAndReturnTrue(id, type, enforcementOptions); }); - case ID_TYPE -> revoker.undoPunishmentByIdAndType(id, type, createUndoDraft()).thenCompose((revoked) -> { + case ID_TYPE -> revoker.undoPunishmentByIdAndType(id, type, operator, reason).thenCompose((revoked) -> { if (!revoked) { return revoker.futuresFactory().completedFuture(false); } return unenforceAndReturnTrue(id, type, enforcementOptions); }); - case TYPE_VICTIM -> revoker.undoPunishmentByTypeAndPossibleVictims(type, victims, createUndoDraft()).thenCompose((id) -> { + case TYPE_VICTIM -> revoker.undoPunishmentByTypeAndPossibleVictims(type, victims, operator, reason).thenCompose((id) -> { if (id == null) { return revoker.futuresFactory().completedFuture(false); } @@ -154,16 +183,12 @@ public ReactionStage> undoAndGetPunishment(EnforcementOptio private ReactionStage undoAndGetPunishmentWithoutUnenforcement() { return switch (getApproach()) { - case ID -> revoker.undoAndGetPunishmentById(id, createUndoDraft()); - case ID_TYPE -> revoker.undoAndGetPunishmentByIdAndType(id, type, createUndoDraft()); - case TYPE_VICTIM -> revoker.undoAndGetPunishmentByTypeAndPossibleVictims(type, victims, createUndoDraft()); + case ID -> revoker.undoAndGetPunishmentById(id, operator, reason); + case ID_TYPE -> revoker.undoAndGetPunishmentByIdAndType(id, type, operator, reason); + case TYPE_VICTIM -> revoker.undoAndGetPunishmentByTypeAndPossibleVictims(type, victims, operator, reason); }; } - private UndoDraft createUndoDraft() { - return revoker.undoDraftCreator().create(operator, reason); - } - @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/bans-core/src/main/java/space/arim/libertybans/core/punish/Revoker.java b/bans-core/src/main/java/space/arim/libertybans/core/punish/Revoker.java index cd9b6d5b..1b5c971c 100644 --- a/bans-core/src/main/java/space/arim/libertybans/core/punish/Revoker.java +++ b/bans-core/src/main/java/space/arim/libertybans/core/punish/Revoker.java @@ -49,7 +49,6 @@ import java.util.Set; import static space.arim.libertybans.core.schema.tables.Punishments.PUNISHMENTS; -import static space.arim.libertybans.core.schema.tables.Undone.UNDONE; import static space.arim.libertybans.core.schema.tables.SimpleActive.SIMPLE_ACTIVE; import static space.arim.libertybans.core.schema.tables.SimpleHistory.SIMPLE_HISTORY; @@ -61,19 +60,17 @@ public class Revoker implements InternalRevoker { private final PunishmentCreator creator; private final GlobalEnforcement enforcement; private final Time time; - private final UndoDraftCreator undoDraftCreator; private static final Logger logger = LoggerFactory.getLogger(ThisClass.get()); @Inject public Revoker(FactoryOfTheFuture futuresFactory, Provider dbProvider, - PunishmentCreator creator, GlobalEnforcement enforcement, Time time, UndoDraftCreator undoDraftCreator) { + PunishmentCreator creator, GlobalEnforcement enforcement, Time time) { this.futuresFactory = futuresFactory; this.dbProvider = dbProvider; this.creator = creator; this.enforcement = enforcement; this.time = time; - this.undoDraftCreator = undoDraftCreator; } FactoryOfTheFuture futuresFactory() { @@ -84,37 +81,33 @@ GlobalEnforcement enforcement() { return enforcement; } - UndoDraftCreator undoDraftCreator() { - return undoDraftCreator; - } - @Override - public CentralisedFuture undoPunishment(final Punishment punishment, final UndoDraft undoDraft) { + public CentralisedFuture undoPunishment(final Punishment punishment, final Operator operator, final String reason) { if (punishment.isExpired(time.toJdkClock())) { // Already expired return futuresFactory.completedFuture(false); } - return undoPunishmentByIdAndType(punishment.getIdentifier(), punishment.getType(), undoDraft); + return undoPunishmentByIdAndType(punishment.getIdentifier(), punishment.getType(), operator, reason); } @Override - public RevocationOrder revokeByIdAndType(long id, PunishmentType type, Operator operator, String reason) { - return new RevocationOrderImpl(this, operator, reason, id, type); + public RevocationOrder revokeByIdAndType(long id, PunishmentType type) { + return new RevocationOrderImpl(this, id, type); } @Override - public RevocationOrder revokeById(long id, Operator operator, String reason) { - return new RevocationOrderImpl(this, operator, reason, id); + public RevocationOrder revokeById(long id) { + return new RevocationOrderImpl(this, id); } @Override - public RevocationOrder revokeByTypeAndVictim(PunishmentType type, Victim victim, Operator operator, String reason) { - return revokeByTypeAndPossibleVictims(type, List.of(victim), operator, reason); + public RevocationOrder revokeByTypeAndVictim(PunishmentType type, Victim victim) { + return revokeByTypeAndPossibleVictims(type, List.of(victim)); } @Override - public RevocationOrder revokeByTypeAndPossibleVictims(PunishmentType type, List victims, Operator operator, String reason) { - return new RevocationOrderImpl(this, operator, reason, type, victims); + public RevocationOrder revokeByTypeAndPossibleVictims(PunishmentType type, List victims) { + return new RevocationOrderImpl(this, type, victims); } @Override @@ -124,7 +117,7 @@ public ExpunctionOrder expungePunishment(long id) { private boolean deleteActivePunishmentByIdAndType(DSLContext context, final long id, final PunishmentType type, - final UndoDraft undoDraft) { + final Operator operator, final String reason) { final Instant currentTime = time.currentTimestamp(); var dataTable = new TableForType(type).dataTable(); @@ -138,7 +131,7 @@ private boolean deleteActivePunishmentByIdAndType(DSLContext context, return false; } context.insertInto(UNDONE) - .values(id, undoDraft.operator(), undoDraft.reason(), Instant.now()) + .values(id, operator, reason, Instant.now()) .execute(); boolean wasNotExpired = context.fetchExists(context .selectFrom(PUNISHMENTS) @@ -151,7 +144,7 @@ private boolean deleteActivePunishmentByIdAndType(DSLContext context, private Punishment deleteAndGetActivePunishmentByIdAndType(DSLContext context, final long id, final PunishmentType type, - final UndoDraft undoDraft) { + final Operator operator, final String reason) { final Instant currentTime = time.currentTimestamp(); var dataTable = new TableForType(type).dataTable(); @@ -164,7 +157,7 @@ private Punishment deleteAndGetActivePunishmentByIdAndType(DSLContext context, return null; } context.insertInto(UNDONE) - .values(id, undoDraft.operator(), undoDraft.reason(), Instant.now()) + .values(id, operator, reason, Instant.now()) .execute(); Punishment result = context .select( @@ -182,27 +175,27 @@ private Punishment deleteAndGetActivePunishmentByIdAndType(DSLContext context, return result; } - CentralisedFuture undoPunishmentByIdAndType(final long id, final PunishmentType type, final UndoDraft undoDraft) { + CentralisedFuture undoPunishmentByIdAndType(final long id, final PunishmentType type, final Operator operator, final String reason) { if (type == PunishmentType.KICK) { // Kicks are never active return futuresFactory.completedFuture(false); } return dbProvider.get().queryWithRetry((context, transaction) -> { - return deleteActivePunishmentByIdAndType(context, id, type, undoDraft); + return deleteActivePunishmentByIdAndType(context, id, type, operator, reason); }); } - CentralisedFuture undoAndGetPunishmentByIdAndType(final long id, final PunishmentType type, final UndoDraft undoDraft) { + CentralisedFuture undoAndGetPunishmentByIdAndType(final long id, final PunishmentType type, final Operator operator, final String reason) { if (type == PunishmentType.KICK) { // Kicks are never active return futuresFactory.completedFuture(null); } return dbProvider.get().queryWithRetry((context, transaction) -> { - return deleteAndGetActivePunishmentByIdAndType(context, id, type, undoDraft); + return deleteAndGetActivePunishmentByIdAndType(context, id, type, operator, reason); }); } - CentralisedFuture undoPunishmentById(final long id, final UndoDraft undoDraft) { + CentralisedFuture undoPunishmentById(final long id, final Operator operator, final String reason) { return dbProvider.get().queryWithRetry((context, transaction) -> { PunishmentType type = context .select(SIMPLE_ACTIVE.TYPE) @@ -210,14 +203,14 @@ CentralisedFuture undoPunishmentById(final long id, final UndoDr .where(SIMPLE_ACTIVE.ID.eq(id)) .fetchSingle(SIMPLE_ACTIVE.TYPE); logger.trace("type={} in undoPunishmentById", type); - if (type == null || !deleteActivePunishmentByIdAndType(context, id, type, undoDraft)) { + if (type == null || !deleteActivePunishmentByIdAndType(context, id, type, operator, reason)) { return null; } return type; }); } - CentralisedFuture undoAndGetPunishmentById(final long id, final UndoDraft undoDraft) { + CentralisedFuture undoAndGetPunishmentById(final long id, final Operator operator, final String reason) { return dbProvider.get().queryWithRetry((context, transaction) -> { PunishmentType type = context .select(SIMPLE_ACTIVE.TYPE) @@ -228,7 +221,7 @@ CentralisedFuture undoAndGetPunishmentById(final long id, final Undo if (type == null) { return null; } - return deleteAndGetActivePunishmentByIdAndType(context, id, type, undoDraft); + return deleteAndGetActivePunishmentByIdAndType(context, id, type, operator, reason); }); } @@ -250,7 +243,7 @@ public Set rejectedValues() { CentralisedFuture undoPunishmentByTypeAndPossibleVictims(final PunishmentType type, final List victims, - final UndoDraft undoDraft) { + final Operator operator, final String reason) { return dbProvider.get().queryWithRetry((context, transaction) -> { var simpleView = new TableForType(type).simpleView(); Long id = context @@ -259,7 +252,7 @@ CentralisedFuture undoPunishmentByTypeAndPossibleVictims(final PunishmentT .where(matchesAnyVictim(simpleView, victims)) .fetchAny(simpleView.id()); logger.trace("id={} in undoPunishmentByTypeAndVictim", id); - if (id == null || !deleteActivePunishmentByIdAndType(context, id, type, undoDraft)) { + if (id == null || !deleteActivePunishmentByIdAndType(context, id, type, operator, reason)) { return null; } return id; @@ -268,7 +261,7 @@ CentralisedFuture undoPunishmentByTypeAndPossibleVictims(final PunishmentT CentralisedFuture undoAndGetPunishmentByTypeAndPossibleVictims(final PunishmentType type, final List victims, - final UndoDraft undoDraft) { + final Operator operator, final String reason) { return dbProvider.get().queryWithRetry((context, transaction) -> { var simpleView = new TableForType(type).simpleView(); Long id = context @@ -280,7 +273,7 @@ CentralisedFuture undoAndGetPunishmentByTypeAndPossibleVictims(final if (id == null) { return null; } - return deleteAndGetActivePunishmentByIdAndType(context, id, type, undoDraft); + return deleteAndGetActivePunishmentByIdAndType(context, id, type, operator, reason); }); } diff --git a/bans-core/src/main/java/space/arim/libertybans/core/punish/SecurePunishment.java b/bans-core/src/main/java/space/arim/libertybans/core/punish/SecurePunishment.java index a08ecc38..0f1f8272 100644 --- a/bans-core/src/main/java/space/arim/libertybans/core/punish/SecurePunishment.java +++ b/bans-core/src/main/java/space/arim/libertybans/core/punish/SecurePunishment.java @@ -22,7 +22,6 @@ import java.time.Instant; import java.util.Objects; import java.util.Optional; -import java.util.concurrent.CompletableFuture; import java.util.function.Consumer; import space.arim.libertybans.api.punish.*; @@ -40,18 +39,22 @@ class SecurePunishment extends AbstractPunishmentBase implements Punishment, Enf private final long id; private final Instant startDate; private final Instant endDate; - private final UndoAttachment undoAttachment; + private final Operator undoOperator; + private final String undoReason; + private final Instant undoDate; SecurePunishment(SecurePunishmentCreator creator, long id, PunishmentType type, Victim victim, Operator operator, String reason, ServerScope scope, Instant startDate, Instant endDate, EscalationTrack escalationTrack, - UndoAttachment undoAttachment) { + Operator undoOperator, String undoReason, Instant undoDate) { super(type, victim, operator, reason, scope, escalationTrack); this.creator = Objects.requireNonNull(creator, "creator"); this.id = id; this.startDate = Objects.requireNonNull(startDate, "startDate"); this.endDate = Objects.requireNonNull(endDate, "endDate"); - this.undoAttachment = undoAttachment; + this.undoOperator = undoOperator; + this.undoReason = undoReason; + this.undoDate = undoDate; } @Override @@ -70,24 +73,28 @@ public Instant getEndDate() { } @Override - public Optional undoAttachment() { - return Optional.ofNullable(undoAttachment); + public Optional getUndoOperator() { + return Optional.ofNullable(undoOperator); } @Override - public CentralisedFuture enforcePunishment(EnforcementOptions enforcementOptions) { - return creator.enforcement().enforce(this, (EnforcementOpts) enforcementOptions); + public Optional getUndoReason() { + return Optional.ofNullable(undoReason); + } + + @Override + public Optional getUndoDate() { + return Optional.ofNullable(undoDate); } @Override - public ReactionStage undoPunishment(Operator operator, String reason, EnforcementOptions enforcementOptions) { - return creator.revoker().undoPunishment(this, creator.undoDraftCreator().create(operator, reason)). - thenCompose((undone) -> { - if (!undone) { - return CompletableFuture.completedFuture(false); - } - return unenforcePunishment(enforcementOptions).thenApply((ignore) -> true); - }); + public UndoBuilder undo() { + return new SecureUndoBuilder(creator, this, undoOperator, undoReason, enforcementOptionsBuilder().build()); + } + + @Override + public CentralisedFuture enforcePunishment(EnforcementOptions enforcementOptions) { + return creator.enforcement().enforce(this, (EnforcementOpts) enforcementOptions); } @Override diff --git a/bans-core/src/main/java/space/arim/libertybans/core/punish/SecurePunishmentCreator.java b/bans-core/src/main/java/space/arim/libertybans/core/punish/SecurePunishmentCreator.java index 9b972c33..4e6cc871 100644 --- a/bans-core/src/main/java/space/arim/libertybans/core/punish/SecurePunishmentCreator.java +++ b/bans-core/src/main/java/space/arim/libertybans/core/punish/SecurePunishmentCreator.java @@ -45,19 +45,14 @@ public class SecurePunishmentCreator implements PunishmentCreator { private final Provider revoker; private final Provider enforcement; private final Provider modifier; - private final SecureUndoAttachmentCreator undoAttachmentCreator; - private final UndoDraftCreator undoDraftCreator; @Inject public SecurePunishmentCreator(InternalScopeManager scopeManager, Provider revoker, - Provider enforcement, Provider modifier, - SecureUndoAttachmentCreator undoAttachmentCreator, UndoDraftCreator undoDraftCreator) { + Provider enforcement, Provider modifier) { this.scopeManager = scopeManager; this.revoker = revoker; this.enforcement = enforcement; this.modifier = modifier; - this.undoAttachmentCreator = undoAttachmentCreator; - this.undoDraftCreator = undoDraftCreator; } InternalRevoker revoker() { @@ -72,19 +67,15 @@ Modifier modifer() { return modifier.get(); } - public UndoDraftCreator undoDraftCreator() { - return undoDraftCreator; - } - @Override public Punishment createPunishment(long id, PunishmentType type, Victim victim, Operator operator, String reason, ServerScope scope, Instant start, Instant end, EscalationTrack escalationTrack) { - return new SecurePunishment(this, id, type, victim, operator, reason, scope, start, end, escalationTrack, undoAttachmentCreator.createEmptyAttachment()); + return new SecurePunishment(this, id, type, victim, operator, reason, scope, start, end, escalationTrack, null, null, null); } @Override public Punishment createPunishment(long id, PunishmentType type, Victim victim, Operator operator, String reason, ServerScope scope, Instant start, Instant end, EscalationTrack escalationTrack, Operator undoOperator, String undoReason, Instant undoDate) { - return new SecurePunishment(this, id, type, victim, operator, reason, scope, start, end, escalationTrack, undoAttachmentCreator.createUndoAttachment(undoOperator, undoReason, undoDate)); + return new SecurePunishment(this, id, type, victim, operator, reason, scope, start, end, escalationTrack, undoOperator, undoReason, undoDate); } @Override @@ -103,7 +94,7 @@ Punishment> punishmentMapperUndone() { record.value1(), record.value2(), // id, type victim, record.value6(), record.value7(), // victim, operator, reason scope, record.value9(), record.value10(), record.value11(), // scope, start, end, track - undoAttachmentCreator.createUndoAttachment(record.value13(), record.value14(), record.value15()) // undo attachment + record.value13(), record.value14(), record.value15() // undo information ); }; } @@ -122,7 +113,7 @@ public RecordMapper punishmentMapperUndone(long id) { id, /* type */ record.value1(), victim, record.value5(), record.value6(), // operator, reason scope, record.value8(), record.value9(), record.value10(), // scope, start, end, track - undoAttachmentCreator.createUndoAttachment(record.value12(), record.value13(), record.value14()) // undo attachment + record.value12(), record.value13(), record.value14() // undo attachment ); }; } @@ -164,7 +155,7 @@ Punishment> punishmentMapper(long id) { id, /* type */ record.value1(), victim, record.value5(), record.value6(), // operator, reason scope, record.value8(), record.value9(), record.value10(), // scope, start, end, track - undoAttachmentCreator.createEmptyAttachment() // undo attachment + null, null, null // undo attachment ); }; } @@ -185,7 +176,7 @@ Punishment> punishmentMapperUndone(long id, PunishmentType type) { id, type, victim, record.value4(), record.value5(), // operator, reason scope, record.value7(), record.value8(), record.value9(), // scope, start, end, track - undoAttachmentCreator.createUndoAttachment(record.value11(), record.value12(), record.value13()) // undo attachment + record.value11(), record.value12(), record.value13() // undo attachment ); }; } @@ -206,7 +197,7 @@ Punishment> punishmentMapper(long id, PunishmentType type) { id, type, victim, record.value4(), record.value5(), // operator, reason scope, record.value7(), record.value8(), record.value9(), // scope, start, end, track - undoAttachmentCreator.createEmptyAttachment() // undo attachment + null, null, null // undo attachment ); }; } @@ -235,7 +226,7 @@ Punishment> punishmentMapperForModifications(Punishment oldPunishment) { oldPunishment.getIdentifier(), oldPunishment.getType(), oldPunishment.getVictim(), oldPunishment.getOperator(), record.value1(), scope, oldPunishment.getStartDate(), record.value2(), - escalationTrack, null + escalationTrack, null, null, null ); }; } diff --git a/bans-core/src/main/java/space/arim/libertybans/core/punish/SecureUndoAttachment.java b/bans-core/src/main/java/space/arim/libertybans/core/punish/SecureUndoAttachment.java deleted file mode 100644 index fc5a1eb9..00000000 --- a/bans-core/src/main/java/space/arim/libertybans/core/punish/SecureUndoAttachment.java +++ /dev/null @@ -1,35 +0,0 @@ -package space.arim.libertybans.core.punish; - -import space.arim.libertybans.api.Operator; -import space.arim.libertybans.api.punish.UndoAttachment; - -import java.time.Instant; - -//TODO: Why is {@link SecurePunishment} called secure? Should this be called Secure too? -public class SecureUndoAttachment implements UndoAttachment { - - private final Operator operator; - private final String reason; - private final Instant time; - - SecureUndoAttachment(Operator operator, String reason, Instant time) { - this.operator = operator; - this.reason = reason; - this.time = time; - } - - @Override - public Operator operator() { - return operator; - } - - @Override - public String reason() { - return reason; - } - - @Override - public Instant time() { - return time; - } -} diff --git a/bans-core/src/main/java/space/arim/libertybans/core/punish/SecureUndoAttachmentCreator.java b/bans-core/src/main/java/space/arim/libertybans/core/punish/SecureUndoAttachmentCreator.java deleted file mode 100644 index 67681226..00000000 --- a/bans-core/src/main/java/space/arim/libertybans/core/punish/SecureUndoAttachmentCreator.java +++ /dev/null @@ -1,22 +0,0 @@ -package space.arim.libertybans.core.punish; - -import jakarta.inject.Singleton; -import org.jooq.RecordMapper; -import space.arim.libertybans.api.Operator; -import space.arim.libertybans.api.punish.UndoAttachment; - -import java.time.Instant; - -@Singleton -public class SecureUndoAttachmentCreator { - - public UndoAttachment createEmptyAttachment() { - return null; - } - - public UndoAttachment createUndoAttachment(Operator operator, String reason, Instant time) { - if(operator == null && reason == null && time == null) return null; - return new SecureUndoAttachment(operator, reason, time); - } - -} diff --git a/bans-core/src/main/java/space/arim/libertybans/core/punish/SecureUndoBuilder.java b/bans-core/src/main/java/space/arim/libertybans/core/punish/SecureUndoBuilder.java new file mode 100644 index 00000000..c17c53ba --- /dev/null +++ b/bans-core/src/main/java/space/arim/libertybans/core/punish/SecureUndoBuilder.java @@ -0,0 +1,67 @@ +package space.arim.libertybans.core.punish; + +import space.arim.libertybans.api.Operator; +import space.arim.libertybans.api.punish.EnforcementOptions; +import space.arim.libertybans.api.punish.Punishment; +import space.arim.libertybans.api.punish.UndoBuilder; +import space.arim.omnibus.util.concurrent.ReactionStage; + +import java.time.Instant; +import java.util.concurrent.CompletableFuture; + +//TODO: Why is {@link SecurePunishment} called secure? Should this be called Secure too? +public class SecureUndoBuilder implements UndoBuilder { + + private final SecurePunishmentCreator creator; + private final SecurePunishment punishment; + private final Operator operator; + private final String reason; + private final EnforcementOptions enforcementOptions; + + SecureUndoBuilder(SecurePunishmentCreator creator, SecurePunishment punishment, Operator operator, String reason, EnforcementOptions enforcementOptions) { + this.creator = creator; + this.punishment = punishment; + this.operator = operator; + this.reason = reason; + this.enforcementOptions = enforcementOptions; + } + + @Override + public UndoBuilder operator(Operator operator) { + return new SecureUndoBuilder(creator, punishment, operator, reason, enforcementOptions); + } + + @Override + public UndoBuilder operatorAndReason(Operator operator, String reason) { + return new SecureUndoBuilder(creator, punishment, operator, reason, enforcementOptions); + } + + @Override + public UndoBuilder clearOperatorAndReason() { + return new SecureUndoBuilder(creator, punishment, operator, reason, enforcementOptions); + } + + @Override + public UndoBuilder enforcementOptions(EnforcementOptions enforcementOptions) { + return new SecureUndoBuilder(creator, punishment, operator, reason, enforcementOptions); + } + + @Override + public ReactionStage undoPunishment() { + return creator.revoker().undoPunishment(punishment, operator, reason) + .thenCompose((undone) -> { + if (!undone) { + return CompletableFuture.completedFuture(false); + } + return punishment.unenforcePunishment(enforcementOptions).thenApply((ignore) -> true); + }); + } + + @Override + public ReactionStage undoAndGetPunishment() { + return undoPunishment() + .thenCompose(aBoolean -> { + + }); + } +} diff --git a/bans-core/src/main/java/space/arim/libertybans/core/punish/UndoDraft.java b/bans-core/src/main/java/space/arim/libertybans/core/punish/UndoDraft.java deleted file mode 100644 index 63de44f6..00000000 --- a/bans-core/src/main/java/space/arim/libertybans/core/punish/UndoDraft.java +++ /dev/null @@ -1,7 +0,0 @@ -package space.arim.libertybans.core.punish; - -import space.arim.libertybans.api.Operator; - -public record UndoDraft(Operator operator, String reason) { - -} diff --git a/bans-core/src/main/java/space/arim/libertybans/core/punish/UndoDraftCreator.java b/bans-core/src/main/java/space/arim/libertybans/core/punish/UndoDraftCreator.java deleted file mode 100644 index f59b6116..00000000 --- a/bans-core/src/main/java/space/arim/libertybans/core/punish/UndoDraftCreator.java +++ /dev/null @@ -1,14 +0,0 @@ -package space.arim.libertybans.core.punish; - -import jakarta.inject.Singleton; -import space.arim.libertybans.api.Operator; - -import java.time.Instant; - -@Singleton -public class UndoDraftCreator { - - public UndoDraft create(Operator operator, String reason) { - return new UndoDraft(operator, reason); - } -} diff --git a/bans-core/src/test/java/space/arim/libertybans/core/punish/EmptyRevocationOrder.java b/bans-core/src/test/java/space/arim/libertybans/core/punish/EmptyRevocationOrder.java index 46560899..31a244d8 100644 --- a/bans-core/src/test/java/space/arim/libertybans/core/punish/EmptyRevocationOrder.java +++ b/bans-core/src/test/java/space/arim/libertybans/core/punish/EmptyRevocationOrder.java @@ -34,37 +34,48 @@ public final class EmptyRevocationOrder implements RevocationOrder, EnforcementOpts.Factory { private final FactoryOfTheFuture futuresFactory; - private final Operator operator; - private final String reason; - public EmptyRevocationOrder(FactoryOfTheFuture futuresFactory, Operator operator, String reason) { + public EmptyRevocationOrder(FactoryOfTheFuture futuresFactory) { this.futuresFactory = futuresFactory; - this.operator = operator; - this.reason = reason; } @Override - public Operator getOperator() { - return operator; + public Optional getID() { + throw new UnsupportedOperationException(); } @Override - public String getReason() { - return reason; + public Optional getType() { + throw new UnsupportedOperationException(); } @Override - public Optional getID() { + public Optional> getVictims() { throw new UnsupportedOperationException(); } @Override - public Optional getType() { + public Optional getOperator() { throw new UnsupportedOperationException(); } @Override - public Optional> getVictims() { + public Optional getReason() { + throw new UnsupportedOperationException(); + } + + @Override + public RevocationOrder operator(Operator operator) { + throw new UnsupportedOperationException(); + } + + @Override + public RevocationOrder operatorAndReason(Operator operator, String reason) { + throw new UnsupportedOperationException(); + } + + @Override + public RevocationOrder clearOperatorAndReason() { throw new UnsupportedOperationException(); }