ConfigurationSerializable Class Example

Discussion in 'Plugin Development' started by Codisimus, Mar 18, 2013.

Thread Status:
Not open for further replies.
  1. Offline

    Codisimus

    For a while I have been attempting to use the ConfigurationSerializable API to make one of my classes serializable. The information at http://wiki.bukkit.org/Configuration_API_Reference is great but I still cannot figure it out. I have the serialize method completed:
    Code:
        @Override
        public Map<String, Object> serialize() {
            Map<String, Object> map = new TreeMap<String, Object>();
            map.put("Name", name);
     
            Map<String, Object> nestedMap = new HashMap<String, Object>();
            nestedMap.put("Days", days);
            nestedMap.put("Hours", hours);
            nestedMap.put("Minutes", minutes);
            nestedMap.put("Seconds", seconds);
            map.put("Reset", nestedMap);
     
            map.put("Global", global);
            map.put("RoundDownTime", round);
            map.put("NumberCollectiveLoots", numberCollectiveLoots);
            map.put("AutoLoot", autoLoot);
     
            nestedMap = new TreeMap<String, Object>();
            nestedMap.put("Upper", moneyUpper);
            nestedMap.put("Lower", moneyLower);
            map.put("Money", nestedMap);
     
            nestedMap = new TreeMap<String, Object>();
            nestedMap.put("Upper", expUpper);
            nestedMap.put("Lower", expLower);
            map.put("Exp", nestedMap);
     
            nestedMap = new TreeMap<String, Object>();
            nestedMap.put("Individual", new ArrayList<Loot>(lootTables[INDIVIDUAL]));
            for (int i = 1; i < 11; i++) {
                nestedMap.put("Coll" + i, new ArrayList<Loot>(lootTables[i]));
            }
            map.put("Loots", new ArrayList<Loot>(lootTables[INDIVIDUAL]));
     
            return map;
        }
    but I am confused with the deserialization.
    Code:
        public PhatLoot(Map<String, Object> map) {
            name = (String) map.get("Name");
     
            Map<String, Object> nestedMap = (Map<String, Object>) map.get("Reset");
            days = (Integer) nestedMap.get("Days");
            hours = (Integer) nestedMap.get("Hours");
            minutes = (Integer) nestedMap.get("Minutes");
            seconds = (Integer) nestedMap.get("Seconds");
     
            global = (Boolean) nestedMap.get("Global");
            round = (Boolean) nestedMap.get("RoundDownTime");
            numberCollectiveLoots = (Integer) nestedMap.get("NumberCollectiveLoots");
            autoLoot = (Boolean) nestedMap.get("AutoLoot");
     
            nestedMap = (Map<String, Object>) map.get("Money");
            moneyUpper = (Integer) nestedMap.get("Upper");
            moneyLower = (Integer) nestedMap.get("Lower");
     
            nestedMap = (Map<String, Object>) map.get("Exp");
            expUpper = (Integer) nestedMap.get("Upper");
            expLower = (Integer) nestedMap.get("Lower");
     
            nestedMap = (Map<String, Object>) map.get("Loots");
            Map<String, Object> lootMap = (Map<String, Object>) map.get("Individual");
            for (Object object : lootMap.values()) {
                lootTables[INDIVIDUAL].add(new Loot((Map<String, Object>) object));
            }
     
            int i = 1;
            for (int j = 1; j < 11; j++) {
                lootMap = (Map<String, Object>) map.get("Coll" + j);
                for (Object object : lootMap.values()) {
                    lootTables[j].add(new Loot((Map<String, Object>) object));
                }
            }
        }
    Should I have to cast everything?

    My other question concerns loading the map from file. Currently I have:

    Save:
    Code:
                File file = new File(dataFolder + File.separator + "PhatLoots"
                                    + File.separator + phatLoot.name + ".yml");
                file.createNewFile();
                plugin.getConfig().load(file);
                FileConfiguration config = plugin.getConfig();
                config.set(phatLoot.name, phatLoot);
                config.save(file);
    Load:
    Code:
    new PhatLoot((Map<String, Object>) YamlConfiguration.loadConfiguration(file).get(name));
    So I guess I am just wondering if all this casting is necessary or even correct. Also if any of this looks wrong or a round about way of doing things please let me know.

    If anyone out there has an example of how they accomplished this I am sure that will help me. Thanks.
     
  2. About your first question... YES you have to type-cast everything.
    Another way to do it, is to use YamlConfiguration. Put the Map in there. But that's not a good idea I think. Because the YamlConfiguration will do all kinds of other stuff, while you could just be type-casting everything :)

    About your second question. Saving looks good. Although, you should know... plugin.getConfig() gives you YamlConfiguration... which inherits from FileConfiguration.
    Loading looks weird. I think the saving could be cleaner too.

    Check the method getConfig and saveConfig in this example (lines 51 and 57).
    This is a class I created. If you give it a location, it converts it to a file name, and loads that .yml file.
    Every yml file contains exactly 1 object of type T.

    Basically all you need to know is this.

    Code:
    YamlConfiguration config = new YamlConfiguration();
    File file = new File("config.yml");
     
    config.save(file);
    config.load(file);
     
    config.get("object");
    config.set("object", object);
    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 31, 2016
Thread Status:
Not open for further replies.

Share This Page