usd.edu.btlbetsstatistics.BetsStatistics.java Source code

Java tutorial

Introduction

Here is the source code for usd.edu.btlbetsstatistics.BetsStatistics.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package usd.edu.btlbetsstatistics;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

/**
 * Determine how many fields are filled in the BETS specification of all tools
 * in the Bioinformatics Tools Library Database
 *
 * @author Shayla.Gustafson
 */
public class BetsStatistics {

    final static int FIRST_TOOL_ID = 3;
    final static int LAST_TOOL_ID = 22371;
    static List<Counter> counters = new ArrayList<>();

    public static void main(String[] args) {
        //        String inputFile = "C:\\Users\\Shayla.Gustafson\\Documents\\GitHub\\BTLBetsStatistics\\src\\main\\java\\usd\\edu\\testdata\\JSON100.json";
        //        String JsonString = readFile(inputFile);
        List<JSONObject> tools = createToolsListFromREST(); //Create a list of all BETS from the database using REST endpoint

        //To write all tools in database to individual JSON files...
        //        for (int i = 0; i < tools.size(); i++) {
        //            String path = "C:\\Users\\Shayla.Gustafson\\Desktop\\BETS_JSON_2\\" + i + ".json";
        //
        //            ObjectOutputStream outputStream = null;
        //            try {
        //                outputStream = new ObjectOutputStream(new FileOutputStream(path));
        //                System.out.println("Start Writings");
        //                outputStream.writeObject(tools.get(i).toString());
        //                outputStream.flush();
        //                outputStream.close();
        //            } catch (Exception e) {
        //                System.err.println("Error: " + e);
        //            }
        //        }
        //To count the attributes of each tool in database
        for (int i = 0; i < tools.size(); i++) {
            System.out.println("Tool " + i + ": " + tools.get(i).get("name"));
            try {
                // JSONObject object = new JSONObject(JsonString); 
                counters = combineLists(counters, analyzeObject(tools.get(i)));
            } catch (JSONException e) {
                System.out.println(i + ": " + tools.get(i).getClass());
                System.out.println(e.getMessage());
            }
        }

        //Just doing one tool-----------------------------------------
        //        JSONObject tool = tools.get(4805);
        //        System.out.println(tool);
        //        counters = combineLists(counters, analyzeObject(tool));
        //-----------------------------------------------------------
        //
        //
        //=======================================================================
        //===============PRINT RESULTS===========================================
        //=======================================================================
        System.out.println("Print Results:");
        for (Counter c : counters) {
            System.out.println(c.keyName + ": " + c.counter);
        }
    }

    /**
     * ReadFile reads the file specified by filename and then returns a
     * testString with the entire contents of the file.
     *
     * @param filename
     * @return
     */
    public static String readFile(String filename) {
        String json = null;
        try {
            byte[] encoded = Files.readAllBytes(Paths.get(filename));
            json = new String(encoded);
        } catch (IOException e) {
            System.err.println(e.getMessage());
            System.exit(-1);
        }
        return json;
    }

    /**
     * Creates a list of all JSONObjects in database using the RESTful endpoint
     * from the osmonds.usd.edu server. This is the list of BETS for all tools.
     *
     * @return List<JSONObject>
     */
    public static List<JSONObject> createToolsListFromREST() {
        List<JSONObject> list = new ArrayList<>();
        for (int i = FIRST_TOOL_ID; i <= LAST_TOOL_ID; i++) { //Calls REST one at a time for all tools in database 
            String output = "";
            try {
                //URL url = new URL("http://osmonds.usd.edu/BTL-REST/resources/bets/" + i);
                URL url = new URL("http://localhost:8080/BTL-REST/resources/bets/" + i);
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod("GET");
                conn.setRequestProperty("Accept", "application/json");

                if (conn.getResponseCode() != 200) { //Some Tools may have been removed from Database and id will not exist
                    throw new MalformedURLException("No Tool exists for id: " + i);
                    //return list;
                }
                BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));

                String line;
                while ((line = br.readLine()) != null) {
                    output += line; //Gets all of the bets specification returned by REST request 
                }
                conn.disconnect();
                JSONObject object = new JSONObject(output); //Turn it into a JSONObject and add to list
                list.add(object);
            } catch (MalformedURLException e) {
                //e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        return list;
    }

    /**
     * Creates a list of all JSONObjects within a given file. This is the list
     * of all BETS tools within the specific json file.
     *
     * @param allJsonFiles
     * @return List<JSONObject>
     */
    public static List<JSONObject> createToolsList(String allJsonFiles) {
        JSONObject allTools = new JSONObject(allJsonFiles); //allJsonFiles = json file with a list of all tools to analyze
        List<String> keys = new ArrayList<>();
        Iterator objectKeys = allTools.keys();
        while (objectKeys.hasNext()) { //This file should only contain one key ("results")
            Object curr = objectKeys.next();
            keys.add(curr.toString());
        }
        //should now have one key = "results"
        JSONArray results = allTools.getJSONArray(keys.get(0));
        List<JSONObject> list = new ArrayList<>();
        for (int i = 0; i < results.length(); i++) {
            JSONObject current = results.getJSONObject(i); //Get all the tools and create JSONObjects 
            list.add(current);
        }
        return list;
    }

    /**
     * Recursive function to determine the keys on the given JSONObject and
     * create a list counting the keys that have a value associated with them.
     *
     * @param object
     * @return List<Counter>
     */
    private static List<Counter> analyzeObject(JSONObject object) {
        List<Counter> list = new ArrayList<>();
        try {
            // -----------------------------------------------------------------
            // Check what type of attribute each key represents and increment that counter
            // -----------------------------------------------------------------
            JSONArray keys2 = object.names();
            for (int i = 0; i < keys2.length(); i++) {

                String currKey = keys2.get(i).toString();
                JSONArray testArray = object.optJSONArray(currKey);
                String testString = object.optString(currKey);
                Boolean testBoolean = object.optBoolean(currKey);
                double testDouble = object.optDouble(currKey, -123456); //arbitrary default to default to
                int testInt = object.optInt(currKey, -123456); //arbitrary default to default to 
                long testLong = object.optLong(currKey, -123456); //arbitrary default to default to
                JSONObject testObject = object.optJSONObject(currKey);
                if (testArray != null && testArray.length() > 0) {
                    list = addOrIncrementCounter(list, currKey);
                    for (int j = 0; j < testArray.length(); j++) {
                        if (testArray.get(j).getClass() == JSONObject.class) {
                            List<Counter> list2 = analyzeObject(testArray.getJSONObject(j));
                            for (Counter c : list2) {
                                c.keyName = currKey + "-" + c.keyName;
                            }
                            list = combineLists(list, list2);
                        }
                    }
                } else if (testObject != null) {
                    list = addOrIncrementCounter(list, currKey);
                    //do the recursive stuff
                    List<Counter> list2 = analyzeObject(testObject);
                    for (Counter c : list2) {
                        c.keyName = currKey + "-" + c.keyName;
                    }
                    list = combineLists(list, list2);
                } else if (testString != null && testString.length() > 0 && !testString.equals("[]")) {
                    list = addOrIncrementCounter(list, currKey);
                    //Boolean values return false even when empty - only boolean fields are within Inputs
                    //                } else if (testBoolean != null) {
                    //                      list = addOrIncrementCounter(list, currKey);
                } else if (testDouble != -123456 || testInt != -123456 || testLong != -123456) {
                    list = addOrIncrementCounter(list, currKey);
                }
            }
        } catch (Exception e) {
            System.out.println("Oops: " + object.toString() + ", e: " + e);
        }
        return list;
    }

    /**
     * Increments the Counter with the given key name. If Counter does not
     * exist, creates a new Counter and sets value to 1.
     *
     * @param list
     * @param currKey
     * @return List<Counter>
     */
    private static List<Counter> addOrIncrementCounter(List<Counter> list, String currKey) {
        for (Counter c : list) {
            if (c.keyName.equals(currKey)) {
                c.counter++;
                return list;
            }
        }
        //This Counter doesn't yet exist in list - create new one and start at 1
        Counter newCounter = new Counter(currKey, 1);
        list.add(newCounter);
        return list;
    }

    /**
     * Combines list and list2 into one list of Counter objects. Combines the
     * counts of the Counter objects if same Counter exists in both lists.
     *
     * @param list
     * @param list2
     * @return List<Counter>
     */
    private static List<Counter> combineLists(List<Counter> list, List<Counter> list2) {
        for (Counter c : list2) {
            if (list.contains(c)) {
                for (Counter d : list) {
                    if (d.equals(c)) {
                        d.counter += c.counter;
                    }
                }
            } else {
                list.add(c);
            }
        }
        return list;
    }

    /**
     * Helper class for BetsStatistics that holds a keyName and counter.
     */
    public static class Counter {

        private String keyName;
        private int counter;

        public Counter() {
        }

        public Counter(String keyName, int counter) {
            this.keyName = keyName;
            this.counter = counter;
        }

        public String getKeyName() {
            return keyName;
        }

        public void setKeyName(String keyName) {
            this.keyName = keyName;
        }

        public int getCounter() {
            return counter;
        }

        public void setCounter(int counter) {
            this.counter = counter;
        }

        /**
         * Counters are the same if they have the same name.
         *
         * @param o
         * @return Boolean
         */
        @Override
        public boolean equals(Object o) {
            return ((Counter) o).keyName.equals(this.keyName);
        }
    }
}