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.google.common.base.Objects; 022import com.google.common.base.Preconditions; 023import com.google.inject.TypeLiteral; 024import com.plotsquared.core.synchronization.LockKey; 025import org.checkerframework.checker.nullness.qual.NonNull; 026 027import java.util.HashMap; 028import java.util.Map; 029 030/** 031 * Key used to access meta data 032 * 033 * @param <T> Meta data type 034 */ 035public final class MetaDataKey<T> { 036 037 private static final Map<String, MetaDataKey<?>> keyMap = new HashMap<>(); 038 private static final Object keyMetaData = new Object(); 039 040 private final String key; 041 private final TypeLiteral<T> type; 042 private final LockKey lockKey; 043 044 private MetaDataKey(final @NonNull String key, final @NonNull TypeLiteral<T> type) { 045 this.key = Preconditions.checkNotNull(key, "Key may not be null"); 046 this.type = Preconditions.checkNotNull(type, "Type may not be null"); 047 this.lockKey = LockKey.of(this.key); 048 } 049 050 /** 051 * Get a new named lock key 052 * 053 * @param key Key name 054 * @param type type 055 * @param <T> Type 056 * @return MetaData key instance 057 */ 058 @SuppressWarnings("unchecked") 059 public static @NonNull <T> MetaDataKey<T> of(final @NonNull String key, final @NonNull TypeLiteral<T> type) { 060 synchronized (keyMetaData) { 061 return (MetaDataKey<T>) 062 keyMap.computeIfAbsent(key, missingKey -> new MetaDataKey<>(missingKey, type)); 063 } 064 } 065 066 @Override 067 public String toString() { 068 return this.key; 069 } 070 071 @Override 072 public boolean equals(final Object o) { 073 if (this == o) { 074 return true; 075 } 076 if (o == null || getClass() != o.getClass()) { 077 return false; 078 } 079 final MetaDataKey<?> lockKey = (MetaDataKey<?>) o; 080 return Objects.equal(this.key, lockKey.key); 081 } 082 083 @Override 084 public int hashCode() { 085 return Objects.hashCode(this.key); 086 } 087 088 /** 089 * Get the {@link LockKey} associated with this key 090 * 091 * @return Lock key 092 */ 093 public @NonNull LockKey getLockKey() { 094 return this.lockKey; 095 } 096 097 /** 098 * Get the meta data type 099 * 100 * @return Meta data type 101 */ 102 public @NonNull TypeLiteral<T> getType() { 103 return this.type; 104 } 105 106}