package com.nicewuerfel.blockown.database;
import com.nicewuerfel.blockown.Ownable;
import com.nicewuerfel.blockown.User;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Objects;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* Immutable object which represents a single action to be performed on the owning database.
*
* @author Pheasn
*/
public final class DatabaseAction {
@Nullable
private final User user;
@Nullable
private final Ownable ownable;
@Nonnull
private final Type type;
private final long timeStamp;
private final int hashCode;
private int attempts = 0;
/**
* The type of a {@link DatabaseAction}.
*/
public enum Type {
/**
* Drop all ownings of a {@link User} from the database.
*/
DROP,
/**
* Own a {@link Ownable} for a {@link User}.
*/
OWN,
/**
* Delete the owner of a {@link Ownable}.
*/
UNOWN
}
/**
* Instantiated a new DatabaseAction of the {@link Type} {@link Type#UNOWN UNOWN}.
*
* @param ownable the Ownable to unown
* @return the {@link DatabaseAction}
*/
@Nonnull
public static DatabaseAction newUnownInstance(@Nonnull Ownable ownable) {
return new DatabaseAction(Type.UNOWN, Objects.requireNonNull(ownable), null);
}
@Nonnull
public static DatabaseAction newOwnInstance(@Nonnull Ownable ownable, @Nonnull User user) {
return new DatabaseAction(Type.OWN, Objects.requireNonNull(ownable),
Objects.requireNonNull(user));
}
@Nonnull
public static DatabaseAction newDropInstance(@Nonnull User user) {
return new DatabaseAction(Type.DROP, null, Objects.requireNonNull(user));
}
/**
* Instantiates a new DatabaseAction.
*
* @param type the DatabaseActionType
* @param ownable the ownable, may be null if type is DROP
* @param user the user, may be null if type is UNOWN
*/
private DatabaseAction(@Nonnull Type type, @Nullable Ownable ownable, @Nullable User user) {
this.user = user;
this.ownable = ownable;
this.type = type;
this.timeStamp = System.currentTimeMillis();
this.hashCode = calcHashCode();
}
@Nullable
public User getUser() {
return user;
}
@Nullable
public Ownable getOwnable() {
return ownable;
}
public long getTimeStamp() {
return timeStamp;
}
@Nonnull
public Type getActionType() {
return type;
}
/**
* Adds an attempt to the counter and returns the count before the attempt.
*
* @return the attempt count before this call.
*/
int addAttempt() {
return attempts++;
}
int getAttempts() {
return attempts;
}
private int calcHashCode() {
final int prime = 31;
int result = 3;
result = prime * result + type.hashCode();
result = prime * result + ((ownable == null) ? 0 : ownable.hashCode());
result = prime * result + (int) (timeStamp ^ (timeStamp >>> 32));
result = prime * result + ((user == null) ? 0 : user.hashCode());
return result;
}
@Override
public int hashCode() {
return hashCode;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof DatabaseAction)) {
return false;
}
DatabaseAction other = (DatabaseAction) obj;
if (type != other.type) {
return false;
}
if (ownable == null) {
if (other.ownable != null) {
return false;
}
} else if (!ownable.equals(other.ownable)) {
return false;
}
if (Long.compare(timeStamp, other.timeStamp) != 0) {
return false;
}
if (user == null) {
if (other.user != null) {
return false;
}
} else if (!user.equals(other.user)) {
return false;
}
return true;
}
@Override
public String toString() {
return "DatabaseAction [user=" + user + ", ownable=" + ownable + ", type=" + type
+ ", timeStamp=" + new SimpleDateFormat().format(new Date(timeStamp)) + "]";
}
}