package com.kkazmierczyk.freestyle; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.Writer; import java.util.ArrayList; import java.util.List; import javax.persistence.EntityManagerFactory; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * * This servlet displays overall statistics refered to whole tree * * @version $Id: StatisticsServlet.java 37 2008-06-03 20:31:47Z kazik $ */ public class StatisticsServlet extends HttpServlet { private static final String MOST_VISITED_NODES = "Most visited nodes"; /** Number of results displayed in statistics of most visited nodes */ private static final int VISITED_NODES_DISPLAY_NO = 10; private static final String OVERALL_NODES = "Number of all nodes visited on each level"; private static final String DEEPEST_VISITED_NODES = "Deepest visited nodes"; private static final String TITLE = "Statistics"; private Bots bots = null; private EntityManagerFactory emf = null; /** * * Displays html table with input data witch overall statistics * * @param writer * Writer to which display data * @param dataToDisplayByLevel * @throws IOException */ private void displaylevelStatsDataTable(final Writer writer, int[][] dataToDisplayByLevel) throws IOException { writer.write("<table>"); writer.write("<tr><th>level</th>"); for (Bot bot : bots.getBots()) { writer.write("<th>" + bot.getName() + "</th>"); } writer.write("</tr>"); for (int i = 0; i < dataToDisplayByLevel[0].length; i++) { writer.write("<tr>"); writer.write("<td>" + i + "</td>"); for (int j = 0; j < dataToDisplayByLevel.length; j++) { writer.write("<td>" + dataToDisplayByLevel[j][i] + "</td>"); } writer.write("</tr>"); } writer.write("</table>"); } private void displayMostVisitedNodes(Writer writer, int displayResultsNO) throws IOException { writer.write("<h2>" + MOST_VISITED_NODES + "</h2>"); writer.write("<table><tr>"); for (Bot bot : bots.getBots()) { writer.write("<th>" + bot.getName() + "</th>"); } writer.write("</tr><tr>"); for (Bot bot : bots.getBots()) { writer.write("<td>" + displayStatsTableOfOneAgent(DataManager .getMostVisitedNodes(emf, bot.getAgent(), displayResultsNO)) + "</td>"); } writer.write("</tr></table>"); } private String displayStatsTableOfOneAgent(List<Object[]> mostVisitedNodes) { StringBuilder result = new StringBuilder("<table>"); for (Object[] objects : mostVisitedNodes) { result.append("<tr><td><a href=\" ").append(objects[0]).append( " \"> ").append(objects[0]).append(" </a></td><td>") .append(objects[1]).append("</td></tr>"); } // to pass w3c test validation if (mostVisitedNodes.size() == 0) { result.append("<tr><td></td></tr>"); } result.append("</table>"); return result.toString(); } /** * Retrieves and displays statistics of number of visited nodes by level in * the tree * * @param writer * Output to which write results * @throws IOException */ private void displayStatsNodesByLevel(final Writer writer) throws IOException { writer.write("<h2>" + OVERALL_NODES + "</h2>"); // preparing data to effective display List<List<Object[]>> allBotsresult = new ArrayList<List<Object[]>>(); for (Bot bot : bots.getBots()) { allBotsresult.add(DataManager.getNodeNumberVisitedByLevel(emf, bot .getAgent())); } int[][] dataToDisplayByLevel = prepareToDisplayByLevel(allBotsresult); displaylevelStatsDataTable(writer, dataToDisplayByLevel); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { final Writer writer = new OutputStreamWriter(resp.getOutputStream(), "utf-8"); writer.write(MainServlet.DOCTYPE + "<html><head>" + "<meta http-equiv=\"content-type\" content=\"utf-8\">" + "<title>" + TITLE + "</title>" + "<meta name=\"robots\" content=\"none\"></head><body>"); displayStatsNodesByLevel(writer); writer.write("<p>"); displayMostVisitedNodes(writer, VISITED_NODES_DISPLAY_NO); writer.write("<p>"); displayDeepestVisitedNodes(writer, VISITED_NODES_DISPLAY_NO); writer.write("</body></html>"); writer.close(); } private void displayDeepestVisitedNodes(Writer writer, int visitedNodesDisplayNo) throws IOException { writer.write("<h2>" + DEEPEST_VISITED_NODES + "</h2>"); writer.write("<table><tr>"); for (Bot bot : bots.getBots()) { writer.write("<th>" + bot.getName() + "</th>"); } writer.write("</tr><tr>"); for (Bot bot : bots.getBots()) { writer.write("<td>" + displayStatsTableOfOneAgent(DataManager .getDeepstVisitedNodes(emf, bot.getAgent(), visitedNodesDisplayNo)) + "</td>"); } writer.write("</tr></table>"); } @Override public void init() throws ServletException { super.init(); emf = (EntityManagerFactory) getServletContext().getAttribute("emf"); bots = (Bots) getServletContext().getAttribute("bots"); } private int[][] prepareToDisplayByLevel(List<List<Object[]>> allBotsresult) { long maxDepth = 0; // Maximal depth of search by bot for (List<Object[]> list : allBotsresult) { if (list.size() > 0) { long currentDepth = (Long) ((Object[]) list .get(list.size() - 1))[0]; maxDepth = Math.max(maxDepth, currentDepth); } } int[][] result = new int[allBotsresult.size()][]; for (int i = 0; i < result.length; i++) { result[i] = new int[(int) (maxDepth + 1)];// We have also level // "0" (empty string) List<Object[]> currentBot = allBotsresult.get(i); for (int j = 0; j < currentBot.size(); j++) { long pos = (Long) (((Object[]) currentBot.get(j))[0]); long value = (Long) (((Object[]) currentBot.get(j))[1]); result[i][(int) pos] = (int) value; } } return result; } }