package com.supaham.commons.bukkit.serializers;
import com.google.common.base.Preconditions;
import com.supaham.commons.bukkit.items.ItemMetaSerializer;
import com.supaham.commons.bukkit.utils.SerializationUtils;
import com.supaham.commons.utils.StringUtils;
import org.bukkit.Material;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.inventory.ItemStack;
import org.bukkit.material.MaterialData;
import org.jetbrains.annotations.Nullable;
import org.yaml.snakeyaml.Yaml;
import javax.annotation.Nonnull;
import pluginbase.config.serializers.Serializer;
import pluginbase.config.serializers.SerializerSet;
/**
* An {@link ItemStack} serializer that currently does not serialize fully, but deserializes
* fully. This serializer depends on {@link MaterialDataSerializer} used through {@link
* #getBaseItemStack(String, SerializerSet)}, and {@link ItemMetaSerializer} used to handle item
* metadata.
*
* @since 0.1
*/
public class ComplexItemStackSerializer implements Serializer<ItemStack> {
private static final Yaml yaml = new Yaml();
@Nullable
@Override
public Object serialize(ItemStack object, @Nonnull SerializerSet serializerSet) {
if (object == null) {
return null;
}
StringBuilder sb = new StringBuilder();
sb.append(object.getType());
if (object.getDurability() != 0) {
sb.append(':').append(object.getDurability());
}
sb.append(" ").append(object.getAmount());
sb.append(" ").append(yaml.dump(ItemMetaSerializer.serialize(object)));
return sb.toString();
}
@Nullable
@Override
public ItemStack deserialize(@Nullable Object serialized, @Nonnull Class wantedType,
@Nonnull SerializerSet serializerSet) {
if (serialized == null || !(serialized instanceof String)) {
return null;
}
String str = (String) serialized;
String[] split = str.split("\\s+", 3);
ItemStack item = getBaseItemStack(split[0], serializerSet);
if (split.length == 1 || item.getType() == Material.AIR) {
return item;
}
String metadata;
if (StringUtils.isNumeric(split[1])) { // amount is defined
item.setAmount(Integer.parseInt(split[1]));
if (split.length == 2) { // only amount was specified.
return item;
}
metadata = split[2];
} else { // Amount was not set, but metadata was.
metadata = split[1] + " " + split[2];
}
YamlConfiguration config = new YamlConfiguration();
try {
config.loadFromString(metadata);
} catch (InvalidConfigurationException e) {
e.printStackTrace();
return null;
}
return ItemMetaSerializer.deserialize(item, config.getValues(false));
}
protected ItemStack getBaseItemStack(String string, SerializerSet serializerSet) {
MaterialData data = SerializationUtils.deserializeWith(string, MaterialDataSerializer.class);
Preconditions.checkArgument(data != null, "Invalid material '" + string + "'.");
ItemStack item = data.toItemStack(1);
if (item == null) {
return new ItemStack(Material.AIR);
}
return item;
}
}