Refactor Prov DB handling
[dmaap/datarouter.git] / datarouter-prov / src / main / java / org / onap / dmaap / datarouter / reports / FeedReport.java
index a3e15dc..3c63c28 100644 (file)
@@ -7,9 +7,9 @@
  * * Licensed under the Apache License, Version 2.0 (the "License");\r
  * * you may not use this file except in compliance with the License.\r
  * * You may obtain a copy of the License at\r
- * * \r
+ * *\r
  *  *      http://www.apache.org/licenses/LICENSE-2.0\r
- * * \r
+ * *\r
  *  * Unless required by applicable law or agreed to in writing, software\r
  * * distributed under the License is distributed on an "AS IS" BASIS,\r
  * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
@@ -37,10 +37,9 @@ import java.util.Arrays;
 import java.util.Calendar;\r
 import java.util.Date;\r
 import java.util.GregorianCalendar;\r
-\r
 import org.json.JSONException;\r
 import org.json.JSONObject;\r
-import org.onap.dmaap.datarouter.provisioning.utils.DB;\r
+import org.onap.dmaap.datarouter.provisioning.utils.ProvDbUtils;\r
 \r
 /**\r
  * Generate a feeds report.  The report is a .CSV file.\r
@@ -49,346 +48,330 @@ import org.onap.dmaap.datarouter.provisioning.utils.DB;
  * @version $Id: FeedReport.java,v 1.2 2013/11/06 16:23:55 eby Exp $\r
  */\r
 public class FeedReport extends ReportBase {\r
-       private static final String SELECT_SQL =\r
-               // Note to use the time in the publish_id, use date(from_unixtime(substring(publish_id, 1, 10)))\r
-               // To just use month, substring(from_unixtime(event_time div 1000), 1, 7)\r
-               "select date(from_unixtime(event_time div 1000)) as date, type, feedid, delivery_subid, count(*) as count" +\r
-               " from LOG_RECORDS" +\r
-               " where type = 'pub' or type = 'del'" +\r
-               " group by date, type, feedid, delivery_subid";\r
-       private static final String SELECT_SQL_OLD =\r
-               "select PUBLISH_ID, TYPE, FEEDID, DELIVERY_SUBID from LOG_RECORDS where EVENT_TIME >= ? and EVENT_TIME <= ?";\r
 \r
-       @Override\r
-       public void run() {\r
-               boolean alg1 = true;\r
-               JSONObject jo = new JSONObject();\r
-               long start = System.currentTimeMillis();\r
-               StringBuilder sb = new StringBuilder();\r
-               try {\r
-                       DB db = new DB();\r
-                       @SuppressWarnings("resource")\r
-                       Connection conn = db.getConnection();\r
-                       PreparedStatement ps = conn.prepareStatement(SELECT_SQL);\r
-//                     ps.setLong(1, from);\r
-//                     ps.setLong(2, to);\r
-                       ResultSet rs = ps.executeQuery();\r
-                       while (rs.next()) {\r
-                               if (alg1) {\r
-                                       String date = rs.getString("date");\r
-                                       String type = rs.getString("type");\r
-                                       int feedid  = rs.getInt("feedid");\r
-                                       int subid   = type.equals("del") ? rs.getInt("delivery_subid") : 0;\r
-                                       int count   = rs.getInt("count");\r
-                                       sb.append(date + "," + type + "," + feedid + "," + subid + "," + count + "\n");\r
-                               } else {\r
-                                       String date = rs.getString("date");\r
-                                       JSONObject datemap = jo.optJSONObject(date);\r
-                                       if (datemap == null) {\r
-                                               datemap = new JSONObject();\r
-                                               jo.put(date, datemap);\r
-                                       }\r
-                                       int feed = rs.getInt("FEEDID");\r
-                                       JSONObject feedmap = datemap.optJSONObject(""+feed);\r
-                                       if (feedmap == null) {\r
-                                               feedmap = new JSONObject();\r
-                                               feedmap.put("pubcount", 0);\r
-                                               datemap.put(""+feed, feedmap);\r
-                                       }\r
-                                       String type = rs.getString("TYPE");\r
-                                       int count   = rs.getInt("count");\r
-                                       if (type.equals("pub")) {\r
-                                               feedmap.put("pubcount", count);\r
-                                       } else if (type.equals("del")) {\r
-                                               String subid = ""+rs.getInt("DELIVERY_SUBID");\r
-                                               feedmap.put(subid, count);\r
-                                       }\r
-                               }\r
-                       }\r
-                       rs.close();\r
-                       ps.close();\r
-                       db.release(conn);\r
-               } catch (SQLException e) {\r
-                       e.printStackTrace();\r
-               }\r
-               logger.debug("Query time: " + (System.currentTimeMillis()-start) + " ms");\r
-               try {\r
-                       PrintWriter os = new PrintWriter(outfile);\r
-                       if (alg1) {\r
-                               os.print("date,type,feedid,subid,count\n");\r
-                               os.print(sb.toString());\r
-                       } else {\r
-                               os.println(toHTML(jo));\r
-                       }\r
-                       os.close();\r
-               } catch (FileNotFoundException e) {\r
-                       System.err.println("File cannot be written: "+outfile);\r
-               }\r
-       }\r
+    @Override\r
+    public void run() {\r
+        boolean alg1 = true;\r
+        JSONObject jo = new JSONObject();\r
+        long start = System.currentTimeMillis();\r
+        StringBuilder sb = new StringBuilder();\r
+        try (Connection conn = ProvDbUtils.getInstance().getConnection();\r
+            PreparedStatement ps = conn.prepareStatement(\r
+                // Note to use the time in the publish_id, use date(from_unixtime(substring(publish_id, 1, 10)))\r
+                // To just use month, substring(from_unixtime(event_time div 1000), 1, 7)\r
+                "select date(from_unixtime(event_time div 1000)) as date, type, feedid, delivery_subid, count(*) "\r
+                    + "as count from LOG_RECORDS where type = 'pub' or type = 'del' group by date, type, feedid, delivery_subid")) {\r
+            try (ResultSet rs = ps.executeQuery()) {\r
+                while (rs.next()) {\r
+                    String date = rs.getString("date");\r
+                    String type = rs.getString("type");\r
+                    int feedid = rs.getInt("feedid");\r
+                    int subid = type.equals("del") ? rs.getInt("delivery_subid") : 0;\r
+                    int count = rs.getInt("count");\r
+                    sb.append(date + "," + type + "," + feedid + "," + subid + "," + count + "\n");\r
+                }\r
+            }\r
+        } catch (SQLException e) {\r
+            logger.error(e.toString());\r
+        }\r
+        logger.debug("Query time: " + (System.currentTimeMillis() - start) + " ms");\r
+        try (PrintWriter os = new PrintWriter(outfile)) {\r
+            os.print("date,type,feedid,subid,count\n");\r
+            os.print(sb.toString());\r
+        } catch (FileNotFoundException e) {\r
+            System.err.println("File cannot be written: " + outfile);\r
+            logger.error(e.toString());\r
+        }\r
+    }\r
+\r
+    public void run2() {\r
+        JSONObject jo = new JSONObject();\r
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");\r
+        long start = System.currentTimeMillis();\r
+        try (Connection conn = ProvDbUtils.getInstance().getConnection();\r
+            PreparedStatement ps = conn.prepareStatement(\r
+                "select PUBLISH_ID, TYPE, FEEDID, DELIVERY_SUBID from LOG_RECORDS "\r
+                    + "where EVENT_TIME >= ? and EVENT_TIME <= ?")) {\r
+            ps.setLong(1, from);\r
+            ps.setLong(2, to);\r
+            ps.setFetchSize(100000);\r
+            try(ResultSet rs = ps.executeQuery()) {\r
+                while (rs.next()) {\r
+                    String id = rs.getString("PUBLISH_ID");\r
+                    String date = sdf.format(new Date(getPstart(id)));\r
+                    JSONObject datemap = jo.optJSONObject(date);\r
+                    if (datemap == null) {\r
+                        datemap = new JSONObject();\r
+                        jo.put(date, datemap);\r
+                    }\r
+                    int feed = rs.getInt("FEEDID");\r
+                    JSONObject feedmap = datemap.optJSONObject("" + feed);\r
+                    if (feedmap == null) {\r
+                        feedmap = new JSONObject();\r
+                        feedmap.put("pubcount", 0);\r
+                        datemap.put("" + feed, feedmap);\r
+                    }\r
+                    String type = rs.getString("TYPE");\r
+                    if (type.equals("pub")) {\r
+                        try {\r
+                            int n = feedmap.getInt("pubcount");\r
+                            feedmap.put("pubcount", n + 1);\r
+                        } catch (JSONException e) {\r
+                            feedmap.put("pubcount", 1);\r
+                            logger.error(e.toString());\r
+                        }\r
+                    } else if (type.equals("del")) {\r
+                        String subid = "" + rs.getInt("DELIVERY_SUBID");\r
+                        try {\r
+                            int n = feedmap.getInt(subid);\r
+                            feedmap.put(subid, n + 1);\r
+                        } catch (JSONException e) {\r
+                            feedmap.put(subid, 1);\r
+                            logger.error(e.toString());\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+        } catch (SQLException e) {\r
+            logger.error(e.toString());\r
+        }\r
+        logger.debug("Query time: " + (System.currentTimeMillis() - start) + " ms");\r
+        try {\r
+            PrintWriter os = new PrintWriter(outfile);\r
+            os.println(toHTML(jo));\r
+            os.close();\r
+        } catch (FileNotFoundException e) {\r
+            System.err.println("File cannot be written: " + outfile);\r
+            logger.error(e.toString());\r
+        }\r
+    }\r
+\r
+    private long getPstart(String t) {\r
+        if (t.indexOf('.') > 0)\r
+            t = t.substring(0, t.indexOf('.'));\r
+        return Long.parseLong(t);\r
+    }\r
+\r
+    @SuppressWarnings("unused")\r
+    private static String toHTMLNested(JSONObject jo) {\r
+        StringBuilder s = new StringBuilder();\r
+        s.append("<table>\n");\r
+        s.append("<tr><th>Date</th><th>Feeds</th></tr>\n");\r
+        String[] dates = JSONObject.getNames(jo);\r
+        Arrays.sort(dates);\r
+        for (int i = dates.length - 1; i >= 0; i--) {\r
+            String date = dates[i];\r
+            JSONObject j2 = jo.getJSONObject(date);\r
+            String[] feeds = JSONObject.getNames(j2);\r
+            Arrays.sort(feeds);\r
+            s.append("<tr><td>" + date + "</td><td>");\r
+            s.append(feeds.length).append(feeds.length > 1 ? " Feeds\n" : " Feed\n");\r
+            s.append("<table>\n");\r
+            s.append("<tr><th>Feed ID</th><th>Publish Count</th><th>Subscriptions</th></tr>\n");\r
+            for (String feed : feeds) {\r
+                JSONObject j3 = j2.getJSONObject(feed);\r
+                String[] subs = JSONObject.getNames(j3);\r
+                Arrays.sort(subs);\r
+                s.append("<tr><td>" + feed + "</td>");\r
+                s.append("<td>" + j3.getInt("pubcount") + "</td>");\r
+                int scnt = j3.length() - 1;\r
+                s.append("<td>").append(scnt).append(" Subcription");\r
+                if (scnt > 1)\r
+                    s.append("s");\r
+                s.append("<table>\n");\r
+                s.append("<tr><th>Sub ID</th><th>Delivery Count</th></tr>\n");\r
+                for (String sub : subs) {\r
+                    if (!sub.equals("pubcount")) {\r
+                        s.append("<tr><td>" + sub + "</td>");\r
+                        s.append("<td>" + j3.getInt(sub) + "</td>");\r
+                        s.append("</td></tr>\n");\r
+                    }\r
+                }\r
+                s.append("</table>\n");\r
+\r
+                s.append("</td></tr>\n");\r
+            }\r
+            s.append("</table>\n");\r
+            s.append("</td></tr>\n");\r
+        }\r
+        s.append("</table>\n");\r
+        return s.toString();\r
+    }\r
 \r
-       public void run2() {\r
-               JSONObject jo = new JSONObject();\r
-               SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");\r
-               long start = System.currentTimeMillis();\r
-               try {\r
-                       DB db = new DB();\r
-                       @SuppressWarnings("resource")\r
-                       Connection conn = db.getConnection();\r
-                       PreparedStatement ps = conn.prepareStatement(SELECT_SQL_OLD);\r
-                       ps.setLong(1, from);\r
-                       ps.setLong(2, to);\r
-                       ps.setFetchSize(100000);\r
-                       ResultSet rs = ps.executeQuery();\r
-                       while (rs.next()) {\r
-                               String id   = rs.getString("PUBLISH_ID");\r
-                               String date = sdf.format(new Date(getPstart(id)));\r
-                               JSONObject datemap = jo.optJSONObject(date);\r
-                               if (datemap == null) {\r
-                                       datemap = new JSONObject();\r
-                                       jo.put(date, datemap);\r
-                               }\r
-                               int feed = rs.getInt("FEEDID");\r
-                               JSONObject feedmap = datemap.optJSONObject(""+feed);\r
-                               if (feedmap == null) {\r
-                                       feedmap = new JSONObject();\r
-                                       feedmap.put("pubcount", 0);\r
-                                       datemap.put(""+feed, feedmap);\r
-                               }\r
-                               String type = rs.getString("TYPE");\r
-                               if (type.equals("pub")) {\r
-                                       try {\r
-                                               int n = feedmap.getInt("pubcount");\r
-                                               feedmap.put("pubcount", n+1);\r
-                                       } catch (JSONException e) {\r
-                                               feedmap.put("pubcount", 1);\r
-                                       }\r
-                               } else if (type.equals("del")) {\r
-                                       String subid = ""+rs.getInt("DELIVERY_SUBID");\r
-                                       try {\r
-                                               int n = feedmap.getInt(subid);\r
-                                               feedmap.put(subid, n+1);\r
-                                       } catch (JSONException e) {\r
-                                               feedmap.put(subid, 1);\r
-                                       }\r
-                               }\r
-                       }\r
-                       rs.close();\r
-                       ps.close();\r
-                       db.release(conn);\r
-               } catch (SQLException e) {\r
-                       e.printStackTrace();\r
-               }\r
-               logger.debug("Query time: " + (System.currentTimeMillis()-start) + " ms");\r
-               try {\r
-                       PrintWriter os = new PrintWriter(outfile);\r
-                       os.println(toHTML(jo));\r
-                       os.close();\r
-               } catch (FileNotFoundException e) {\r
-                       System.err.println("File cannot be written: "+outfile);\r
-               }\r
-       }\r
-       private long getPstart(String t) {\r
-               if (t.indexOf('.') > 0)\r
-                       t = t.substring(0, t.indexOf('.'));\r
-               return Long.parseLong(t);\r
-       }\r
-       @SuppressWarnings("unused")\r
-       private static String toHTMLNested(JSONObject jo) {\r
-               StringBuilder s = new StringBuilder();\r
-               s.append("<table>\n");\r
-               s.append("<tr><th>Date</th><th>Feeds</th></tr>\n");\r
-               String[] dates = JSONObject.getNames(jo);\r
-               Arrays.sort(dates);\r
-               for (int i = dates.length-1; i >= 0; i--) {\r
-                       String date = dates[i];\r
-                       JSONObject j2 = jo.getJSONObject(date);\r
-                       String[] feeds = JSONObject.getNames(j2);\r
-                       Arrays.sort(feeds);\r
-                       s.append("<tr><td>"+date+"</td><td>");\r
-                       s.append(feeds.length).append(feeds.length > 1 ? " Feeds\n" : " Feed\n");\r
-                       s.append("<table>\n");\r
-                       s.append("<tr><th>Feed ID</th><th>Publish Count</th><th>Subscriptions</th></tr>\n");\r
-                       for (String feed : feeds) {\r
-                               JSONObject j3 = j2.getJSONObject(feed);\r
-                               String[] subs = JSONObject.getNames(j3);\r
-                               Arrays.sort(subs);\r
-                               s.append("<tr><td>"+feed+"</td>");\r
-                               s.append("<td>"+j3.getInt("pubcount")+"</td>");\r
-                               int scnt = j3.length()-1;\r
-                               s.append("<td>").append(scnt).append(" Subcription");\r
-                               if (scnt > 1)\r
-                                       s.append("s");\r
-                               s.append("<table>\n");\r
-                               s.append("<tr><th>Sub ID</th><th>Delivery Count</th></tr>\n");\r
-                               for (String sub : subs) {\r
-                                       if (!sub.equals("pubcount")) {\r
-                                               s.append("<tr><td>"+sub+"</td>");\r
-                                               s.append("<td>"+j3.getInt(sub)+"</td>");\r
-                                               s.append("</td></tr>\n");\r
-                                       }\r
-                               }\r
-                               s.append("</table>\n");\r
+    private static String toHTML(JSONObject jo) {\r
+        StringBuilder s = new StringBuilder();\r
+        s.append("<table>\n");\r
+        s.append("<tr><th>Date</th><th>Feeds</th><th>Feed ID</th><th>Publish Count</th><th>Subs</th><th>Sub ID</th><th>Delivery Count</th></tr>\n");\r
+        String[] dates = JSONObject.getNames(jo);\r
+        Arrays.sort(dates);\r
+        for (int i = dates.length - 1; i >= 0; i--) {\r
+            String date = dates[i];\r
+            JSONObject j2 = jo.getJSONObject(date);\r
+            int rc1 = countrows(j2);\r
+            String[] feeds = JSONObject.getNames(j2);\r
+            Arrays.sort(feeds);\r
+            s.append("<tr><td rowspan=\"" + rc1 + "\">")\r
+                .append(date)\r
+                .append("</td>");\r
+            s.append("<td rowspan=\"" + rc1 + "\">")\r
+                .append(feeds.length)\r
+                .append("</td>");\r
+            String px1 = "";\r
+            for (String feed : feeds) {\r
+                JSONObject j3 = j2.getJSONObject(feed);\r
+                int pubcount = j3.getInt("pubcount");\r
+                int subcnt = j3.length() - 1;\r
+                int rc2 = (subcnt < 1) ? 1 : subcnt;\r
+                String[] subs = JSONObject.getNames(j3);\r
+                Arrays.sort(subs);\r
+                s.append(px1)\r
+                    .append("<td rowspan=\"" + rc2 + "\">")\r
+                    .append(feed)\r
+                    .append("</td>");\r
+                s.append("<td rowspan=\"" + rc2 + "\">")\r
+                    .append(pubcount)\r
+                    .append("</td>");\r
+                s.append("<td rowspan=\"" + rc2 + "\">")\r
+                    .append(subcnt)\r
+                    .append("</td>");\r
+                String px2 = "";\r
+                for (String sub : subs) {\r
+                    if (!sub.equals("pubcount")) {\r
+                        s.append(px2);\r
+                        s.append("<td>" + sub + "</td>");\r
+                        s.append("<td>" + j3.getInt(sub) + "</td>");\r
+                        s.append("</tr>\n");\r
+                        px2 = "<tr>";\r
+                    }\r
+                }\r
+                if (px2.equals(""))\r
+                    s.append("<td></td><td></td></tr>\n");\r
+                px1 = "<tr>";\r
+            }\r
+        }\r
+        s.append("</table>\n");\r
+        return s.toString();\r
+    }\r
 \r
-                               s.append("</td></tr>\n");\r
-                       }\r
-                       s.append("</table>\n");\r
-                       s.append("</td></tr>\n");\r
-               }\r
-               s.append("</table>\n");\r
-               return s.toString();\r
-       }\r
-       private static String toHTML(JSONObject jo) {\r
-               StringBuilder s = new StringBuilder();\r
-               s.append("<table>\n");\r
-               s.append("<tr><th>Date</th><th>Feeds</th><th>Feed ID</th><th>Publish Count</th><th>Subs</th><th>Sub ID</th><th>Delivery Count</th></tr>\n");\r
-               String[] dates = JSONObject.getNames(jo);\r
-               Arrays.sort(dates);\r
-               for (int i = dates.length-1; i >= 0; i--) {\r
-                       String date = dates[i];\r
-                       JSONObject j2 = jo.getJSONObject(date);\r
-                       int rc1 = countrows(j2);\r
-                       String[] feeds = JSONObject.getNames(j2);\r
-                       Arrays.sort(feeds);\r
-                       s.append("<tr><td rowspan=\"" + rc1 + "\">")\r
-                        .append(date)\r
-                        .append("</td>");\r
-                       s.append("<td rowspan=\"" + rc1 + "\">")\r
-                        .append(feeds.length)\r
-                        .append("</td>");\r
-                       String px1 = "";\r
-                       for (String feed : feeds) {\r
-                               JSONObject j3 = j2.getJSONObject(feed);\r
-                               int pubcount = j3.getInt("pubcount");\r
-                               int subcnt = j3.length()-1;\r
-                               int rc2 = (subcnt < 1) ? 1 : subcnt;\r
-                               String[] subs = JSONObject.getNames(j3);\r
-                               Arrays.sort(subs);\r
-                               s.append(px1)\r
-                                .append("<td rowspan=\"" + rc2 + "\">")\r
-                                .append(feed)\r
-                                .append("</td>");\r
-                               s.append("<td rowspan=\"" + rc2 + "\">")\r
-                                .append(pubcount)\r
-                                .append("</td>");\r
-                               s.append("<td rowspan=\"" + rc2 + "\">")\r
-                                .append(subcnt)\r
-                                .append("</td>");\r
-                               String px2 = "";\r
-                               for (String sub : subs) {\r
-                                       if (!sub.equals("pubcount")) {\r
-                                               s.append(px2);\r
-                                               s.append("<td>"+sub+"</td>");\r
-                                               s.append("<td>"+j3.getInt(sub)+"</td>");\r
-                                               s.append("</tr>\n");\r
-                                               px2 = "<tr>";\r
-                                       }\r
-                               }\r
-                               if (px2.equals(""))\r
-                                       s.append("<td></td><td></td></tr>\n");\r
-                               px1 = "<tr>";\r
-                       }\r
-               }\r
-               s.append("</table>\n");\r
-               return s.toString();\r
-       }\r
-       private static int countrows(JSONObject x) {\r
-               int n = 0;\r
-               for (String feed : JSONObject.getNames(x)) {\r
-                       JSONObject j3 = x.getJSONObject(feed);\r
-                       int subcnt = j3.length()-1;\r
-                       int rc2 = (subcnt < 1) ? 1 : subcnt;\r
-                       n += rc2;\r
-               }\r
-               return (n > 0) ? n : 1;\r
-       }\r
+    private static int countrows(JSONObject x) {\r
+        int n = 0;\r
+        for (String feed : JSONObject.getNames(x)) {\r
+            JSONObject j3 = x.getJSONObject(feed);\r
+            int subcnt = j3.length() - 1;\r
+            int rc2 = (subcnt < 1) ? 1 : subcnt;\r
+            n += rc2;\r
+        }\r
+        return (n > 0) ? n : 1;\r
+    }\r
 \r
-       /**\r
-        * Convert a .CSV file (as generated by the normal FeedReport mechanism) to an HTML table.\r
-        * @param args\r
-        */\r
-       public static void main(String[] args) {\r
-               int rtype = 0;  // 0 -> day, 1 -> week, 2 -> month, 3 -> year\r
-               String infile  = null;\r
-               String outfile = null;\r
-               for (int i = 0; i < args.length; i++) {\r
-                       if (args[i].equals("-t")) {\r
-                               switch (args[++i].charAt(0)) {\r
-                               case 'w':       rtype = 1; break;\r
-                               case 'm':       rtype = 2; break;\r
-                               case 'y':       rtype = 3; break;\r
-                               default:        rtype = 0; break;\r
-                               }\r
-                       } else if (infile == null) {\r
-                               infile = args[i];\r
-                       } else if (outfile == null) {\r
-                               outfile = args[i];\r
-                       }\r
-               }\r
-               if (infile == null) {\r
-                       System.err.println("usage: FeedReport [ -t <reporttype> ] [ <input .csv> ] [ <output .html> ]");\r
-                       System.exit(1);\r
-               }\r
-               try {\r
-                       JSONObject jo = new JSONObject();\r
-                       LineNumberReader lr = new LineNumberReader(new FileReader(infile));\r
-                       String line = lr.readLine();\r
-                       while (line != null) {\r
-                               String[] tt = line.split(",");\r
-                               if (tt[0].startsWith("2")) {\r
-                                       String date = tt[0];\r
-                                       switch (rtype) {\r
-                                       case 1:\r
-                                               String[] xx = date.split("-");\r
-                                               Calendar cal = new GregorianCalendar(new Integer(xx[0]), new Integer(xx[1])-1, new Integer(xx[2]));\r
-                                               date = xx[0] + "-W" + cal.get(Calendar.WEEK_OF_YEAR);\r
-                                               break;\r
-                                       case 2: date = date.substring(0, 7); break;\r
-                                       case 3: date = date.substring(0, 4); break;\r
-                                       }\r
-                                       JSONObject datemap = jo.optJSONObject(date);\r
-                                       if (datemap == null) {\r
-                                               datemap = new JSONObject();\r
-                                               jo.put(date, datemap);\r
-                                       }\r
-                                       int feed = Integer.parseInt(tt[2]);\r
-                                       JSONObject feedmap = datemap.optJSONObject(""+feed);\r
-                                       if (feedmap == null) {\r
-                                               feedmap = new JSONObject();\r
-                                               feedmap.put("pubcount", 0);\r
-                                               datemap.put(""+feed, feedmap);\r
-                                       }\r
-                                       String type = tt[1];\r
-                                       int count   = Integer.parseInt(tt[4]);\r
-                                       if (type.equals("pub")) {\r
-                                               try {\r
-                                                       int n = feedmap.getInt("pubcount");\r
-                                                       feedmap.put("pubcount", n+count);\r
-                                               } catch (JSONException e) {\r
-                                                       feedmap.put("pubcount", count);\r
-                                               }\r
-                                       } else if (type.equals("del")) {\r
-                                               String subid = tt[3];\r
-                                               try {\r
-                                                       int n = feedmap.getInt(subid);\r
-                                                       feedmap.put(subid, n+count);\r
-                                               } catch (JSONException e) {\r
-                                                       feedmap.put(subid, count);\r
-                                               }\r
-                                       }\r
-                               }\r
-                               line = lr.readLine();\r
-                       }\r
-                       lr.close();\r
-                       String t = toHTML(jo);\r
-                       switch (rtype) {\r
-                       case 1: t = t.replaceAll("<th>Date</th>", "<th>Week</th>"); break;\r
-                       case 2: t = t.replaceAll("<th>Date</th>", "<th>Month</th>"); break;\r
-                       case 3: t = t.replaceAll("<th>Date</th>", "<th>Year</th>"); break;\r
-                       }\r
-                       System.out.println(t);\r
-               } catch (Exception e) {\r
-                       System.err.println(e);\r
-                       e.printStackTrace();\r
-               }\r
-       }\r
+    /**\r
+     * Convert a .CSV file (as generated by the normal FeedReport mechanism) to an HTML table.\r
+     *\r
+     * @param args\r
+     */\r
+    public void main(String[] args) {\r
+        int rtype = 0;    // 0 -> day, 1 -> week, 2 -> month, 3 -> year\r
+        String infile = null;\r
+        String outfile = null;\r
+        for (int i = 0; i < args.length; i++) {\r
+            if (args[i].equals("-t")) {\r
+                switch (args[++i].charAt(0)) {\r
+                    case 'w':\r
+                        rtype = 1;\r
+                        break;\r
+                    case 'm':\r
+                        rtype = 2;\r
+                        break;\r
+                    case 'y':\r
+                        rtype = 3;\r
+                        break;\r
+                    default:\r
+                        rtype = 0;\r
+                        break;\r
+                }\r
+            } else if (infile == null) {\r
+                infile = args[i];\r
+            } else if (outfile == null) {\r
+                outfile = args[i];\r
+            }\r
+        }\r
+        if (infile == null) {\r
+            System.err.println("usage: FeedReport [ -t <reporttype> ] [ <input .csv> ] [ <output .html> ]");\r
+            System.exit(1);\r
+        }\r
+        try {\r
+            JSONObject jo = new JSONObject();\r
+            try(LineNumberReader lr = new LineNumberReader(new FileReader(infile))) {\r
+                String line = lr.readLine();\r
+                while (line != null) {\r
+                    String[] tt = line.split(",");\r
+                    if (tt[0].startsWith("2")) {\r
+                        String date = tt[0];\r
+                        switch (rtype) {\r
+                            case 1:\r
+                                String[] xx = date.split("-");\r
+                                Calendar cal = new GregorianCalendar(new Integer(xx[0]), new Integer(xx[1]) - 1, new Integer(xx[2]));\r
+                                date = xx[0] + "-W" + cal.get(Calendar.WEEK_OF_YEAR);\r
+                                break;\r
+                            case 2:\r
+                                date = date.substring(0, 7);\r
+                                break;\r
+                            case 3:\r
+                                date = date.substring(0, 4);\r
+                                break;\r
+                        }\r
+                        JSONObject datemap = jo.optJSONObject(date);\r
+                        if (datemap == null) {\r
+                            datemap = new JSONObject();\r
+                            jo.put(date, datemap);\r
+                        }\r
+                        int feed = Integer.parseInt(tt[2]);\r
+                        JSONObject feedmap = datemap.optJSONObject("" + feed);\r
+                        if (feedmap == null) {\r
+                            feedmap = new JSONObject();\r
+                            feedmap.put("pubcount", 0);\r
+                            datemap.put("" + feed, feedmap);\r
+                        }\r
+                        String type = tt[1];\r
+                        int count = Integer.parseInt(tt[4]);\r
+                        if (type.equals("pub")) {\r
+                            try {\r
+                                int n = feedmap.getInt("pubcount");\r
+                                feedmap.put("pubcount", n + count);\r
+                            } catch (JSONException e) {\r
+                                feedmap.put("pubcount", count);\r
+                                logger.error(e.toString());\r
+                            }\r
+                        } else if (type.equals("del")) {\r
+                            String subid = tt[3];\r
+                            try {\r
+                                int n = feedmap.getInt(subid);\r
+                                feedmap.put(subid, n + count);\r
+                            } catch (JSONException e) {\r
+                                feedmap.put(subid, count);\r
+                                logger.error(e.toString());\r
+                            }\r
+                        }\r
+                    }\r
+                    line = lr.readLine();\r
+                }\r
+            }\r
+            String t = toHTML(jo);\r
+            switch (rtype) {\r
+                case 1:\r
+                    t = t.replaceAll("<th>Date</th>", "<th>Week</th>");\r
+                    break;\r
+                case 2:\r
+                    t = t.replaceAll("<th>Date</th>", "<th>Month</th>");\r
+                    break;\r
+                case 3:\r
+                    t = t.replaceAll("<th>Date</th>", "<th>Year</th>");\r
+                    break;\r
+            }\r
+            System.out.println(t);\r
+        } catch (Exception e) {\r
+            System.err.println(e);\r
+            logger.error(e.toString());\r
+        }\r
+    }\r
 }\r