allow removing denotation for racelog tracking from racelogs

This commit is contained in:
Fredrik Teschke committed 2014-04-23 23:16:59 +02:00
1 parent 3524639080
commit 17f718edc0
15 files changed
+123 -63

No files matched your search

@@ -0,0 +1,13 @@
package com.sap.sailing.domain.common.racelog.tracking;
public class NotRevokableException extends Exception {
private static final long serialVersionUID = 6825451915706047105L;
public NotRevokableException() {
super();
}
public NotRevokableException(String msg) {
super(msg);
}
}
@@ -52,17 +52,20 @@ public interface RaceLogTrackingAdapter {
*/
void denoteRaceForRaceLogTracking(RacingEventService service, Leaderboard leaderboard, RaceColumn raceColumn,
Fleet fleet, String raceName) throws NotDenotableForRaceLogTrackingException;
/**
* Revoke the {@link DenoteForTrackingEvent}, and if it exists the {@link StartTrackingEvent}.
* This does not affect existing an {@link RaceLogRaceTracker}
* or {@link TrackedRace} for this {@code RaceLog}.
*/
void removeDenotationForRaceLogTracking(RacingEventService service, RaceLog raceLog);
/**
* Denotes the entire {@link Leaderboard} for racelog-tracking, by calling the
* {@link #denoteRaceForRaceLogTracking(RacingEventService, Leaderboard, RaceColumn, Fleet, String)} method for each
* {@link RaceLog}.<p>
*
* Will fail if there one or more of the attached {@code RaceLogs} are not empty.<p>
*
* Also, a listener is registered, that denotes every {@link RaceLog} that is added at a later time as well.
* {@link RaceLog}.
*/
void denoteLeaderboardForRaceLogTracking(RacingEventService service, Leaderboard leaderboard)
void denoteAllRacesForRaceLogTracking(RacingEventService service, Leaderboard leaderboard)
throws NotDenotableForRaceLogTrackingException;
/**
@@ -31,12 +31,12 @@ import com.sap.sailing.domain.common.TrackedRaceStatusEnum;
import com.sap.sailing.domain.common.WithID;
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
import com.sap.sailing.domain.common.impl.Util.Pair;
import com.sap.sailing.domain.common.racelog.tracking.NotRevokableException;
import com.sap.sailing.domain.common.racelog.tracking.RaceLogTrackingState;
import com.sap.sailing.domain.common.racelog.tracking.RaceNotCreatedException;
import com.sap.sailing.domain.markpassingcalculation.MarkPassingCalculator;
import com.sap.sailing.domain.racelog.RaceLog;
import com.sap.sailing.domain.racelog.RaceLogCourseDesignChangedEvent;
import com.sap.sailing.domain.racelog.RaceLogEventFactory;
import com.sap.sailing.domain.racelog.analyzing.impl.LastPublishedCourseDesignFinder;
import com.sap.sailing.domain.racelog.impl.BaseRaceLogEventVisitor;
import com.sap.sailing.domain.racelog.tracking.DeviceCompetitorMappingEvent;
@@ -352,10 +352,9 @@ public class RaceLogRaceTracker extends BaseRaceLogEventVisitor implements RaceT
Course course = new CourseImpl(raceInfo.getA() + " course", courseBase.getWaypoints());
if (raceColumn.getTrackedRace(fleet) != null) {
if (event != null) {
raceLog.add(RaceLogEventFactory.INSTANCE.createRevokeEvent(MillisecondsTimePoint.now(),
getParams().getService().getServerAuthor(), raceLog.getCurrentPassId(), event.getId()));
}
try {
raceLog.revokeEvent(params.getService().getServerAuthor(), event);
} catch (NotRevokableException e) {}
throw new RaceNotCreatedException(String.format("Race for racelog (%s) has already been created", raceLog));
}
@@ -16,7 +16,6 @@ import com.sap.sailing.domain.base.RaceColumn;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.base.SharedDomainFactory;
import com.sap.sailing.domain.base.Waypoint;
import com.sap.sailing.domain.base.impl.BaseRaceColumnListener;
import com.sap.sailing.domain.base.impl.CourseDataImpl;
import com.sap.sailing.domain.common.PassingInstruction;
import com.sap.sailing.domain.common.RegattaIdentifier;
@@ -25,6 +24,7 @@ import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
import com.sap.sailing.domain.common.impl.Util;
import com.sap.sailing.domain.common.racelog.tracking.NotDenotableForRaceLogTrackingException;
import com.sap.sailing.domain.common.racelog.tracking.NotDenotedForRaceLogTrackingException;
import com.sap.sailing.domain.common.racelog.tracking.NotRevokableException;
import com.sap.sailing.domain.common.racelog.tracking.RaceLogRaceTrackerExistsException;
import com.sap.sailing.domain.common.racelog.tracking.RaceLogTrackingState;
import com.sap.sailing.domain.leaderboard.Leaderboard;
@@ -32,9 +32,12 @@ import com.sap.sailing.domain.leaderboard.RegattaLeaderboard;
import com.sap.sailing.domain.racelog.RaceLog;
import com.sap.sailing.domain.racelog.RaceLogEvent;
import com.sap.sailing.domain.racelog.RaceLogEventFactory;
import com.sap.sailing.domain.racelog.Revokable;
import com.sap.sailing.domain.racelog.analyzing.impl.LastPublishedCourseDesignFinder;
import com.sap.sailing.domain.racelog.tracking.DenoteForTrackingEvent;
import com.sap.sailing.domain.racelog.tracking.DeviceIdentifier;
import com.sap.sailing.domain.racelog.tracking.StartTrackingEvent;
import com.sap.sailing.domain.racelog.tracking.analyzing.impl.LastEventOfTypeFinder;
import com.sap.sailing.domain.racelog.tracking.analyzing.impl.RaceLogTrackingStateAnalyzer;
import com.sap.sailing.domain.racelogtracking.PingDeviceIdentifierImpl;
import com.sap.sailing.domain.racelogtracking.RaceLogTrackingAdapter;
@@ -109,47 +112,26 @@ public class RaceLogTrackingAdapterImpl implements RaceLogTrackingAdapter {
RaceLog raceLog = raceColumn.getRaceLog(fleet);
assert raceLog != null : new NotDenotableForRaceLogTrackingException("No RaceLog found in place");
assert raceLog.isEmpty() : new NotDenotableForRaceLogTrackingException("RaceLog is not empty");
if (new RaceLogTrackingStateAnalyzer(raceLog).analyze().isForTracking()) {
throw new NotDenotableForRaceLogTrackingException("Already denoted for tracking");
}
RaceLogEvent event = RaceLogEventFactory.INSTANCE.createDenoteForTrackingEvent(MillisecondsTimePoint.now(),
service.getServerAuthor(), raceLog.getCurrentPassId(), raceName, boatClass);
raceLog.add(event);
}
@Override
public void denoteLeaderboardForRaceLogTracking(final RacingEventService service, final Leaderboard leaderboard)
public void denoteAllRacesForRaceLogTracking(final RacingEventService service, final Leaderboard leaderboard)
throws NotDenotableForRaceLogTrackingException {
for (RaceColumn column : leaderboard.getRaceColumns()) {
for (Fleet fleet : column.getFleets()) {
RaceLog raceLog = column.getRaceLog(fleet);
if (raceLog == null || ! column.getRaceLog(fleet).isEmpty()) {
throw new NotDenotableForRaceLogTrackingException("Not all racelogs in the leaderboard are empty");
}
try {
denoteRaceForRaceLogTracking(service, leaderboard, column, fleet, null);
} catch (NotDenotableForRaceLogTrackingException e) {}
}
}
for (RaceColumn column : leaderboard.getRaceColumns()) {
for (Fleet fleet : column.getFleets()) {
denoteRaceForRaceLogTracking(service, leaderboard, column, fleet, null);
}
}
// add listener, that also denotes all newly added RaceLogs for tracking
leaderboard.addRaceColumnListener(new BaseRaceColumnListener() {
private static final long serialVersionUID = 2058141016872230058L;
@Override
public void raceColumnAddedToContainer(RaceColumn raceColumn) {
for (Fleet fleet : raceColumn.getFleets()) {
try {
denoteRaceForRaceLogTracking(service, leaderboard, raceColumn, fleet, null);
} catch (NotDenotableForRaceLogTrackingException e) {
logger.log(Level.WARNING, "Listener could not denote newly added RaceLog for racelog-tracking");
e.printStackTrace();
}
}
}
});
}
@Override
@@ -234,5 +216,15 @@ public class RaceLogTrackingAdapterImpl implements RaceLogTrackingAdapter {
service.getServerAuthor(), device, mark, raceLog.getCurrentPassId(), time, time);
raceLog.add(mapping);
service.getGPSFixStore().storeFix(device, gpsFix);
}
}
@Override
public void removeDenotationForRaceLogTracking(RacingEventService service, RaceLog raceLog) {
Revokable denoteForTrackingEvent = (Revokable) new LastEventOfTypeFinder(raceLog, true, DenoteForTrackingEvent.class).analyze();
Revokable startTrackingEvent = (Revokable) new LastEventOfTypeFinder(raceLog, true, StartTrackingEvent.class).analyze();
try {
raceLog.revokeEvent(service.getServerAuthor(), denoteForTrackingEvent);
raceLog.revokeEvent(service.getServerAuthor(), startTrackingEvent);
} catch (NotRevokableException e) {}
}
}
@@ -3,6 +3,7 @@ package com.sap.sailing.domain.racelog.tracking;
import com.sap.sailing.domain.base.BoatClass;
import com.sap.sailing.domain.racelog.RaceLog;
import com.sap.sailing.domain.racelog.RaceLogEvent;
import com.sap.sailing.domain.racelog.Revokable;
/**
* The existence of this event in a {@link RaceLog} indicates that the necessary data
@@ -13,7 +14,7 @@ import com.sap.sailing.domain.racelog.RaceLogEvent;
* @author Fredrik Teschke
*
*/
public interface DenoteForTrackingEvent extends RaceLogEvent {
public interface DenoteForTrackingEvent extends RaceLogEvent, Revokable {
String getRaceName();
BoatClass getBoatClass();
}
@@ -68,6 +68,9 @@ interface AdminConsoleResources extends ClientBundle {
@Source("com/sap/sailing/gwt/ui/client/images/denote_for_racelog_tracking.png")
ImageResource denoteForRaceLogTracking();
@Source("com/sap/sailing/gwt/ui/client/images/undenote_for_racelog_tracking.png")
ImageResource unDenoteForRaceLogTracking();
@Source("com/sap/sailing/gwt/ui/client/images/start_racelog_tracking.png")
ImageResource startRaceLogTracking();
@@ -122,6 +122,8 @@ public class RaceLogTrackingEventManagementPanel extends AbstractLeaderboardConf
boolean editable = object.getB().raceLogTrackingState != RaceLogTrackingState.TRACKING;
if (RaceLogTrackingEventManagementRaceImagesBarCell.ACTION_DENOTE_FOR_RACELOG_TRACKING.equals(value)) {
denoteForRaceLogTracking(object.getA(), object.getB());
} else if (RaceLogTrackingEventManagementRaceImagesBarCell.ACTION_REMOVE_DENOTATION.equals(value)) {
removeDenotation(object.getA(), object.getB());
} else if (RaceLogTrackingEventManagementRaceImagesBarCell.ACTION_COMPETITOR_REGISTRATIONS.equals(value)) {
new RaceLogTrackingCompetitorRegistrationsDialog(sailingService, stringMessages, errorReporter,
getSelectedLeaderboardName(), object.getA().getName(), object.getB().getName(), editable).show();
@@ -267,7 +269,6 @@ public class RaceLogTrackingEventManagementPanel extends AbstractLeaderboardConf
@Override
public void onSuccess(Void result) {
loadAndRefreshLeaderboard(leaderboard.name, raceColumn.getName());
raceColumnTableSelectionModel.clear();
}
@Override
@@ -277,6 +278,21 @@ public class RaceLogTrackingEventManagementPanel extends AbstractLeaderboardConf
});
}
private void removeDenotation(final RaceColumnDTO raceColumn, final FleetDTO fleet) {
final StrippedLeaderboardDTO leaderboard = getSelectedLeaderboard();
sailingService.removeDenotationForRaceLogTracking(leaderboard.name, raceColumn.getName(), fleet.getName(), new AsyncCallback<Void>() {
@Override
public void onSuccess(Void result) {
loadAndRefreshLeaderboard(leaderboard.name, raceColumn.getName());
}
@Override
public void onFailure(Throwable caught) {
errorReporter.reportError("Could not remove denotation: " + caught.getMessage());
}
});
}
private void startTracking(Set<RaceColumnDTOAndFleetDTOWithNameBasedEquality> races) {
final StrippedLeaderboardDTO leaderboard = getSelectedLeaderboard();
@@ -290,7 +306,6 @@ public class RaceLogTrackingEventManagementPanel extends AbstractLeaderboardConf
public void onSuccess(Void result) {
loadAndRefreshLeaderboard(leaderboard.name, raceColumn.getName());
trackedRacesListComposite.regattaRefresher.fillRegattas();
raceColumnTableSelectionModel.clear();
}
@Override
@@ -10,6 +10,7 @@ import com.sap.sailing.gwt.ui.client.shared.components.ImagesBarCell;
public class RaceLogTrackingEventManagementRaceImagesBarCell extends ImagesBarCell {
public final static String ACTION_DENOTE_FOR_RACELOG_TRACKING = "ACTION_DENOTE_FOR_RACELOG_TRACKING";
public final static String ACTION_REMOVE_DENOTATION = "ACTION_REMOVE_DENOTATION";
public final static String ACTION_COMPETITOR_REGISTRATIONS = "ACTION_COMPETITOR_REGISTRATIONS";
public final static String ACTION_DEFINE_COURSE = "ACTION_DEFINE_COURSE";
public final static String ACTION_MAP_DEVICES = "ACTION_MAP_DEVICES";
@@ -30,9 +31,8 @@ public class RaceLogTrackingEventManagementRaceImagesBarCell extends ImagesBarCe
RaceColumnDTOAndFleetDTOWithNameBasedEquality object = (RaceColumnDTOAndFleetDTOWithNameBasedEquality) getContext().getKey();
if (! object.getB().raceLogTrackingState.isForTracking()) {
result.add(new ImageSpec(ACTION_DENOTE_FOR_RACELOG_TRACKING, stringMessages.denoteForRaceLogTracking(), makeImagePrototype(resources.denoteForRaceLogTracking())));
}
if (object.getB().raceLogTrackingState.isForTracking()) {
} else {
result.add(new ImageSpec(ACTION_REMOVE_DENOTATION, stringMessages.removeDenotation(), makeImagePrototype(resources.unDenoteForRaceLogTracking())));
result.add(new ImageSpec(ACTION_COMPETITOR_REGISTRATIONS, stringMessages.competitorRegistrations(), makeImagePrototype(resources.competitorRegistrations())));
result.add(new ImageSpec(ACTION_DEFINE_COURSE, stringMessages.defineCourse(), makeImagePrototype(resources.defineCourse())));
result.add(new ImageSpec(ACTION_MAP_DEVICES, stringMessages.mapDevices(), makeImagePrototype(resources.mapDevices())));
@@ -36,11 +36,14 @@ import com.sap.sailing.domain.common.impl.Util.Triple;
import com.sap.sailing.domain.common.racelog.RacingProcedureType;
import com.sap.sailing.domain.common.racelog.tracking.NoCorrespondingServiceRegisteredException;
import com.sap.sailing.domain.common.racelog.tracking.NotDenotedForRaceLogTrackingException;
import com.sap.sailing.domain.common.racelog.tracking.NotRevokableException;
import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
import com.sap.sailing.domain.racelog.RaceLog;
import com.sap.sailing.domain.racelog.Revokable;
import com.sap.sailing.domain.racelog.tracking.DenoteForTrackingEvent;
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
import com.sap.sailing.domain.racelogtracking.RaceLogTrackingAdapter;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.gwt.ui.shared.BulkScoreCorrectionDTO;
import com.sap.sailing.gwt.ui.shared.CompactRaceMapDataDTO;
import com.sap.sailing.gwt.ui.shared.CompetitorsRaceDataDTO;
@@ -399,6 +402,14 @@ public interface SailingService extends RemoteService {
Map<RegattaAndRaceIdentifier, Integer> importWindFromIgtimi(List<RaceDTO> selectedRaces) throws Exception;
void denoteForRaceLogTracking(String leaderboardName, String raceColumnName, String fleetName) throws Exception;
/**
* Revoke the {@link DenoteForTrackingEvent}. This does not affect an existing {@code RaceLogRaceTracker}
* or {@link TrackedRace} for this {@code RaceLog}.
*
* @see RaceLogTrackingAdapter#removeDenotationForRaceLogTracking
*/
void removeDenotationForRaceLogTracking(String leaderboardName, String raceColumnName, String fleetName);
void denoteForRaceLogTracking(String leaderboardName) throws Exception;
@@ -450,5 +461,6 @@ public interface SailingService extends RemoteService {
* Revoke the events in the {@code RaceLog} that are identified by the {@code eventIds}.
* This only affects such events that implement {@link Revokable}.
*/
void revokeRaceLogEvents(String leaderboardName, String raceColumnName, String fleetName, List<Serializable> eventIds);
void revokeRaceLogEvents(String leaderboardName, String raceColumnName, String fleetName, List<Serializable> eventIds)
throws NotRevokableException;
}
@@ -574,5 +574,8 @@ public interface SailingServiceAsync {
AsyncCallback<Void> callback);
void removeSeries(RegattaIdentifier regattaIdentifier, String seriesName, AsyncCallback<Void> callback);
void removeDenotationForRaceLogTracking(String leaderboardName, String raceColumnName, String fleetName,
AsyncCallback<Void> callback);
}
@@ -1005,4 +1005,5 @@ public interface StringMessages extends Messages {
String importWindTooltip();
String authorName();
String authorPriority();
String removeDenotation();
}
@@ -990,4 +990,5 @@ ratio=ratio
importWind=Import Wind
importWindTooltip=Unchecking this option will drastically lower the amount of data transfered.
authorName=Author name
authorPriority=Author priority
authorPriority=Author priority
removeDenotation=Remove Denotation
@@ -986,4 +986,5 @@ ratio=Verhältnis
importWind=Wind importieren
importWindTooltip=Diese Option zu deselektieren führt zu einer wesentlich kleineren übertragenen Datenmenge.
authorName=Benutzername
authorPriority=Benutzer-Priorität
authorPriority=Benutzer-Priorität
removeDenotation=Markierung entfernen
@@ -162,6 +162,8 @@ import com.sap.sailing.domain.common.racelog.Flags;
import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
import com.sap.sailing.domain.common.racelog.tracking.NoCorrespondingServiceRegisteredException;
import com.sap.sailing.domain.common.racelog.tracking.NotDenotedForRaceLogTrackingException;
import com.sap.sailing.domain.common.racelog.tracking.NotRevokableException;
import com.sap.sailing.domain.common.racelog.tracking.RaceLogTrackingState;
import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
import com.sap.sailing.domain.common.racelog.tracking.TypeBasedServiceFinder;
import com.sap.sailing.domain.common.racelog.tracking.TypeBasedServiceFinderFactory;
@@ -185,6 +187,7 @@ import com.sap.sailing.domain.racelog.RaceLogEvent;
import com.sap.sailing.domain.racelog.RaceLogEventFactory;
import com.sap.sailing.domain.racelog.RaceLogFlagEvent;
import com.sap.sailing.domain.racelog.RaceStateOfSameDayHelper;
import com.sap.sailing.domain.racelog.Revokable;
import com.sap.sailing.domain.racelog.analyzing.impl.AbortingFlagFinder;
import com.sap.sailing.domain.racelog.analyzing.impl.LastPublishedCourseDesignFinder;
import com.sap.sailing.domain.racelog.state.ReadonlyRaceState;
@@ -2032,7 +2035,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
} else {
leaderboardDTO.discardThresholds = null;
}
leaderboardDTO.isDenotableForRaceLogTracking = leaderboard instanceof RegattaLeaderboard;
boolean oneRaceLogDenotableForTracking = false;
for (RaceColumn raceColumn : leaderboard.getRaceColumns()) {
for (Fleet fleet : raceColumn.getFleets()) {
RaceDTO raceDTO = null;
@@ -2050,15 +2053,20 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
fleetDTO, raceColumn.isMedalRace(), raceIdentifier, raceDTO);
RaceLog raceLog = raceColumn.getRaceLog(fleet);
fleetDTO.raceLogTrackingState = new RaceLogTrackingStateAnalyzer(raceLog).analyze();
RaceLogTrackingState raceLogTrackingState = new RaceLogTrackingStateAnalyzer(raceLog).analyze();
fleetDTO.raceLogTrackingState = raceLogTrackingState;
fleetDTO.raceLogTrackerExists = getService().getRaceTrackerById(raceLog.getId()) != null;
fleetDTO.courseDefinitionInRaceLog = new LastPublishedCourseDesignFinder(raceLog).analyze() != null;
fleetDTO.courseDefinitionInRaceLog = raceLogTrackingState.isForTracking() ?
new LastPublishedCourseDesignFinder(raceLog).analyze() != null : false;
if (! raceLog.isEmpty()) {
leaderboardDTO.isDenotableForRaceLogTracking = false;
if (! raceLogTrackingState.isForTracking()) {
oneRaceLogDenotableForTracking = true;
}
}
}
if (oneRaceLogDenotableForTracking) {
leaderboardDTO.isDenotableForRaceLogTracking = leaderboard instanceof RegattaLeaderboard;
}
return leaderboardDTO;
}
@@ -4029,10 +4037,16 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
getRaceLogTrackingAdapter().denoteRaceForRaceLogTracking(getService(), leaderboard, raceColumn, fleet, null);
}
@Override
public void removeDenotationForRaceLogTracking(String leaderboardName, String raceColumnName, String fleetName) {
RaceLog raceLog = getRaceLog(leaderboardName, raceColumnName, fleetName);
getRaceLogTrackingAdapter().removeDenotationForRaceLogTracking(getService(), raceLog);
}
@Override
public void denoteForRaceLogTracking(String leaderboardName) throws Exception {
Leaderboard leaderboard = getService().getLeaderboardByName(leaderboardName);
getRaceLogTrackingAdapter().denoteLeaderboardForRaceLogTracking(getService(), leaderboard);
getRaceLogTrackingAdapter().denoteAllRacesForRaceLogTracking(getService(), leaderboard);
}
private RaceLog getRaceLog(String leaderboardName, String raceColumnName, String fleetName) {
@@ -4051,8 +4065,9 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
private void unregisterCompetitor(RaceLog raceLog, Competitor competitor) {
for (RaceLogEvent event : raceLog.getUnrevokedEventsDescending()) {
if (event instanceof RegisterCompetitorEvent && ((RegisterCompetitorEvent) event).getCompetitor().equals(competitor)) {
raceLog.add(RaceLogEventFactory.INSTANCE.createRevokeEvent(MillisecondsTimePoint.now(),
getService().getServerAuthor(), raceLog.getCurrentPassId(), event.getId()));
try {
raceLog.revokeEvent(getService().getServerAuthor(), (RegisterCompetitorEvent) event);
} catch (NotRevokableException e) {}
}
}
}
@@ -4340,12 +4355,13 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
@Override
public void revokeRaceLogEvents(String leaderboardName, String raceColumnName, String fleetName,
List<Serializable> eventIds) {
List<Serializable> eventIds) throws NotRevokableException {
RaceLog raceLog = getRaceLog(leaderboardName, raceColumnName, fleetName);
for (Serializable idToRevoke : eventIds) {
RaceLogEvent event = RaceLogEventFactory.INSTANCE.createRevokeEvent(MillisecondsTimePoint.now(),
getService().getServerAuthor(), raceLog.getCurrentPassId(), idToRevoke);
raceLog.add(event);
RaceLogEvent event = raceLog.getEventById(idToRevoke);
if (event instanceof Revokable) {
raceLog.revokeEvent(getService().getServerAuthor(), (Revokable) event);
}
}
}