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() + "]"; } }