Reading two of the same paths in a .yml file

Discussion in 'Plugin Development' started by CraterHater, Dec 30, 2016.

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

    CraterHater

    Alright so I got an issue.

    I am trying to read a .yml file. This.yml file looks like this:
    http://imgur.com/a/EsepA
    so I got this code to read the data from the first createObject:

    Code:
    public boolean read(String name, int act){
            if(getConfig().contains(name)){
                if(getConfig().contains(name + ".act" + act)){
                    //===============================================================//
                    //TEST FOR METHOD CREATEOBJECT AND GET REQUIREMENTS
                    //===============================================================//
                    if(getConfig().contains(name + ".act" + act + ".createObject")){
                        ArrayList<ItemStack> equipment = new ArrayList<ItemStack>();
                        Location loc = null;
                        String ename = null;
                      
                        if(getConfig().contains(name + ".act" + act + ".createObject.equipment")){
                            String s = getConfig().getString(name + ".act" + act + ".createObject.equipment");
                            String[] t = s.split(",");
                            for(String part : t){
                                Material m = Material.getMaterial(part);
                                equipment.add(new ItemStack(m,1));
                            }
                        }
                        if(getConfig().contains(name + ".act" + act + ".createObject.location")){
                            String s = getConfig().getString(name + ".act" + act + ".createObject.location");
                            String[] t = s.split(",");
                          
                            String world = t[0];
                            if(isNumeric(t[1]) && isNumeric(t[2]) && isNumeric(t[3])){
                            int x = Integer.parseInt(t[1]);
                            int y = Integer.parseInt(t[2]);
                            int z = Integer.parseInt(t[3]);
                          
                            loc = new Location(Bukkit.getWorld(world),x,y,z);
                          
                            }else{
                                return false;
                            }
                               
                        }else{
                            return false;
                        }
                        if(getConfig().contains(name + ".act" + act + ".createObject.name")){
                            ename = getConfig().getString(name + ".act" + act + ".createObject.name");
                        }else{
                            return false;
                        }
                      
                        createObject(loc,ename,equipment);
                      
                    }
                }else{
                    return false;
                }
            }else{
                return false;
            }
            return false;
        }
    but now I also want to read the second and do the same with it. How would I go about doing that?
    Thanks!
     
  2. Offline

    ShaneCraftDev

    @CraterHater
    You will have to create a YAML array, similar to the JSON object-array notation without the brackets.

    Say I want to have a YAML file contain a list of contracts and I want to translate those contracts to the following class to use in my application:
    Show Spoiler

    Code:java
    1.  
    2. public class Contract {
    3.  
    4. private final String name;
    5.  
    6. private final String caseOf;
    7.  
    8. private final Date date;
    9.  
    10. public Contract(String name, String caseOf, long timestamp) {
    11. this.name = name;
    12. this.caseOf = caseOf;
    13.  
    14. this.date = new Date(timestamp * 1000);
    15. }
    16.  
    17. public String getName() {
    18. return name;
    19. }
    20.  
    21. public String getCaseOf() {
    22. return caseOf;
    23. }
    24.  
    25. public Date getDate() {
    26. return date;
    27. }
    28.  
    29. @SuppressWarnings("deprecation")
    30. @Override
    31. public String toString() {
    32. return String.format("Contract by %s concerning the case %s on %s",
    33. name,
    34. caseOf,
    35. date.toLocaleString());
    36. }
    37. }
    38.  


    A contract always has the same keyvalue pairs. To save an object-array in YAML, you should to store all contracts in SETS. The YAML file would look like this:
    Show Spoiler

    Code:yaml
    1.  
    2. contracts:
    3. - case: ABC
    4. name: John Doe
    5. timestamp: 1483106575
    6. timezone: UTC
    7. - case: DEF
    8. name: Doe John
    9. timestamp: 1477905300
    10. timezone: UTC
    11.  


    Now to load such set into a list of usable objects it takes a lot of type checking to make sure the objects in the array are correctly set. Here is an example of how to parse the contracts set of the YAML file into a list of Contract objects:
    Show Spoiler

    Code:java
    1.  
    2. Object ymlContracts = ...;
    3. System.out.printf("contracts => class instance of: %s", ymlContracts.getClass().getSimpleName());
    4.  
    5. List<Contract> contracts = new ArrayList<>();
    6. if (ymlContracts instanceof List<?>) {
    7. for (Object contract : (List<?>) ymlContracts) {
    8. System.out.printf("contract => class instance of: %s", contract.getClass().getSimpleName());
    9.  
    10. if (contract instanceof Map<?, ?>) {
    11. Map<?, ?> map = (Map<?, ?>) contract;
    12. System.out.printf("map => content: %s", map.toString());
    13.  
    14. if (map.containsKey("name") &&
    15. map.containsKey("case") &&
    16. map.containsKey("timezone")) {
    17. // now we can establish a contract object
    18.  
    19. try {
    20. String name = map.get("name").toString();
    21. String caseOf = map.get("case").toString();
    22. Integer timestamp = (int)map.get("timestamp");
    23.  
    24. // String timezone = map.get("timezone").toString(); -- lets not parse the timezone
    25.  
    26. contracts.add(new Contract(name, caseOf, timestamp.longValue()));
    27. } catch(Exception ex) { // InvalidCastException is for C#, don't know what to set here for Java
    28. // invalid cast, some fields are not what they suppose to be
    29. System.err.println("invalid cast");
    30. System.out.println(ex.getMessage());
    31. }
    32. }
    33. }
    34. }
    35. }
    36.  
    37. for (Contract contract : contracts) {
    38. System.out.println(contract);
    39. }
    40.  


    The following should print:
    Code:
    [15:55:01 INFO]: Contract by John Doe concerning the case ABC on 30-dec-2016 15:02:55
    [15:55:01 INFO]: Contract by Doe John concerning the case DEF on 31-okt-2016 10:15:00
    
     
  3. Offline

    CraterHater

    @ShaneCraftDev
    Thanks for your response!

    But what if case: "ABC" and case: "DEF" are similar. If they are both named "ABC" by the user. My .yml file will be edited by the user and in most cases, this will be how it is ^
     
  4. Offline

    ShaneCraftDev

    @CraterHater
    How would that be an issue? case is the key and ABC | DEF is the value. Nothing has to be unique here, duplicates can exist. Instead of an object with unique keys, you now have an object-array. Thus being able to have the same keys in each object of the array.
     
Thread Status:
Not open for further replies.

Share This Page