0

I found this answer and I think it applies, but with a little twist.

How to return multiple objects from a Java method?

I have two JSON formatted files using the YML subset, one of which is a list of devices, and the other is a file that lists the attributes of a particular type of device.

The choice of dividing up the list of Device instances into one file and the attributes in another file is to allow the Device manufacturer to change the attributes without having to go back and rewrite/recompile hard coded attributes.

In any case, I could use two different calls to the JSONParser and then add the list of attributes to the Device object in the end, but that solution seems like a waste of code since, except for the inner part of the while loop where the values are set, they do exactly the same thing.

I thought something like a Ruby-ish Yield might do the trick in the inner loop, but not sure if this exists in Java.

So, without much further ado, here is the code:

// Import the json simple parser, used to read configuration files
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import org.json.simple.parser.*;

public  class LoadJson {

    private String path = "";
    private String fileType = "";

    //public LoadJson(String path, String fileType){

        //this.path = path;
        //this.fileType = fileType;

    //}

    public static Device openJSON(String fileType, String deviceName) {
        JSONParser parser = new JSONParser();
        Device myDevice = new Device();

        ContainerFactory containerFactory = new ContainerFactory(){
            public List creatArrayContainer() {
              return new LinkedList();
            }

        public Map createObjectContainer() {
          return new LinkedHashMap();
        }

      };

      try {
            File appBase = new File("."); //current directory
            String path = appBase.getAbsolutePath();
            System.out.println(path);

            Map obj = (Map)parser.parse(new FileReader(path+fileType),containerFactory);

            Iterator iter = obj.entrySet().iterator();

            //Iterator iterInner = new Iterator();

            while(iter.hasNext()){
                //LinkedList entry = (LinkedList)iter.next();
                LinkedList myList = new LinkedList(); 
                Map.Entry entry = (Map.Entry)iter.next();

                myList = (LinkedList) (entry.getValue());

                Iterator iterate = myList.iterator();
                while (iterate.hasNext())
                {
                    LinkedHashMap entry2 = (LinkedHashMap)iterate.next();
                    if(fileType=="mav2opc")
                            {
                             String deviceName1 = entry2.get("DeviceName").toString();
                             String userName = entry2.get("UserName").toString();
                             String password = entry2.get("Password").toString();
                             String deviceType = entry2.get("DeviceType").toString();
                             String ipAddress = entry2.get("IPAddress").toString();
                             myDevice = new Device(deviceName1, userName, password, deviceType,ipAddress);
                             openJSON(deviceType,deviceName1);
                             System.out.println(myDevice);
                            } else
                            {
                                //Add a tag
                                String tagName = entry2.get("tagName").toString();
                                String tagType = entry2.get("tagType").toString();
                                String tagXPath = entry2.get("tagXPath").toString();
                                String tagWritable = entry2.get("tagWritable").toString();
                            }

                }
            } 

            //System.out.println("==toJSONString()==");
            //System.out.println(JSONValue.toJSONString(json));

      } catch (FileNotFoundException e) {
            e.printStackTrace();
      } catch (IOException e) {
            e.printStackTrace();
      } catch(ParseException pe){
            System.out.println(pe);
    }
      return myDevice;
}

}

Community
  • 1
  • 1
bentaisan
  • 1,056
  • 3
  • 12
  • 29
  • Also, perhaps the inner part of the loop can be passed as an anonymous function, or perhaps a decorator pattern could be used to add the functions to LoadJSON. – bentaisan Feb 22 '12 at 17:31
  • So the two files have the exact same structure? – Miserable Variable Feb 22 '12 at 18:05
  • No, the two files have different structures. There is a master list of Devices, and each device has a type. There is one Type file for each type, containing the attributes. – bentaisan Feb 22 '12 at 18:10
  • I am sorry, I meant that except for the names they have the same structure, a list of map in both cases. – Miserable Variable Feb 22 '12 at 18:17
  • How about creating a superclass called Loadable and then having both types of objects derive from the same class, with the proper functions overloaded? – bentaisan Feb 22 '12 at 18:36
  • Can you include a sample of the per-device file? It seems to me that you are reading only one map from it. Actually you are reading into local variables and discarding them so I am not sure how you intend to use what you read from that file – Miserable Variable Feb 22 '12 at 22:22

1 Answers1

1

Ok, so you have two files, one with list of devices and the other, per-device file, which has attributes of the device. The structures of the two files is exactly same, I am guessing something like

The devices file:

{{"DeviceName:"d1","UserName":"u1","Password":"p1","DeviceType":"t1","IPAddress":"i1"},
 {"DeviceName:"d2","UserName":"u2","Password":"p2","DeviceType":"t2","IPAddress":"ir"}}

And the per-device file

{{"tagName:"n1","tagType":"t1","tagXPath":"X1","tagWritable":true}}

In the per-device file there is only one map, though it is inside a list. The processing logic is to open the file, create the parser, read json and for each entry in the list process the map.

The logic for processing the map is the only difference between the two. Note that right now you are discarding what you read from the per-device file, which you will have to store somewhere in the myDevice

One way to do this is using a callback: create an interface MapHandler that has a method process. openJSON takes a parameter of this type and calls process on it for each method.

The device-level handler can be constructed with the myDevice being processed and set the fields.

Miserable Variable
  • 28,432
  • 15
  • 72
  • 133