001/* 002 * PlotSquared, a land and world management plugin for Minecraft. 003 * Copyright (C) IntellectualSites <https://intellectualsites.com> 004 * Copyright (C) IntellectualSites team and contributors 005 * 006 * This program is free software: you can redistribute it and/or modify 007 * it under the terms of the GNU General Public License as published by 008 * the Free Software Foundation, either version 3 of the License, or 009 * (at your option) any later version. 010 * 011 * This program is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 014 * GNU General Public License for more details. 015 * 016 * You should have received a copy of the GNU General Public License 017 * along with this program. If not, see <https://www.gnu.org/licenses/>. 018 */ 019package com.plotsquared.core.player; 020 021import com.plotsquared.core.synchronization.LockRepository; 022import org.checkerframework.checker.nullness.qual.NonNull; 023import org.checkerframework.checker.nullness.qual.Nullable; 024 025import java.util.Optional; 026 027/** 028 * Access to player meta data 029 * 030 * @param <T> Meta data type 031 */ 032public abstract class MetaDataAccess<T> implements AutoCloseable { 033 034 private final PlotPlayer<?> player; 035 private final MetaDataKey<T> metaDataKey; 036 private final LockRepository.LockAccess lockAccess; 037 private boolean closed = false; 038 039 MetaDataAccess( 040 final @NonNull PlotPlayer<?> player, 041 final @NonNull MetaDataKey<T> metaDataKey, 042 final LockRepository.@NonNull LockAccess lockAccess 043 ) { 044 this.player = player; 045 this.metaDataKey = metaDataKey; 046 this.lockAccess = lockAccess; 047 } 048 049 @SuppressWarnings("unchecked") 050 private static <E extends Throwable> void sneakyThrow(final Throwable e) throws E { 051 throw (E) e; 052 } 053 054 /** 055 * Check if the player has meta data stored with the given key 056 * 057 * @return {@code true} if player has meta data with this key, or 058 * {@code false} 059 */ 060 public abstract boolean isPresent(); 061 062 /** 063 * Remove the stored value meta data 064 * 065 * @return Old value, or {@code null} 066 */ 067 public @Nullable 068 abstract T remove(); 069 070 /** 071 * Set the meta data value 072 * 073 * @param value New value 074 */ 075 public abstract void set(final @NonNull T value); 076 077 /** 078 * Get the stored meta data value 079 * 080 * @return Stored value, or {@link Optional#empty()} 081 */ 082 public @NonNull 083 abstract Optional<T> get(); 084 085 @Override 086 public final void close() { 087 this.lockAccess.close(); 088 this.closed = true; 089 } 090 091 /** 092 * Get the owner of the meta data 093 * 094 * @return Player 095 */ 096 public @NonNull PlotPlayer<?> getPlayer() { 097 return this.player; 098 } 099 100 /** 101 * Get the meta data key 102 * 103 * @return Meta data key 104 */ 105 public @NonNull MetaDataKey<T> getMetaDataKey() { 106 return this.metaDataKey; 107 } 108 109 /** 110 * Check whether or not the meta data access has been closed. 111 * After being closed, all attempts to access the meta data 112 * through the instance, will lead to {@link IllegalAccessException} 113 * being thrown 114 * 115 * @return {@code true} if the access has been closed 116 */ 117 public boolean isClosed() { 118 return this.closed; 119 } 120 121 protected void checkClosed() { 122 if (this.closed) { 123 sneakyThrow(new IllegalAccessException("The meta data access instance has been closed")); 124 } 125 } 126 127 128}