001: /*
002: Very Quick Wiki - WikiWikiWeb clone
003: Copyright (C) 2001-2002 Gareth Cronin
004:
005: This program is free software; you can redistribute it and/or modify
006: it under the terms of the latest version of the GNU Lesser General
007: Public License as published by the Free Software Foundation;
008:
009: This program is distributed in the hope that it will be useful,
010: but WITHOUT ANY WARRANTY; without even the implied warranty of
011: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: GNU Lesser General Public License for more details.
013:
014: You should have received a copy of the GNU Lesser General Public License
015: along with this program (gpl.txt); if not, write to the Free Software
016: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
017: */
018: package vqwiki.servlets;
019:
020: import java.io.IOException;
021: import java.text.NumberFormat;
022: import java.util.ArrayList;
023: import java.util.Calendar;
024: import java.util.Collection;
025: import java.util.Collections;
026: import java.util.GregorianCalendar;
027: import java.util.HashMap;
028: import java.util.Iterator;
029: import java.util.List;
030: import java.util.Set;
031:
032: import javax.servlet.ServletException;
033: import javax.servlet.http.HttpServletRequest;
034: import javax.servlet.http.HttpServletResponse;
035:
036: import org.apache.log4j.Logger;
037:
038: import vqwiki.Change;
039: import vqwiki.TopicVersion;
040: import vqwiki.VersionManager;
041: import vqwiki.WikiBase;
042: import vqwiki.servlets.beans.StatisticsAuthorBean;
043: import vqwiki.servlets.beans.StatisticsMonthBean;
044: import vqwiki.servlets.beans.StatisticsOneWikiBean;
045: import vqwiki.servlets.beans.StatisticsVWikiBean;
046: import vqwiki.utils.Utilities;
047:
048: /**
049: * This servlet provides some general statisitcs for the usage of wiki
050: *
051: * This class was created on 09:34:30 19.07.2003
052: *
053: * @author $Author: wrh2 $
054: */
055: public class StatisticServlet extends LongLastingOperationServlet {
056:
057: /** Logging */
058: private static final Logger logger = Logger
059: .getLogger(StatisticServlet.class);
060: private StatisticsVWikiBean vwikis;
061:
062: /**
063: * Constructor
064: *
065: *
066: */
067: public StatisticServlet() {
068: super ();
069: }
070:
071: /**
072: * Handle post request.
073: * Generate a RSS feed and send it back as XML.
074: *
075: * @param request The current http request
076: * @param response What the servlet will send back as response
077: *
078: * @throws ServletException If something goes wrong during servlet execution
079: * @throws IOException If the output stream cannot be accessed
080: *
081: */
082: protected void doPost(HttpServletRequest request,
083: HttpServletResponse response) throws ServletException,
084: IOException {
085: super .doPost(request, response);
086: }
087:
088: /**
089: *
090: */
091: public void run() {
092: vwikis = new StatisticsVWikiBean();
093: NumberFormat nf = NumberFormat.getInstance(locale);
094: nf.setMaximumFractionDigits(2);
095: nf.setMinimumFractionDigits(1);
096: Collection allWikis;
097: try {
098: allWikis = WikiBase.getInstance().getVirtualWikiList();
099: } catch (Exception e) {
100: allWikis = Collections.EMPTY_LIST;
101: }
102: if (!allWikis.contains(WikiBase.DEFAULT_VWIKI)) {
103: allWikis.add(WikiBase.DEFAULT_VWIKI);
104: }
105: HashMap revisionsOverMonths = new HashMap();
106: HashMap topicsOverMonths = new HashMap();
107: HashMap authors = new HashMap();
108: int revisionsLastWeek = 0;
109: int topicsLastWeek = 0;
110: Calendar cal = new GregorianCalendar();
111: Calendar twelveMonthsAgo = new GregorianCalendar();
112: twelveMonthsAgo.setTime(new java.util.Date());
113: twelveMonthsAgo.add(Calendar.MONTH, -12);
114: Calendar lastWeekAgo = new GregorianCalendar();
115: lastWeekAgo.setTime(new java.util.Date());
116: lastWeekAgo.add(Calendar.DAY_OF_YEAR, -7);
117: int allWikiCount = 0;
118: int pageCount = 0;
119: for (Iterator iterator = allWikis.iterator(); iterator
120: .hasNext(); allWikiCount++) {
121: setProgress(allWikiCount, allWikis.size(), 0, 0);
122: String currentWiki = (String) iterator.next();
123: StatisticsOneWikiBean onewiki = new StatisticsOneWikiBean();
124: onewiki.setName(currentWiki);
125: int numberOfChanges = 0;
126: int numberOfTopics = 0;
127: try {
128: pageCount = 0;
129: Collection topics = WikiBase.getInstance()
130: .getSearchEngineInstance().getAllTopicNames(
131: currentWiki);
132: numberOfTopics = topics.size();
133: onewiki.setNumpages(String.valueOf(numberOfTopics));
134: for (Iterator iter = topics.iterator(); iter.hasNext(); pageCount++) {
135: setProgress(allWikiCount, allWikis.size(),
136: pageCount, numberOfTopics);
137: try {
138: String topic = (String) iter.next();
139: VersionManager versionManager = WikiBase
140: .getInstance()
141: .getVersionManagerInstance();
142: List versions = versionManager.getAllVersions(
143: currentWiki, topic);
144: int numberOfVersions = versions.size();
145: //numberOfVersions = (numberOfVersions < 1)?1:numberOfVersions;
146: numberOfChanges += numberOfVersions;
147: HashMap hasMonthModification = new HashMap();
148: boolean hasWeekModification = false;
149: for (Iterator versionIterator = versions
150: .iterator(); versionIterator.hasNext();) {
151: TopicVersion aVersion = (TopicVersion) versionIterator
152: .next();
153: cal.setTime(new java.util.Date(aVersion
154: .getRevisionDate().getTime()));
155: // is revision older than 12 months?
156: if (cal.after(twelveMonthsAgo)) {
157: Integer month = new Integer(cal
158: .get(Calendar.MONTH));
159: int count = 0;
160: if (null != revisionsOverMonths
161: .get(month)) {
162: count = ((Integer) revisionsOverMonths
163: .get(month)).intValue();
164: }
165: count++;
166: revisionsOverMonths.put(month,
167: new Integer(count));
168: if (null == hasMonthModification
169: .get(month)) {
170: count = 0;
171: if (null != topicsOverMonths
172: .get(month)) {
173: count = ((Integer) topicsOverMonths
174: .get(month)).intValue();
175: }
176: count++;
177: topicsOverMonths.put(month,
178: new Integer(count));
179: hasMonthModification.put(month,
180: new Boolean(true));
181: }
182: } // otherwise forget about this entry
183: if (cal.after(lastWeekAgo)) {
184: revisionsLastWeek++;
185: if (!hasWeekModification) {
186: topicsLastWeek++;
187: hasWeekModification = true;
188: }
189: }
190: // determine author
191: Collection changesOnThisDay = WikiBase
192: .getInstance()
193: .getChangeLogInstance().getChanges(
194: currentWiki,
195: new java.util.Date(aVersion
196: .getRevisionDate()
197: .getTime()));
198: if (changesOnThisDay != null) {
199: for (Iterator changeIterator = changesOnThisDay
200: .iterator(); changeIterator
201: .hasNext();) {
202: Change aChange = (Change) changeIterator
203: .next();
204: if (aChange.getTopic().equals(
205: aVersion.getTopicName())) {
206: if (aChange.getUser() != null) {
207: int count = 0;
208: if (null != authors
209: .get(aChange
210: .getUser())) {
211: // FIXME - more than four levels of indentation
212: // is usually a sign that a function needs to
213: // be broken up or simplified...
214: count = ((Integer) authors
215: .get(aChange
216: .getUser()))
217: .intValue();
218: }
219: count++;
220: authors.put(aChange
221: .getUser(),
222: new Integer(count));
223: }
224: }
225: }
226: }
227: }
228: } catch (Exception e) {
229: logger.fatal("Exception", e);
230: }
231: }
232: } catch (Exception ex) {
233: logger.error(ex);
234: }
235: // fill months
236: cal.setTime(new java.util.Date());
237: List monthList = new ArrayList();
238: for (int i = 0; i < 12; i++) {
239: Integer month = new Integer((cal.get(Calendar.MONTH)
240: - i + 12) % 12);
241: Integer changes = (Integer) revisionsOverMonths
242: .get(month);
243: if (changes == null)
244: changes = new Integer(0);
245: Integer pages = (Integer) topicsOverMonths.get(month);
246: if (pages == null)
247: pages = new Integer(0);
248: StatisticsMonthBean mb = new StatisticsMonthBean();
249: if (i == 0) {
250: mb
251: .setName(Utilities.resource("month.this",
252: locale));
253: } else if (i == 1) {
254: mb
255: .setName(Utilities.resource("month.last",
256: locale));
257: } else {
258: mb.setName(Utilities.resource("month.name"
259: + month.toString(), locale));
260: }
261: mb.setChanges(changes.toString());
262: mb.setPages(pages.toString());
263: mb.setRatio(nf.format(changes.doubleValue()
264: / pages.doubleValue()));
265: monthList.add(mb);
266: }
267: onewiki.setMonths(monthList);
268: onewiki.setNumchangeslw(String.valueOf(revisionsLastWeek));
269: onewiki.setNumpageslw(String.valueOf(topicsLastWeek));
270: onewiki
271: .setRatiolw(nf
272: .format(((double) revisionsLastWeek / (double) topicsLastWeek)));
273: onewiki.setNumchanges(String.valueOf(numberOfChanges));
274: onewiki
275: .setNummodifications(nf
276: .format(((double) numberOfChanges / (double) numberOfTopics)));
277: // fill up authors
278: Set authorNames = authors.keySet();
279: List authorList = new ArrayList();
280: for (Iterator authorIterator = authorNames.iterator(); authorIterator
281: .hasNext();) {
282: String anAuthorName = (String) authorIterator.next();
283: StatisticsAuthorBean ab = new StatisticsAuthorBean();
284: ab.setName(anAuthorName);
285: ab.setChanges(((Integer) authors.get(anAuthorName))
286: .toString());
287: authorList.add(ab);
288: }
289: onewiki.setAuthors(authorList);
290: vwikis.getVwiki().add(onewiki);
291: }
292: progress = PROGRESS_DONE;
293: }
294:
295: /**
296: * Set the progress
297: * @param allWikiCount Current wiki, we are processing
298: * @param allWikiSize Number of wikis (overall)
299: * @param pageCount Current page we are processing
300: * @param pageSize Number of pages of this wiki
301: */
302: private void setProgress(int allWikiCount, int allWikiSize,
303: int pageCount, int pageSize) {
304: double one = 100.0 / (double) allWikiSize;
305: if (pageSize == 0) {
306: progress = Math
307: .min((int) ((double) allWikiCount * one), 99);
308: } else {
309: progress = Math
310: .min(
311: (int) ((double) allWikiCount * one + (double) pageCount
312: * one / (double) pageSize), 99);
313: }
314: }
315:
316: /**
317: * We are done. Go to result page.
318: * @see vqwiki.servlets.LongLastingOperationServlet#dispatchDone(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
319: */
320: protected void dispatchDone(HttpServletRequest request,
321: HttpServletResponse response) {
322: request.setAttribute("virtualwikis", vwikis);
323: request.setAttribute("title", Utilities.resource(
324: "statistics.title", request.getLocale()));
325: dispatch("/jsp/statistics.jsp", request, response);
326: }
327:
328: /**
329: * Handle get request.
330: * The request is handled the same way as the post request.
331: *
332: * @see doPost()
333: *
334: * @param httpServletRequest The current http request
335: * @param httpServletResponse What the servlet will send back as response
336: *
337: * @throws ServletException If something goes wrong during servlet execution
338: * @throws IOException If the output stream cannot be accessed
339: *
340: */
341: protected void doGet(HttpServletRequest httpServletRequest,
342: HttpServletResponse httpServletResponse)
343: throws ServletException, IOException {
344: this .doPost(httpServletRequest, httpServletResponse);
345: }
346: }
347:
348: /*
349: * Log:
350: *
351: * $Log$
352: * Revision 1.7 2006/04/23 06:36:56 wrh2
353: * Coding style updates (VQW-73).
354: *
355: * Revision 1.6 2003/10/05 05:07:32 garethc
356: * fixes and admin file encoding option + merge with contributions
357: *
358: * Revision 1.5 2003/07/23 13:45:19 mrgadget4711
359: * ADD: progress information
360: *
361: * Revision 1.4 2003/07/23 00:34:26 mrgadget4711
362: * ADD: Long lasting operations
363: *
364: * Revision 1.3 2003/07/21 09:19:39 mrgadget4711
365: * Fixes
366: *
367: * Revision 1.2 2003/07/20 20:56:19 garethc
368: * 2.5.2
369: *
370: * Revision 1.1 2003/07/19 13:22:59 mrgadget4711
371: * ADD: Statistic capabilities
372: *
373: * ------------END------------
374: */
|