package com.nicewuerfel.blockown.protection;
import com.nicewuerfel.blockown.Material;
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;
/**
* An immutable object containing information about a single action on the protection database.<br>
* Can't be instantiated directly, the class {@link ProtectAction.Builder} must be used.
*
* @author Pheasn
*/
public final class ProtectAction {
@Nonnull
private final Type type;
@Nonnull
private final User owner;
@Nullable
private final User user;
@Nullable
private final Material material;
private final long timeStamp;
/**
* Describes the type of {@link ProtectAction action} to be performed.
*/
public enum Type {
/**
* Protect a {@link Material} against other players, except friends.
*/
PROTECT,
/**
* Revert {@link #PROTECT}.
*/
UNPROTECT,
/**
* Protects a {@link Material} against all players, even friends.
*/
LOCK,
/**
* Revert {@link #LOCK}.
*/
UNLOCK,
/**
* Adds a {@link User} to the friend list of this {@link ProtectAction action's} main user.
*/
FRIEND,
/**
* Revert {@link #FRIEND}.
*/
UNFRIEND,
/**
* Drop all occurrences of this player in any {@link Protection}-related data.<br>
* This means the player won't have any locked or protected {@link Material materials}, no
* friends and would be removed from all friend-lists of other players.
*/
DROP
}
/**
* A builder class for {@link ProtectAction} objects.
*
* @author Pheasn
*/
public static class Builder {
private Type type;
private User owner;
private Material material;
private User user;
/**
* Creates a new Builder instance.
*
* @param owner the main {@link User} this action is about
*/
public Builder(@Nonnull User owner) {
this.owner = Objects.requireNonNull(owner);
}
/**
* Sets the type to {@link Type#PROTECT} and specifies the {@link Material} to protect.
*
* @param material the {@link Material}
* @return this {@link Builder}
*/
public Builder protect(@Nonnull Material material) {
this.material = Objects.requireNonNull(material);
type = Type.PROTECT;
return this;
}
/**
* Sets the type to {@link Type#UNPROTECT} and specifies the {@link Material} to unprotect.
*
* @param material the {@link Material}
* @return this {@link Builder}
*/
public Builder unprotect(@Nonnull Material material) {
this.material = Objects.requireNonNull(material);
type = Type.UNPROTECT;
return this;
}
/**
* Sets the type to {@link Type#LOCK} and specifies the {@link Material} to lock.
*
* @param material the {@link Material}
* @return this {@link Builder}
*/
public Builder lock(@Nonnull Material material) {
this.material = Objects.requireNonNull(material);
type = Type.LOCK;
return this;
}
/**
* Sets the type to {@link Type#UNLOCK} and specifies the {@link Material} to unlock.
*
* @param material the {@link Material}
* @return this {@link Builder}
*/
public Builder unlock(@Nonnull Material material) {
this.material = Objects.requireNonNull(material);
type = Type.UNLOCK;
return this;
}
/**
* Sets the type to {@link Type#FRIEND} and specifies the {@link User} to add as a friend for
* the main user.
*
* @param user the {@link User}
* @return this {@link Builder}
*/
public Builder friend(@Nonnull User user) {
this.user = Objects.requireNonNull(user);
type = Type.FRIEND;
return this;
}
/**
* Sets the type to {@link Type#UNFRIEND} and specifies the {@link User} to remove from the main
* user's friend list.
*
* @param user the {@link User}
* @return this {@link Builder}
*/
public Builder unfriend(@Nonnull User user) {
this.user = user;
type = Type.UNFRIEND;
return this;
}
/**
* Sets the type to {@link Type#DROP}.
*
* @return this {@link Builder}
*/
public Builder drop() {
type = Type.DROP;
return this;
}
/**
* Returns an instance of {@link ProtectAction}.
*
* @return the {@link ProtectAction}
* @throws IllegalStateException if this is called without calling any other method first
*/
public ProtectAction build() {
if (type == null) {
throw new IllegalStateException("No type selected");
}
return new ProtectAction(type, owner, material, user);
}
}
private ProtectAction(Type type, User owner, Material material, User user) {
this.type = type;
this.owner = owner;
this.material = material;
this.user = user;
this.timeStamp = System.currentTimeMillis();
}
/**
* Gets the {@link Type}.
*
* @return the {@link Type}
*/
@Nonnull
public Type getActionType() {
return type;
}
/**
* Gets the main {@link User} this action is about.
*
* @return the {@link User}
*/
@Nonnull
public User getOwner() {
return owner;
}
/**
* Gets the second {@link User} to {@link Type#FRIEND FRIEND} or {@link Type#UNFRIEND UNFRIEND}.
* <br>
* If the type is none of the above, returns null.
*
* @return the {@link User}
*/
@Nullable
public User getUser() {
return user;
}
/**
* Gets the {@link Material} to {@link Type#PROTECT PROTECT}, {@link Type#UNPROTECT UNPROTECT},
* {@link Type#LOCK LOCK} or {@link Type#UNLOCK UNLOCK}.<br>
* If the type is none of the above, returns null.
*
* @return the {@link Material}
*/
@Nullable
public Material getMaterial() {
return material;
}
/**
* Returns the value of {@link System#currentTimeMillis()} at the time of this object's creation.
*
* @return the Unix time stamp in milliseconds
*/
public long getTimeStamp() {
return timeStamp;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 17;
result = prime * result + ((material == null) ? 0 : material.hashCode());
result = prime * result + owner.hashCode();
result = prime * result + type.hashCode();
result = prime * result + (int) (timeStamp ^ (timeStamp >>> 32));
result = prime * result + ((user == null) ? 0 : user.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof ProtectAction)) {
return false;
}
ProtectAction other = (ProtectAction) obj;
if (material == null) {
if (other.material != null) {
return false;
}
} else if (!material.equals(other.material)) {
return false;
}
if (!owner.equals(other.owner)) {
return false;
}
if (type != other.type) {
return false;
}
if (timeStamp != other.timeStamp) {
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 "ProtectAction [protectActionType=" + type + ", owner=" + owner + ", user=" + user
+ ", material=" + material + ", timeStamp="
+ new SimpleDateFormat().format(new Date(timeStamp)) + "]";
}
}