View Javadoc

1   /*
2    * Copyright (c) 2004 UNINETT FAS
3    *
4    * This program is free software; you can redistribute it and/or modify it
5    * under the terms of the GNU General Public License as published by the Free
6    * Software Foundation; either version 2 of the License, or (at your option)
7    * any later version.
8    *
9    * This program is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11   * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12   * more details.
13   *
14   * You should have received a copy of the GNU General Public License along with
15   * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
16   * Place - Suite 330, Boston, MA 02111-1307, USA.
17   *
18   * $Id: StatisticsServlet.java,v 1.8 2006/01/19 15:15:51 catoolsen Exp $
19   */
20  
21  package no.feide.moria.servlet;
22  
23  import java.io.File;
24  import java.util.Calendar;
25  import java.io.IOException;
26  import java.io.PrintWriter;
27  import java.util.Iterator;
28  import java.util.TreeMap;
29  import java.util.Properties;
30  import java.util.ResourceBundle;
31  
32  import javax.servlet.ServletException;
33  import javax.servlet.http.HttpServlet;
34  import javax.servlet.http.HttpServletRequest;
35  import javax.servlet.http.HttpServletResponse;
36  import javax.xml.parsers.SAXParser;
37  import javax.xml.parsers.SAXParserFactory;
38  import java.util.MissingResourceException;
39  
40  import no.feide.moria.log.MessageLogger;
41  import no.feide.moria.controller.MoriaController;
42  
43  /***
44   * The StatisticsServlet shows the usage of Moria.
45   * @version $Revision: 1.8 $
46   */
47  public class StatisticsServlet
48  extends MoriaServlet {
49  
50      /*** Used for logging. */
51      private final MessageLogger log = new MessageLogger(StatusServlet.class);
52  
53      /***
54       * List of parameters required by <code>StatusServlet</code>.
55       * <br>
56       * <br>
57       * Current required parameters are:
58       * <ul>
59       * <li><code>RequestUtil.PROP_BACKENDSTATUS_STATISTICS_XML</code>
60       * <li><code>RequestUtil.PROP_BACKENDSTATUS_STATISTICS2_XML</code>
61       * <li><code>RequestUtil.PROP_BACKENDSTATUS_IGNORE</code>
62       * <li><code>RequestUtil.PROP_COOKIE_LANG_XML</code>
63       * </ul>
64       * @see RequestUtil#PROP_BACKENDSTATUS_STATISTICS_XML
65       */
66      private static final String[] REQUIRED_PARAMETERS = {
67              RequestUtil.PROP_BACKENDSTATUS_STATISTICS_XML,
68              RequestUtil.PROP_BACKENDSTATUS_STATISTICS2_XML,
69              RequestUtil.PROP_BACKENDSTATUS_STATISTICS2_BASENAME_XML,
70              RequestUtil.PROP_BACKENDSTATUS_IGNORE,
71              RequestUtil.PROP_COOKIE_LANG };
72  
73      /***
74       * 
75       * @return the required parameters for this servlet.
76       */
77      public static String[] getRequiredParameters() {
78          return REQUIRED_PARAMETERS;
79      }
80  
81      /***
82       * Handles the GET requests.
83       * @param request
84       *            The HTTP request object.
85       * @param response
86       *            The HTTP response object.
87       * @throws java.io.IOException
88       *             If an input or output error is detected when the servlet
89       *             handles the GET request.
90       * @throws javax.servlet.ServletException
91       *             If the request for the GET could not be handled.
92       * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest,
93       *      javax.servlet.http.HttpServletResponse)
94       */
95      public final void doGet(final HttpServletRequest request, final HttpServletResponse response)
96      throws IOException, ServletException {
97                  
98          response.setContentType("text/html");
99          PrintWriter out = response.getWriter();
100         String docType = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n";
101         
102         String year = request.getParameter("year");
103         if (year != null && year != "") {
104             try {
105                 int number = Integer.parseInt(year);
106                 if (number < 2005) year = null;
107             }
108             catch (NumberFormatException e) {
109                 year = null;
110             }
111         }
112         if (year == null || year.equals("")) {
113             int yearnumber = Calendar.getInstance().get(Calendar.YEAR);
114             Integer tmp = new Integer(yearnumber);
115             year = tmp.toString();
116         }       
117         /* Resource bundle. */
118         String language = null;
119         String langFromCookie = null;
120         Properties config = getConfig();
121         if (config != null && request.getCookies() != null) {
122            langFromCookie = RequestUtil.getCookieValue((String) config.get(RequestUtil.PROP_COOKIE_LANG), request.getCookies());
123         }
124         // Update cookie if language has changed
125         if (request.getParameter(RequestUtil.PARAM_LANG) != null) {
126             language = request.getParameter(RequestUtil.PARAM_LANG);
127             response.addCookie(RequestUtil.createCookie(
128                     (String) config.get(RequestUtil.PROP_COOKIE_LANG),
129                     language,
130                     new Integer((String) config.get(RequestUtil.PROP_COOKIE_LANG_TTL)).intValue()));
131         }
132 
133         /* Get bundle, using either cookie or language parameter */
134        final ResourceBundle bundle = RequestUtil.getBundle(
135                 RequestUtil.BUNDLE_STATISTICSSERVLET,
136                 language, langFromCookie, null,
137                 request.getHeader("Accept-Language"), 
138                 (String) config.get(RequestUtil.PROP_LOGIN_DEFAULT_LANGUAGE));
139         
140         // Header
141         out.println("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>");
142         out.println(docType + "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=" + bundle.getLocale() + ">"); 
143         out.println("<head><link rel=\"icon\" href=\"/favicon.ico\" type=\"image/png\">"); 
144         out.println("<style type=\"text/css\">\n@import url(\"../resource/stil.css\");\n</style>");
145         out.println("<link rel=\"author\" href=\"mailto:" + config.get(RequestUtil.RESOURCE_MAIL)+ "\">");
146         out.println("<title>" + bundle.getString("header_title") + "</title></head><body>");
147         
148         //Layout table
149         out.println("<table summary=\"Layout-tabell\" class=\"invers\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\">");
150         out.println("<tbody><tr valign=\"middle\">");
151         out.println("<td class=\"logo\" width=\"76\"><a href=" + config.get(RequestUtil.RESOURCE_LINK) + ">");
152         out.println("<img src=\"../resource/logo.gif\" alt=" + config.get(RequestUtil.PROP_FAQ_OWNER) + " border=\"0\" height=\"41\" width=\"76\"></a></td>");
153         out.println("<td width=\"0%\"><a class=\"noline\" href=" + config.get(RequestUtil.RESOURCE_LINK) + ">");
154         out.println(bundle.getString("header_feide") + "</a></td>");
155         out.println("<td width=\"35%\">&nbsp;</td>");
156         
157         	// Language selection
158             TreeMap languages = (TreeMap)RequestUtil.parseConfig(config, RequestUtil.PROP_LANGUAGE, RequestUtil.PROP_COMMON);
159             Iterator it = languages.keySet().iterator();
160             while(it.hasNext()) {
161                 String longName = (String) it.next();
162                 String shortName  = (String) languages.get(longName);
163                 if (RequestUtil.ATTR_SELECTED_LANG.equals(shortName)) {
164                     out.println("[" + longName + "]");
165                 } else
166                     out.println("<td align=\"centre\"><small><a class=\"invers\" href ="
167                             + config.get(RequestUtil.PROP_STATISTICS_URL) + "?" + RequestUtil.PARAM_LANG + "=" + shortName + ">" + longName
168                             + "</a></small></td>");
169                 }
170          
171         //More Layout
172         out.println("<td class=\"dekor1\" width=\"100%\">&nbsp;</td></tr></tbody></table>");
173         out.println("<div class=\"midt\">");
174         out.println("<table cellspacing=\"0\">");
175         out.println("<tbody><tr valign=\"top\">");
176         out.println("<td class=\"kropp\">");
177         
178         //Print info
179         if (year.equals("2005")) {
180             
181             // Link to new statistics
182             out.println("<a href=" + (String)config.get(RequestUtil.PROP_STATISTICS_URL) + ">" + bundle.getString("stat_2006") + "</a>");
183             this.printOldStatistics(out, bundle);
184                 
185             //Statistics from moria2
186             out.println("<br><h3>" + bundle.getString("stat_info2") + "</h3>");
187             out.println(bundle.getString("stat_info3"));
188             String filename2 = (String) config.get(RequestUtil.PROP_BACKENDSTATUS_STATISTICS2_XML);
189             this.printStatistics(out, bundle, filename2);
190         }
191         else {
192             // Link to statistics for 2005
193             out.println("<a href=" + (String)config.get(RequestUtil.PROP_STATISTICS_URL) + "?year=2005" + ">" + bundle.getString("stat_2005") + "</a>" );
194             out.println("<br><h3>" + bundle.getString("stat_info") + "</h3>");
195             out.println(bundle.getString("stat_info3"));
196             String filename2 = (String) config.get(RequestUtil.PROP_BACKENDSTATUS_STATISTICS2_BASENAME_XML);
197             filename2 += "_" + year + ".xml";
198             this.printStatistics(out, bundle, filename2);
199         }
200         //Layout
201         out.println("</tr>");
202         out.println("</table>");
203         out.println("</tbody>");
204         out.println("</div>");
205 
206         out.println("<p>");
207         out.println("<table summary=\"Layout-tabell\" class=\"invers\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\">");
208         out.println("<tbody><tr class=\"bunn\" valign=\"middle\">");
209         out.println("<td class=\"invers\" align=\"left\"><small><a class=\"invers\" href=\"mailto:"
210                 + config.get(RequestUtil.RESOURCE_MAIL) + "\">" + config.get(RequestUtil.RESOURCE_MAIL) + "</a></small></td>");
211         out.println("<td class=\"invers\" align=\"right\"><small>" + config.get(RequestUtil.RESOURCE_DATE) + "</small></td>");
212         out.println("</tr></tbody></table></p>");
213                         
214         // Finish up.
215         out.println("</body></html>");
216         
217 
218     }
219     
220     private void printOldStatistics(PrintWriter out, ResourceBundle bundle) {
221         Properties config = getConfig();
222         
223         // Print statistics    
224         out.println("<br><h3>" + bundle.getString("stat_info") + "</h3>");
225         
226         //Statistics from moria1
227         String filename = (String) config.get(RequestUtil.PROP_BACKENDSTATUS_STATISTICS_XML);
228         this.printStatistics(out, bundle, filename);
229         
230         out.println("<br><i>" + bundle.getString("vortex_number") + "</i>");
231     }
232     
233     private void printStatistics(PrintWriter out, ResourceBundle bundle, String filename) {
234         Properties config = getConfig();
235         if (config != null) {
236             StatisticsHandler handler = new StatisticsHandler();
237             
238             // Read ignore-list from config file
239             String ignorestring = (String)config.get(RequestUtil.PROP_BACKENDSTATUS_IGNORE);
240             String[] ignore = ignorestring.split(",");
241             for (int i=0; i<ignore.length; i++) {
242                 handler.addIgnoreService(ignore[i]);
243             }
244             SAXParserFactory factory = SAXParserFactory.newInstance();
245             try {
246                 SAXParser saxParser = factory.newSAXParser();
247                 saxParser.parse(new File(filename), handler);
248                 
249                 int numstats = handler.getNumStatisticsCollections();
250                 if (numstats == 1) numstats = 0;
251                 for (int s = -1; s < numstats; s++) {                 
252                     StatisticsCollection stat = null;
253                     if (s < 0) {
254                         stat = handler.getAccumStatistics();
255                         out.print("<p>");
256                     }
257                     else {
258                         stat = handler.getStatisticsCollection(s);
259                         String name = stat.getOrgName();
260                         try {
261                             out.println("<p><b>" + bundle.getString(name) + "</b>");
262                         } catch (MissingResourceException m) {
263                             out.println("<p><b>" + name + "</b>");
264                         }
265                     } 
266                     final int nummonths = stat.getNumMonths();
267                     if (nummonths > 0) {
268                         // Make table
269                         out.println("<table border=1><tr><th>" + bundle.getString("stat_services") + "</th>");
270                         for (int i = 0; i < nummonths; i++) {
271                             out.print("<th>");
272                             out.print(bundle.getString(stat.getMonthName(i)));
273                             out.print("</th>");
274                         }
275                         out.print("<th>" + bundle.getString("stat_sum") + "</th>");
276                         for (int j = 0; j < stat.getNumStatisticsData(); j++) {
277                             StatisticsData data = stat.getStatisticsData(j);
278                             out.print("<tr>");
279                             String name = data.getName();
280                             // Print the translated name for a service if it exists
281                             try {
282                                 out.print("<td>" + bundle.getString(name) + "</td>");
283                             } catch (MissingResourceException m) {
284                                 out.print("<td>" + name + "</td>");
285                             } 
286                             // Print numbers and summarize
287                             int sum = 0;
288                             for (int i = 0; i < nummonths; i++) {
289                                 sum += data.getCount(stat.getMonthName (i));
290                                 out.print("<td align=right>");
291                                 out.print(Integer.toString(data.getCount(stat.getMonthName(i))));
292                                 out.print("</td>");
293                             }
294                             out.print("<td align=right>" + Integer.toString(sum) + "</td>");
295                             out.print("</tr>");
296                         }
297                         
298                         
299                         out.println("</table>");
300                     }
301                 }
302             }
303             catch (Throwable t) {
304                 out.println("Error while parsing xml");
305                 out.println(t.getMessage());
306             }
307         }
308     }
309     
310     /***
311      * Get this servlet's configuration from the web module, given by
312      * <code>RequestUtil.PROP_CONFIG</code>.
313      * @return The last valid configuration.
314      * @throws IllegalStateException
315      *             If unable to read the current configuration from the servlet
316      *             context, and there is no previous configuration. Also thrown
317      *             if any of the required parameters (given by
318      *             <code>REQUIRED_PARAMETERS</code>) are not set.
319      * @see #REQUIRED_PARAMETERS
320      * @see RequestUtil#PROP_CONFIG
321      */
322     private Properties getConfig() {
323         return getServletConfig(getRequiredParameters(), log);
324     }
325     
326 
327 }
328