1
Files
lecture-professional-softwa…/src/main/java/mops/gruppen2/domain/event/Event.java
2020-04-19 16:20:20 +02:00

120 lines
4.1 KiB
Java

package mops.gruppen2.domain.event;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.extern.log4j.Log4j2;
import mops.gruppen2.domain.exception.BadArgumentException;
import mops.gruppen2.domain.exception.EventException;
import mops.gruppen2.domain.exception.IdMismatchException;
import mops.gruppen2.domain.model.group.Group;
import mops.gruppen2.infrastructure.GroupCache;
import java.time.LocalDateTime;
import java.util.UUID;
import static com.fasterxml.jackson.annotation.JsonSubTypes.Type;
import static com.fasterxml.jackson.annotation.JsonTypeInfo.As;
import static com.fasterxml.jackson.annotation.JsonTypeInfo.Id;
@Log4j2
@JsonTypeInfo(use = Id.NAME, include = As.PROPERTY, property = "class")
@JsonSubTypes({@Type(value = AddMemberEvent.class, name = "ADDMEMBER"),
@Type(value = CreateGroupEvent.class, name = "CREATEGROUP"),
@Type(value = DestroyGroupEvent.class, name = "DESTROYGROUP"),
@Type(value = KickMemberEvent.class, name = "KICKMEMBER"),
@Type(value = SetDescriptionEvent.class, name = "SETDESCRIPTION"),
@Type(value = SetInviteLinkEvent.class, name = "SETLINK"),
@Type(value = SetLimitEvent.class, name = "SETLIMIT"),
@Type(value = SetParentEvent.class, name = "SETPARENT"),
@Type(value = SetTitleEvent.class, name = "SETTITLE"),
@Type(value = SetTypeEvent.class, name = "SETTYPE"),
@Type(value = UpdateRoleEvent.class, name = "UPDATEROLE")})
@Getter
@NoArgsConstructor // Lombok needs a default constructor in the base class
public abstract class Event {
@JsonProperty("groupid")
protected UUID groupid;
@JsonProperty("version")
protected long version; // Group-Version
@JsonProperty("exec")
protected String exec;
@JsonProperty("target")
protected String target;
@JsonProperty("date")
protected LocalDateTime date;
//TODO: Eigentlich sollte die Gruppe aus dem Cache genommen werden, nicht übergeben
public Event(UUID groupid, String exec, String target) {
this.groupid = groupid;
this.exec = exec;
this.target = target;
}
public void init(long version) {
if (this.version != 0) {
throw new BadArgumentException("Event wurde schon initialisiert. (" + type() + ")");
}
date = LocalDateTime.now();
log.trace("Event wurde initialisiert. (" + type() + "," + version + ")");
this.version = version;
}
public void apply(Group group, GroupCache cache) throws EventException {
log.trace("Event wird angewendet:\t{}", this);
if (version == 0) {
throw new BadArgumentException("Event wurde nicht initialisiert.");
}
checkGroupIdMatch(group.getId());
group.updateVersion(version);
applyEvent(group);
updateCache(cache, group); // Update erst nachdem apply keine exception geworfen hat
}
public void apply(Group group) throws EventException {
log.trace("Event wird angewendet:\t{}", this);
if (version == 0) {
throw new BadArgumentException("Event wurde nicht initialisiert.");
}
checkGroupIdMatch(group.getId());
group.updateVersion(version);
applyEvent(group);
}
private void checkGroupIdMatch(UUID groupid) throws IdMismatchException {
// CreateGroupEvents müssen die Id erst initialisieren
if (this instanceof CreateGroupEvent) {
return;
}
if (!this.groupid.equals(groupid)) {
throw new IdMismatchException("Das Event gehört zu einer anderen Gruppe");
}
}
protected abstract void updateCache(GroupCache cache, Group group);
protected abstract void applyEvent(Group group) throws EventException;
@JsonIgnore
public abstract String format();
@JsonIgnore
public abstract String type();
}