/*
* This file is part of NucleusFramework for Bukkit, licensed under the MIT License (MIT).
*
* Copyright (c) JCThePants (www.jcwhatever.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.jcwhatever.nucleus.utils.items;
import com.jcwhatever.nucleus.internal.NucLang;
import com.jcwhatever.nucleus.managed.language.Localizable;
import com.jcwhatever.nucleus.mixins.IPluginOwned;
import com.jcwhatever.nucleus.storage.IDataNode;
import com.jcwhatever.nucleus.utils.CollectionUtils;
import com.jcwhatever.nucleus.utils.PreCon;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* A collection of ItemStacks that can be used for validation/filtering of ItemStacks.
*/
public class ItemFilter implements IPluginOwned {
@Localizable static final String _WHITELIST = "Whitelist";
@Localizable static final String _BLACKLIST = "Blacklist";
private final Plugin _plugin;
private final IDataNode _dataNode;
private final ItemStackMatcher _matcher;
private final Map<MatchableItem, MatchableItem> _filterItems = new HashMap<>(6 * 9);
private FilterPolicy _filter = FilterPolicy.WHITELIST;
/**
* Validation filtering policy.
*/
public enum FilterPolicy {
WHITELIST,
BLACKLIST;
public String getDisplayName() {
switch (this) {
case WHITELIST:
return NucLang.get(_WHITELIST).toString();
case BLACKLIST:
return NucLang.get(_BLACKLIST).toString();
default:
return super.toString();
}
}
@Override
public String toString() {
return getDisplayName();
}
}
/**
* Constructor.
*
* <p>Uses default {@link ItemStackMatcher}.</p>
*
* @param plugin The owning plugin.
* @param dataNode Data node to save and load settings.
*/
public ItemFilter(Plugin plugin, @Nullable IDataNode dataNode) {
this(plugin, dataNode, ItemStackMatcher.getDefault());
}
/**
* Constructor.
*
* @param plugin The owning plugin.
* @param dataNode The data node to save and load settings from.
* @param matcher The {@link ItemStackMatcher} to use to match items.
*/
public ItemFilter(Plugin plugin, @Nullable IDataNode dataNode, ItemStackMatcher matcher) {
PreCon.notNull(plugin);
PreCon.notNull(matcher);
_plugin = plugin;
_dataNode = dataNode;
_matcher = matcher ;
load();
}
@Override
public Plugin getPlugin() {
return _plugin;
}
/**
* Get the filter policy used for validating items.
*/
public FilterPolicy getPolicy() {
return _filter;
}
/**
* Set the filter policy used for validation items.
*
* @param filter The filter policy.
*/
public void setPolicy(FilterPolicy filter) {
PreCon.notNull(filter);
_filter = filter;
if (_dataNode != null) {
_dataNode.set("policy", filter);
_dataNode.save();
}
}
/**
* Get the {@link ItemStackMatcher} used to match items.
*/
public ItemStackMatcher getItemStackMatcher() {
return _matcher;
}
/**
* Determine if the specified {@link org.bukkit.inventory.ItemStack} is valid.
*
* <p>Checks to see if the collection contains a matching {@link org.bukkit.inventory.ItemStack} as
* determined by the collections {@link ItemStackMatcher} and the filter policy.</p>
*
* @param item The item to check.
*/
public boolean isValid(ItemStack item) {
PreCon.notNull(item);
MatchableItem wrapper = _filterItems.get(new MatchableItem(item, _matcher));
if (wrapper == null)
return _filter == FilterPolicy.BLACKLIST;
return _filter == FilterPolicy.WHITELIST;
}
/**
* Get the set of matchable items from the collection.
*/
public Collection<MatchableItem> getMatchable() {
return CollectionUtils.unmodifiableSet(_filterItems.keySet());
}
/**
* Get the set of matchable items from the collection.
*/
public <T extends Collection<MatchableItem>> T getMatchable(T output) {
PreCon.notNull(output);
output.addAll(_filterItems.keySet());
return output;
}
/**
* Add an item to the collection.
*
* @param itemStack The item to add.
*/
public boolean add(ItemStack itemStack) {
PreCon.notNull(itemStack);
MatchableItem wrapper = new MatchableItem(itemStack, _matcher);
if (_filterItems.put(wrapper, wrapper) != null) {
save();
return true;
}
return false;
}
/**
* Add multiple items to the collection.
*
* @param itemStacks The items to add.
*/
public boolean add(ItemStack[] itemStacks) {
PreCon.notNull(itemStacks);
for (ItemStack stack : itemStacks) {
MatchableItem wrapper = new MatchableItem(stack, _matcher);
_filterItems.put(wrapper, wrapper);
}
save();
return true;
}
/**
* Remove an item from the collection.
*
* @param itemStack The item to remove.
*/
public boolean remove(ItemStack itemStack) {
PreCon.notNull(itemStack);
if (_filterItems.remove(new MatchableItem(itemStack, _matcher)) != null) {
save();
return true;
}
return false;
}
/**
* Remove multiple items from the collection.
*
* @param itemStacks The items to remove.
*/
public boolean remove(ItemStack[] itemStacks) {
PreCon.notNull(itemStacks);
for (ItemStack stack : itemStacks) {
_filterItems.remove(new MatchableItem(stack, _matcher));
}
save();
return true;
}
/**
* Remove all items from the collection.
*/
public boolean clear() {
_filterItems.clear();
if (_dataNode != null) {
_dataNode.set("items", null);
_dataNode.save();
}
return true;
}
private void save() {
if (_dataNode == null)
return;
Collection<MatchableItem> wrappers = _filterItems.values();
List<ItemStack> stacks = new ArrayList<ItemStack>(wrappers.size());
for (MatchableItem wrapper : wrappers) {
stacks.add(wrapper.getItem());
}
_dataNode.set("items", stacks.toArray(new ItemStack[stacks.size()]));
_dataNode.save();
}
private void load() {
if (_dataNode == null)
return;
_filter = _dataNode.getEnum("policy", _filter, FilterPolicy.class);
ItemStack[] craftItems = _dataNode.getItemStacks("items");
_filterItems.clear();
if (craftItems != null && craftItems.length > 0) {
for (ItemStack stack : craftItems) {
MatchableItem wrapper = new MatchableItem(stack, _matcher);
_filterItems.put(wrapper, wrapper);
}
}
}
}