package com.nicewuerfel.blockown;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.block.Block;
import java.lang.ref.WeakReference;
public class OwnedBlock implements Ownable {
private static final long serialVersionUID = 4996349639615230112L;
private transient WeakReference<Block> blockRef = new WeakReference<>(null);
private final int hashCode;
private final String worldName;
private final int x;
private final int y;
private final int z;
private transient Material material = null;
/**
* Creates a new OwnedBlock instance holding a WeakReference to the given block.
*
* @param block the Block
* @return the new OwnedBlock instance
*/
public static OwnedBlock newInstance(Block block) {
if (block == null) {
throw new NullPointerException("Block can't be null");
} else {
return new OwnedBlock(block.getWorld().getName(), block.getX(), block.getY(), block.getZ(),
new Material(block.getType()), block);
}
}
/**
* Creates a new OwnedBlock instance. The corresponding Block will be looked up when getBlock() is
* called.
*
* @param worldName the world name
* @param x the x coordinate
* @param y the y coordinate
* @param z the z coordinate
* @param material the material
* @return the new OwnedBlock instance
*/
public static OwnedBlock newInstance(String worldName, int x, int y, int z, Material material) {
if (worldName == null) {
throw new NullPointerException("world name can't be null");
}
// it's ok if material is null
return new OwnedBlock(worldName, x, y, z, material, null);
}
/**
* Creates a new OwnedBlock instance. The corresponding Block and its Material will be looked up
* when needed.
*
* @param worldName the world name
* @param x the x
* @param y the y
* @param z the z
* @return the new OwnedBlock instance
*/
public static OwnedBlock newInstance(String worldName, int x, int y, int z) {
return newInstance(worldName, x, y, z, null);
}
private OwnedBlock(String worldName, int x, int y, int z, Material material, Block block) {
this.worldName = worldName;
this.x = x;
this.y = y;
this.z = z;
this.material = material;
this.blockRef = new WeakReference<>(block);
this.hashCode = calcHashCode();
}
private int calcHashCode() {
final int prime = 31;
int result = 13;
result = prime * result + worldName.hashCode();
result = prime * result + x;
result = prime * result + y;
result = prime * result + z;
return result;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getZ() {
return z;
}
@Override
public World getWorld() throws InvalidWorldNameException {
World world = Bukkit.getServer().getWorld(worldName);
if (world == null) {
throw new InvalidWorldNameException("There is no world called " + worldName);
}
return world;
}
/**
* Returns the Block at the location of this OwnedBlock. Never null.
*
* @return the Block
* @throws InvalidWorldNameException if the world referenced by the world name doesn't exist
*/
public Block getBlock() throws InvalidWorldNameException {
if (blockRef == null) {
blockRef = new WeakReference<>(null);
}
Block result = blockRef.get();
if (result == null) {
result = getWorld().getBlockAt(x, y, z);
blockRef = new WeakReference<>(result);
}
return result;
}
@Override
public String getWorldName() {
return worldName;
}
@Override
public Material getMaterial() throws InvalidWorldNameException {
if (material == null) {
material = new Material(getBlock().getType());
}
return material;
}
@Override
public int hashCode() {
return hashCode;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof OwnedBlock)) {
return false;
}
OwnedBlock other = (OwnedBlock) obj;
if (!worldName.equals(other.worldName)) {
return false;
}
if (x != other.x) {
return false;
}
if (y != other.y) {
return false;
}
return z == other.z;
}
@Override
public String toString() {
return "OwnedBlock [block=" + getWorldName() + ":" + getX() + "," + getY() + "," + getZ() + "]";
}
}