com.turt2live.xmail.mail.attachment.ItemAttachment.java Source code

Java tutorial

Introduction

Here is the source code for com.turt2live.xmail.mail.attachment.ItemAttachment.java

Source

/*******************************************************************************
 * Copyright (C) 2014 Travis Ralston (turt2live)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 ******************************************************************************/

package com.turt2live.xmail.mail.attachment;

import com.turt2live.xmail.XMail;
import com.turt2live.xmail.entity.XMailEntity;
import com.turt2live.xmail.entity.XMailPlayer;
import com.turt2live.xmail.mail.Mail;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.configuration.serialization.ConfigurationSerialization;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BookMeta;
import org.bukkit.inventory.meta.ItemMeta;
import org.json.simple.JSONValue;
import org.json.simple.parser.ContainerFactory;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

import java.util.*;
import java.util.Map.Entry;

public class ItemAttachment extends Attachment {

    /**
     * Represents a key used in JSON serialization (internal use)
     */
    public static final String CLASS_KEY = "XMAIL-SERIAL-DESERIAL-CLASS";

    private static final long serialVersionUID = -1476657368786253041L;

    private ItemStack item;

    public ItemAttachment(ItemStack item) {
        if (item == null) {
            throw new IllegalArgumentException();
        }
        this.item = item;
    }

    @Override
    public Attachment clone() {
        return new ItemAttachment(item);
    }

    @Override
    public Object getContent() {
        return item;
    }

    /**
     * Gets an EDITABLE item stack object.
     *
     * @return the item stack, editable
     */
    public ItemStack getItemStack() {
        return item;
    }

    @Override
    public Object getSerializedContent() {
        Map<String, Object> serial = item.serialize();
        if (serial.get("meta") != null) {
            ItemMeta itemmeta = item.getItemMeta();
            Map<String, Object> meta = itemmeta.serialize();
            Map<String, Object> meta2 = new HashMap<String, Object>();
            for (String key : meta.keySet()) {
                meta2.put(key, meta.get(key));
            }
            for (String key : meta2.keySet()) {
                Object o = meta2.get(key);
                if (o instanceof ConfigurationSerializable) {
                    ConfigurationSerializable serial1 = (ConfigurationSerializable) o;
                    Map<String, Object> serialed = recursiveSerialization(serial1);
                    meta2.put(key, serialed);
                }
            }
            meta = meta2;
            serial.put("meta", meta);
        }
        return JSONValue.toJSONString(serial);
    }

    @Override
    public AttachmentType getType() {
        return AttachmentType.ITEM;
    }

    @Override
    public boolean giveTo(XMailEntity entity) {
        if (entity instanceof XMailPlayer) {
            XMailPlayer xp = (XMailPlayer) entity;
            CommandSender sender = xp.getOwner();
            if (sender instanceof Player) {
                Player pl = (Player) sender;
                HashMap<Integer, ItemStack> overflow = pl.getInventory().addItem(item);
                if (overflow.isEmpty()) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public void onGive(XMailEntity to, Mail mail) {
        if (to instanceof XMailPlayer && item.getType() == XMail.EXPLOSIVE_MATERIAL
                && item.getDurability() == XMail.EXPLOSIVE_DATA_VALUE) {
            int explosive = item.getAmount();
            int explosionSize = explosive > 16 ? 16 : explosive;
            if (explosionSize > 0) {
                Player target = (Player) to.getOwner();
                Location loc = target.getLocation();
                target.getWorld().createExplosion(loc.getX(), loc.getY(), loc.getZ(), explosionSize * 2, false,
                        false);
                Random random = new Random(System.currentTimeMillis());
                for (int i = 0; i < 50; i++) {
                    target.playSound(loc, Sound.GHAST_SCREAM, 1.0f,
                            (random.nextFloat() - random.nextFloat()) * 0.2F + 1.0F);
                }
            }
        }
    }

    private Map<String, Object> recursiveSerialization(ConfigurationSerializable o) {
        Map<String, Object> map = o.serialize();
        Map<String, Object> map2 = new HashMap<String, Object>();
        for (String key : map.keySet()) {
            Object o2 = map.get(key);
            map2.put(key, o2);
            if (o2 instanceof ConfigurationSerializable) {
                ConfigurationSerializable serialObj = (ConfigurationSerializable) o2;
                Map<String, Object> newMap = recursiveSerialization(serialObj);
                newMap.put(CLASS_KEY, ConfigurationSerialization.getAlias(serialObj.getClass()));
                map2.put(key, newMap);
            }
        }
        map2.put(CLASS_KEY, ConfigurationSerialization.getAlias(o.getClass()));
        return map2;
    }

    @SuppressWarnings("unchecked")
    public static ItemAttachment deserializeFromJson(String content) {
        JSONParser parser = new JSONParser();
        ContainerFactory containerFactory = new ContainerFactory() {
            @Override
            public List<Object> creatArrayContainer() {
                return new LinkedList<Object>();
            }

            @Override
            public Map<String, Object> createObjectContainer() {
                return new LinkedHashMap<String, Object>();
            }

        };

        Map<String, Object> keys = new HashMap<String, Object>();

        try {
            Map<?, ?> json = (Map<?, ?>) parser.parse(content, containerFactory);
            Iterator<?> iter = json.entrySet().iterator();

            // Type check
            while (iter.hasNext()) {
                Entry<?, ?> entry = (Entry<?, ?>) iter.next();
                if (!(entry.getKey() instanceof String)) {
                    throw new IllegalArgumentException("Not in <String, Object> format");
                }
            }

            keys = (Map<String, Object>) json;
        } catch (ParseException e) {
            e.printStackTrace();
            return new ItemAttachment(new ItemStack(Material.GRASS, 1));
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
            return new ItemAttachment(new ItemStack(Material.GRASS, 1));
        }

        // Repair Gson thinking int == double
        if (keys.get("amount") != null) {
            Double d = (Double) keys.get("amount");
            Integer i = d.intValue();
            keys.put("amount", i);
        }

        ItemStack item = null;
        try {
            item = ItemStack.deserialize(keys);
        } catch (Exception e) {
            return null;
        }

        // Handle item meta
        if (keys.containsKey("meta")) {
            Map<String, Object> itemmeta = (Map<String, Object>) keys.get("meta");
            // Convert doubles -> ints
            itemmeta = recursiveDoubleToInteger(itemmeta);

            // Deserilize everything
            itemmeta = recursiveDeserialization(itemmeta);

            // Create the Item Meta
            ItemMeta meta = (ItemMeta) ConfigurationSerialization.deserializeObject(itemmeta,
                    ConfigurationSerialization.getClassByAlias("ItemMeta"));

            // Colorize everything
            if (meta.hasDisplayName()) {
                meta.setDisplayName(ChatColor.translateAlternateColorCodes('&', meta.getDisplayName()));
            }
            if (meta.hasLore()) {
                List<String> lore = meta.getLore();
                for (int i = 0; i < lore.size(); i++) {
                    String line = lore.get(i);
                    line = ChatColor.translateAlternateColorCodes('?', line);
                    line = ChatColor.translateAlternateColorCodes('&', line);
                    lore.set(i, line);
                }
                meta.setLore(lore);
            }
            if (meta instanceof BookMeta) {
                BookMeta book = (BookMeta) meta;
                if (book.hasAuthor()) {
                    book.setAuthor(ChatColor.translateAlternateColorCodes('&', book.getAuthor()));
                }
                if (book.hasTitle()) {
                    book.setTitle(ChatColor.translateAlternateColorCodes('&', book.getTitle()));
                }
                if (book.hasPages()) {
                    List<String> pages = new ArrayList<String>();
                    pages.addAll(book.getPages());
                    for (int i = 0; i < pages.size(); i++) {
                        String line = pages.get(i);
                        line = ChatColor.translateAlternateColorCodes('&', line);
                        pages.set(i, line);
                    }
                    book.setPages(pages);
                }
            }

            // Assign the item meta
            item.setItemMeta(meta);
        }
        return new ItemAttachment(item);
    }

    private static Map<String, Object> recursiveDeserialization(Map<String, Object> map) {
        Map<String, Object> map2 = new HashMap<String, Object>();
        for (String key : map.keySet()) {
            Object o = map.get(key);
            map2.put(key, o);
            if (o instanceof Map) {
                @SuppressWarnings("unchecked")
                Map<String, Object> map3 = (Map<String, Object>) o;
                if (map3.containsKey(CLASS_KEY)) {
                    String alias = (String) map3.get(CLASS_KEY);
                    Object deserialed = ConfigurationSerialization.deserializeObject(map3,
                            ConfigurationSerialization.getClassByAlias(alias));
                    map2.put(key, deserialed);
                } // else: ignore
            }
        }
        return map2;
    }

    private static Map<String, Object> recursiveDoubleToInteger(Map<String, Object> map) {
        Map<String, Object> map2 = new HashMap<String, Object>();
        for (String key : map.keySet()) {
            Object o = map.get(key);
            map2.put(key, o);
            if (o instanceof Double) {
                Double d = (Double) o;
                Integer i = d.intValue();
                map2.put(key, i);
            } else if (o instanceof Map) {
                @SuppressWarnings("unchecked")
                Map<String, Object> map3 = (Map<String, Object>) o;
                map2.put(key, recursiveDoubleToInteger(map3));
            }
        }
        return map2;
    }

}