import com.jaivox.interpreter.*; import java.util.*; import java.io.*; import java.sql.*; public class SqliteCommand extends Command { String category; String function; // replace with your location static String dbfile = "/home/you/.mozilla/firefox/t8a8aqor.default/cookies.sqlite"; static String dbspec = "jdbc:sqlite:" + dbfile; Connection connection = null; Statement statement = null; boolean initialized = false; public SqliteCommand () { super (); boolean ok = setDriverParams (); if (!ok) { System.out.println ("Sqlite is not set up properly for this example."); return; } else initialized = true; } boolean setDriverParams () { try { // adapted from Xerial example // load the sqlite-JDBC driver using the current class loader Class.forName("org.sqlite.JDBC"); // is this the first time? see if the database file exists File test = new File (dbfile); boolean docreate = true; if (test.exists ()) docreate = false; // the following will create the file anyway connection = DriverManager.getConnection (dbspec); statement = connection.createStatement (); statement.setQueryTimeout (30); // set timeout to 30 sec. if (docreate) { String c1 = "create table action (procid string, reqid string, refid string, "; String c2 = "time string, type string, status string, detail string)"; statement.executeUpdate (c1+c2); } return true; } catch (Exception e) { System.err.println(e.getMessage()); e.printStackTrace (); return false; } } String executeQuery (String query) { // throws // QueryFailedException{ try { ResultSet rs = statement.executeQuery (query); ResultSetMetaData rsMetaData = rs.getMetaData (); int ncols = rsMetaData.getColumnCount (); StringBuffer sb = new StringBuffer (); while (rs.next()) { for (int i=1; i<=ncols; i++) { String s = rs.getString (i); if (i>1) sb.append (","); sb.append (s); } sb.append ("\n"); } String result = new String (sb); return result; } catch (Exception e) { e.printStackTrace (); return "Error"; } } public String handleCommand (Qapair p) { if (!initialized) { return "I cannot answer, since the database is not initialized."; } String arg = p.getArg (); StringTokenizer st = new StringTokenizer (arg, ",()"); category = ""; function = ""; if (st.hasMoreTokens ()) category = st.nextToken (); if (st.hasMoreTokens ()) function = st.nextToken (); // branching according to the extra information String result = ""; if (function.equals ("mostCookies")) { result = mostCookies (); } if (function.equals ("analyticRatio")) { result = analyticRatio (); } if (function.equals ("recentRatio")) { result = recentRatio (); } return result; } String mostCookies () { try { String query = "select baseDomain, count(*) as frequency "+ "from moz_cookies group by " + "baseDomain order by count(*) desc"; String data = executeQuery (query); StringTokenizer st = new StringTokenizer (data, ",\r\n"); if (!st.hasMoreTokens ()) { return "Seems like no site has placed cookies"; } String site = st.nextToken (); return site + " seems to have the most cookies."; } catch (Exception e) { e.printStackTrace (); return "There was an error in finding the site with the most cookies"; } } // gets the Google analytics cookies that start with __utm String analyticRatio () { try { String query = "select name from moz_cookies"; String data = executeQuery (query); StringTokenizer st = new StringTokenizer (data, "\n"); int n = st.countTokens (); if (n == 0) { return "Seems like nobody has any cookies"; } int count = 0; for (int i=0; i<n; i++) { String s = st.nextToken (); if (s.startsWith ("__utm")) count++; } String result = getRatioWords (count, n); return result +" of the cookies are for anlytics"; } catch (Exception e) { e.printStackTrace (); return "There was an error finding the proportion of analytic cookies"; } } String getRatioWords (int num, int denom) { double x = (double)num/(double)denom; if (x > 3.0/4.0) { return "more than three fourths"; } else if (x > 1.0/2.0) { return "more than half"; } else if (x > 1.0/3.0) { return "more than a third"; } else if (x > 1.0/4.0) { return "more than a fourth"; } else if (x > 1.0/5.0) { return "more than a fifth"; } else return "less than a fifth"; } // we will interpret recent to mean within a week of the // current day String recentRatio () { try { java.util.Date today = new java.util.Date (); long time = today.getTime (); long week = 7L * 24L * 60L * 60L * 1000L; long start = time - week; long check = start * 1000L; // microseconds String query = "select lastAccessed from moz_cookies"; String data = executeQuery (query); StringTokenizer st = new StringTokenizer (data, "\n"); int n = st.countTokens (); if (n == 0) { return "Seems like nobody has any cookies"; } int count = 0; for (int i=0; i<n; i++) { String s = st.nextToken (); Long when = Long.parseLong (s); if (when > check) count++; } String result = getRatioWords (count, n); return result +" of the cookies were modified within the last week"; } catch (Exception e) { e.printStackTrace (); return "There was some error determining proportion of recent cookies"; } } };