1

Hello I have the following task:

A URL that has a JSON Object:

            - Write a program to read/write URL

            - Parse data in URL using JSON to JAVA Object

            - display 3 variables to user from the object

                            - Find entity/list of object = Find object that has ‘name’

                            - Find Object that has ‘author’

                            - Find Object that has ‘item’

*Define through annotation how to define JSON into Java list and find Object that has ‘name’ in it.

I think the question is asking to parse the JSON without using any java library. So far I have developed the following code:

class JSONObject {
    HashMap map = new HashMap();
}

public class SYW {
    public static String sampleUrl = "https://api.github.com/users/mralexgray/repos";
    public static Integer index = 1;

    public static void main(String[] args) {
        //String sampleJSON = fetchJSON(sampleUrl);
        JSONObject json = getJSONObject("{\"login\": \"mralexgray\",\"id\": 262517,\"avatar_url\": \"https://avatars.githubusercontent.com/u/262517?v=3\"}");
        // suppose there is a owner class
        populateJavaObject(json, Owner.class);
    }

    public static void populateJavaObject(JSONObject json, Class class1) {
        // TODO Auto-generated method stub
        Object obj = null;
        try {
            obj = class1.newInstance();
            Iterator it = json.map.keySet().iterator();
            while (it.hasNext()) {
                String key = (String)it.next();
                Object value = json.map.get(key);
                Field field = class1.getDeclaredField(key);
                field.setAccessible(true);
                if (value instanceof Integer) {
                    field.setInt(obj, (Integer)value);
                } else if (value instanceof String) {
                    field.setString(obj, (String)value);
                }
            }
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public static String getString(String jsonStr) {
        int i = index;
        StringBuffer buf = new StringBuffer();
        while (jsonStr.charAt(i) != '\"') {
            jsonStr.charAt(i);
            buf.append(jsonStr.charAt(i));
            i++;
        }
        index = i;
        return buf.toString();
    }

    public static JSONObject getJSONObject (String jsonStr) {
        StringBuffer buf = new StringBuffer();
        boolean isKey = true;
        String currentKey = "";
        Object currentValue = "";
        JSONObject json = new JSONObject();

        while (jsonStr.charAt(index) != '}') {
            if (jsonStr.charAt(index) == '\"') {
                index++;
                String token = getString(jsonStr);
                if (isKey) {
                    currentKey = token;
                } else {
                    currentValue = token;                       
                }
            } else if (Character.isDigit(jsonStr.charAt(index))) {
                Integer token = getNumber(jsonStr);
                currentValue = token;
            } else if (jsonStr.charAt(index) == '{') {
                currentValue = getJSONObject(jsonStr);
            } else if (jsonStr.charAt(index) == '[') {
                currentValue = getArray(jsonStr);
            } else if (jsonStr.charAt(index) == ':') {
                isKey = false;
            } else if (jsonStr.charAt(index) == ',' || jsonStr.charAt(index) == '}') {
                isKey = true;
                json.map.put(currentKey, currentValue);
            }
            index++;
        }

        return json;
    }

    private static ArrayList getArray(String jsonStr) {     
        ArrayList list = new ArrayList();
        while (jsonStr.charAt(index) != ']') {          
            index++;
        }
        return null;
    }

    private static Integer getNumber(String jsonStr) {
        // TODO Auto-generated method stub
        Integer num = 0;

        while (Character.isDigit(jsonStr.charAt(index))) {
            num = num * 10 + Integer.parseInt(jsonStr.charAt(index)+"");
            index++;
        }

        index--;

        return num;
    }

    public static Object parseJSON(String jsonStr) {
        Owner owner = new Owner();
        while (index <= jsonStr.length()) {
            if (jsonStr.charAt(index) == '{') {
                return getJSONObject(jsonStr);
            } else if (jsonStr.charAt(index) == '[') {
                return getArray(jsonStr);
            }
        }   

        return null;
    }

    public static String fetchJSON(String url) {
        String nextLine = "";
        try {
            URL sywURL = new URL(url);
            BufferedReader reader = new BufferedReader(new InputStreamReader(sywURL.openStream()));
            StringBuffer buf = new StringBuffer();          
            while ((nextLine = reader.readLine()) != null) {
                buf.append(nextLine);
            }
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return nextLine;
    }
}

What I am doing here is I have a JSONObject class which stores the JSON attributes in a map then I want to use reflection to populate any class.

For parsing the JSON, I am trying to create a mini FSM ( :) ), which parses the string using a for loop and based on the character it either parses the string or number or array token. I am using a non-generic map so that I can store object of any type.

I was thinking may be I can use template or something pattern where each node will have a recursive structure or will be a leaf node. But I am really confused how to represent that because each leaf node can have one attribute and value. How can I represent that? Besides Is this the only way to represent that or whatever I have done so far is in the right direction?

Secondly, if I parse the objects, then how can I store them? Obviously the task is to find elements based on different attribute values. So I can create probably a hashmap based on one key to serve the one such query. But then how can I create an efficient data structure that will allow me efficiently query based on different attributes?

Thirdly, I am not sure what this means "Define through annotation how to define JSON into Java list and find Object that has ‘name’ in it."

Please help.

Thanks

user1539343
  • 1,569
  • 6
  • 28
  • 45

1 Answers1

2

'I think the question is asking to parse the JSON without using any java library' - personally I take it as being the complete opposite.

Software engineering principle number 1 is 'Don't reinvent the wheel'.

I think 'Define through annotation how to define JSON into Java list and find Object that has ‘name’ in it.' is a strong hint to use the annotations with the Jackson parser - which would be the standard way to attack this problem. Jackson annotations

Lee
  • 738
  • 3
  • 13
  • Maybe the OP wants to build a parser for educational reasons, which is a valid reason – Sleiman Jneidi May 14 '16 at 20:37
  • 1
    He's being asked to 'read a url' and 'parse data', not 'write a parser' – Lee May 14 '16 at 20:39
  • This is an interview question from a company kind of which would require you to write your own code instead of utilizing a library / framework. – user1539343 May 15 '16 at 00:04
  • If they were that 'kind' of company I would find somewhere else to work. Seriously, if they consider using a library as 'cheating' you don't want to know. – Lee May 15 '16 at 00:07
  • This is a core java position. So they would require you to invent different new algorithms and data structures. They ask this kind of questions to see your thinking process and strength in core java. Most companies like Microsoft, Amazon, etc conduct this kind of interviews. – user1539343 May 15 '16 at 02:22
  • One of the popular questions is to reverse a string which could be done easily and expectedly using some java api / external libraries. – user1539343 May 15 '16 at 02:23