001: /*
002: * Coefficient - facilitates project based collaboration
003: * Copyright (C) 2003, Dylan Etkin, CSIR icomtek
004: * PO Box 395
005: * Pretoria 0001, RSA
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or (at your option) any later version.
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public
016: * License along with this library; if not, write to the Free Software
017: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: */
019:
020: package za.org.coefficient.statistics.data;
021:
022: import java.text.SimpleDateFormat;
023:
024: import java.util.Calendar;
025: import java.util.Date;
026: import java.util.GregorianCalendar;
027: import java.util.HashMap;
028: import java.util.Iterator;
029: import java.util.Map;
030:
031: /**
032: * @hibernate.class
033: * table="COEFFICIENT_PROJECT_STATISTICS"
034: */
035: public class ProjectStatistics implements java.io.Serializable {
036:
037: public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat(
038: "dd/MM/yyyy");
039:
040: //~ Instance fields ========================================================
041:
042: private Date statsDate;
043: private Long id;
044: private Long projectId;
045: private Map moduleStatistics = new HashMap();
046: private Map archive = new HashMap();
047: private ProjectStatisticsData currentData;
048:
049: //~ Constructors ===========================================================
050:
051: public ProjectStatistics() {
052: archive = new HashMap();
053: currentData = new ProjectStatisticsData();
054: }
055:
056: //~ Methods ================================================================
057:
058: public boolean archiveStats() {
059: boolean retVal = false;
060: Calendar c1 = new GregorianCalendar();
061: c1.setTime(this .getLatestModifiedDate());
062: Calendar c2 = new GregorianCalendar();
063: if (c1.get(Calendar.DAY_OF_YEAR) < c2.get(Calendar.DAY_OF_YEAR)) {
064: retVal = true;
065: // Roll the current stats into the archive
066: this .archive
067: .put(DATE_FORMAT.format(statsDate), currentData);
068: ProjectStatisticsData newData = new ProjectStatisticsData();
069: newData.setCarryOverViewCount(currentData.getViewCount()
070: + currentData.getCarryOverViewCount());
071: newData.setCarryOverDownloadCount(currentData
072: .getDownloadCount()
073: + currentData.getCarryOverDownloadCount());
074: currentData = newData;
075: statsDate = new Date(System.currentTimeMillis());
076:
077: Map modStats = this .moduleStatistics;
078: for (Iterator it = modStats.keySet().iterator(); it
079: .hasNext();) {
080: String key = (String) it.next();
081:
082: // Give each module a chance to archive itself
083: ModuleStatistics ms = (ModuleStatistics) modStats
084: .get(key);
085: ms.archiveStats();
086: }
087: }
088: return retVal;
089: }
090:
091: /**
092: * Sets the value of id
093: *
094: * @param argId Value to assign to this.id
095: */
096: public void setId(Long argId) {
097: this .id = argId;
098: }
099:
100: /**
101: * Gets the value of id
102: *
103: * @return the value of id
104: * @hibernate.id
105: * generator-class="native"
106: */
107: public Long getId() {
108: return this .id;
109: }
110:
111: public Date getLatestModifiedDate() {
112: Date retVal = statsDate;
113: for (Iterator it = moduleStatistics.keySet().iterator(); it
114: .hasNext();) {
115: String key = (String) it.next();
116: ModuleStatistics ms = (ModuleStatistics) moduleStatistics
117: .get(key);
118: if (ms.getStatsDate().after(retVal)) {
119: retVal = ms.getStatsDate();
120: }
121: }
122:
123: return retVal;
124: }
125:
126: /**
127: * Sets the value of moduleStatistics
128: *
129: * @param argModuleStatistics Value to assign to this.moduleStatistics
130: */
131: public void setModuleStatistics(Map argModuleStatistics) {
132: this .moduleStatistics = argModuleStatistics;
133: }
134:
135: /**
136: * Gets the value of moduleStatistics
137: *
138: * @return the value of moduleStatistics
139: * @hibernate.map
140: * cascade="all"
141: * table="COEFFICIENT_PROJECT_STATISTICS_MODULE_STATISTICS"
142: * @hibernate.collection-key
143: * column="PROJECT_STATISTICS_ID"
144: * @hibernate.collection-index
145: * column="IDX"
146: * type="string"
147: * @hibernate.collection-many-to-many
148: * class="za.org.coefficient.statistics.data.ModuleStatistics"
149: * column="MODULE_STATISTIC"
150: */
151: public Map getModuleStatistics() {
152: return this .moduleStatistics;
153: }
154:
155: /**
156: * Sets the value of projectId
157: *
158: * @param argProjectId Value to assign to this.projectId
159: */
160: public void setProjectId(Long argProjectId) {
161: this .projectId = argProjectId;
162: }
163:
164: /**
165: * Gets the value of projectId
166: *
167: * @return the value of projectId
168: * @hibernate.property
169: * column="PROJECT_ID"
170: */
171: public Long getProjectId() {
172: return this .projectId;
173: }
174:
175: /**
176: * Sets the value of statsDate
177: *
178: * @param argStatsDate Value to assign to this.statsDate
179: */
180: public void setStatsDate(Date argStatsDate) {
181: this .statsDate = argStatsDate;
182: }
183:
184: /**
185: * Gets the value of statsDate
186: *
187: * @return the value of statsDate
188: * @hibernate.property
189: * column="STATISTICS_DATE"
190: */
191: public Date getStatsDate() {
192: return this .statsDate;
193: }
194:
195: public void addModuleStatistics(ModuleStatistics ms) {
196: ms.setProjectId(getProjectId());
197: this .moduleStatistics.put(ms.getName(), ms);
198: }
199:
200: public void calculateRank() {
201: // perform some equation that calculates the rank points
202: long newRank = getCurrentData().getCarryOverViewCount()
203: + getCurrentData().getCarryOverDownloadCount()
204: + calculateStats();
205: if (newRank != getCurrentData().getRank()) {
206: getCurrentData().setRank(newRank);
207: }
208: }
209:
210: public void deleteModuleStatistics(ModuleStatistics ms) {
211: this .moduleStatistics.remove(ms.getName());
212: }
213:
214: /**
215: * Gets the value of archive
216: *
217: * @return the value of archive
218: * @hibernate.map
219: * cascade="all"
220: * table="COEFFICIENT_PROJECT_STATISTICS_ARCHIVE"
221: * @hibernate.collection-key
222: * column="PROJECT_STATISTICS_ID"
223: * @hibernate.collection-index
224: * column="IDX"
225: * type="string"
226: * @hibernate.collection-many-to-many
227: * class="za.org.coefficient.statistics.data.ProjectStatisticsData"
228: * column="PROJECT_STATISTICS_DATA"
229: */
230: public Map getArchive() {
231: return this .archive;
232: }
233:
234: /**
235: * Sets the value of archive
236: *
237: * @param argArchive Value to assign to this.archive
238: */
239: public void setArchive(Map argArchive) {
240: this .archive = argArchive;
241: }
242:
243: /**
244: * Gets the value of currentData
245: *
246: * @return the value of currentData
247: * @hibernate.many-to-one
248: * cascade="all"
249: * unique="true"
250: * column="CURRENT_DATA"
251: */
252: public ProjectStatisticsData getCurrentData() {
253: return this .currentData;
254: }
255:
256: /**
257: * Sets the value of currentData
258: *
259: * @param argCurrentData Value to assign to this.currentData
260: */
261: public void setCurrentData(ProjectStatisticsData argCurrentData) {
262: this .currentData = argCurrentData;
263: }
264:
265: /**
266: * This method will get the total activity for each day up to the number
267: * of specified days from today. For example if daysAgo is 7 the returned
268: * map will return the total activity for the last 7 days including today.
269: *
270: * @param days indicates how many days including today to report back on. If
271: * there is no data for a day then the activity result will be 0.
272: * @return Map is a map keyed by a java.util.Date object containing the
273: * java.lang.Long value that is the total activity for the day.
274: */
275: public Map getTotalActivityForNumberOfDaysIncludingToday(int days) {
276: HashMap activity = new HashMap();
277: Date theDate = statsDate;
278:
279: for (int i = 0; i < days; i++) {
280: long modulesTotal = 0;
281: for (Iterator it = moduleStatistics.keySet().iterator(); it
282: .hasNext();) {
283: String moduleName = (String) it.next();
284: ModuleStatistics modStat = (ModuleStatistics) moduleStatistics
285: .get(moduleName);
286: modulesTotal += modStat.getStatsTotalForDate(theDate);
287: }
288: activity.put(theDate, new Long(getViewStatsForDate(theDate)
289: + getDownloadStatsForDate(theDate) + modulesTotal));
290: // decrement the date
291: theDate = new Date(theDate.getTime()
292: - (1000 * 60 * 60 * 24));
293: }
294: return activity;
295: }
296:
297: public long getViewStatsForDate(Date date) {
298: long retVal = 0;
299:
300: if (ProjectStatistics.DATE_FORMAT.format(statsDate).equals(
301: ProjectStatistics.DATE_FORMAT.format(date))) {
302: retVal = currentData.getViewCount();
303: } else {
304: // look to the archive for this data
305: ProjectStatisticsData prjStatData = (ProjectStatisticsData) archive
306: .get(DATE_FORMAT.format(date));
307: if (prjStatData != null) {
308: retVal = prjStatData.getViewCount();
309: }
310: }
311:
312: return retVal;
313: }
314:
315: public long getDownloadStatsForDate(Date date) {
316: long retVal = 0;
317:
318: if (ProjectStatistics.DATE_FORMAT.format(statsDate).equals(
319: ProjectStatistics.DATE_FORMAT.format(date))) {
320: retVal = currentData.getDownloadCount();
321: } else {
322: // look to the archive for this data
323: ProjectStatisticsData prjStatData = (ProjectStatisticsData) archive
324: .get(DATE_FORMAT.format(date));
325: if (prjStatData != null) {
326: retVal = prjStatData.getDownloadCount();
327: }
328: }
329:
330: return retVal;
331: }
332:
333: /**
334: * This method will get the view activity for each day up to the number
335: * of specified days from today. For example if daysAgo is 7 the returned
336: * map will return the view activity for the last 7 days including today.
337: *
338: * @param days indicates how many days including today to report back on. If
339: * there is no data for a day then the activity result will be 0.
340: * @return Map is a map keyed by a java.util.Date object containing the
341: * java.lang.Long value that is the view activity for the day.
342: */
343: public Map getViewActivityForNumberOfDaysIncludingToday(int days) {
344: HashMap activity = new HashMap();
345: Date theDate = statsDate;
346:
347: for (int i = 0; i < days; i++) {
348: activity.put(theDate,
349: new Long(getViewStatsForDate(theDate)));
350: // decrement the date
351: theDate = new Date(theDate.getTime()
352: - (1000 * 60 * 60 * 24));
353: }
354: return activity;
355: }
356:
357: /**
358: * This method will get the view activity for each day up to the number
359: * of specified days from today.
360: *
361: * @param days indicates how many days including today to report back on. If
362: * there is no data for a day then the activity result will be 0.
363: * @return long is the total for the date range
364: */
365: public long getViewActivityTotalForNumberOfDaysIncludingToday(
366: int days) {
367: long total = 0;
368: Date theDate = statsDate;
369:
370: for (int i = 0; i < days; i++) {
371: total += getViewStatsForDate(theDate);
372: // decrement the date
373: theDate = new Date(theDate.getTime()
374: - (1000 * 60 * 60 * 24));
375: }
376: return total;
377: }
378:
379: /**
380: * This method will get the download activity for each day up to the number
381: * of specified days from today.
382: *
383: * @param days indicates how many days including today to report back on. If
384: * there is no data for a day then the activity result will be 0.
385: * @return Map is a map keyed by a java.util.Date object containing the
386: * java.lang.Long value that is the download activity for the day.
387: */
388: public Map getDownloadActivityForNumberOfDaysIncludingToday(int days) {
389: HashMap activity = new HashMap();
390: Date theDate = statsDate;
391:
392: for (int i = 0; i < days; i++) {
393: activity.put(theDate, new Long(
394: getDownloadStatsForDate(theDate)));
395: // decrement the date
396: theDate = new Date(theDate.getTime()
397: - (1000 * 60 * 60 * 24));
398: }
399: return activity;
400: }
401:
402: /**
403: * This method will get the download activity for each day up to the number
404: * of specified days from today.
405: *
406: * @param days indicates how many days including today to report back on. If
407: * there is no data for a day then the activity result will be 0.
408: * @return long is the total for the date range
409: */
410: public long getDownloadActivityTotalForNumberOfDaysIncludingToday(
411: int days) {
412: long total = 0;
413: Date theDate = statsDate;
414:
415: for (int i = 0; i < days; i++) {
416: total += getDownloadStatsForDate(theDate);
417: // decrement the date
418: theDate = new Date(theDate.getTime()
419: - (1000 * 60 * 60 * 24));
420: }
421: return total;
422: }
423:
424: public long getRankForNumberOfDaysIncludingToday(int days) {
425: long rank = currentData.getRank();
426: Date theDate = statsDate;
427:
428: if ((days - 1) < archive.size()) {
429: // Find the rank on the day we want
430: for (int i = 0; i < days; i++) {
431: theDate = new Date(theDate.getTime()
432: - (1000 * 60 * 60 * 24));
433: }
434: ProjectStatisticsData prjStatData = (ProjectStatisticsData) archive
435: .get(DATE_FORMAT.format(theDate));
436: while (prjStatData == null) {
437: theDate = new Date(theDate.getTime()
438: - (1000 * 60 * 60 * 24));
439: prjStatData = (ProjectStatisticsData) archive
440: .get(DATE_FORMAT.format(theDate));
441: }
442: rank -= prjStatData.getRank();
443: }
444: return rank;
445: }
446:
447: private long calculateStats() {
448: long retVal = 0;
449: retVal = getCurrentData().getViewCount()
450: + getCurrentData().getDownloadCount();
451: for (Iterator it = moduleStatistics.keySet().iterator(); it
452: .hasNext();) {
453: String key = (String) it.next();
454: ModuleStatistics ms = (ModuleStatistics) moduleStatistics
455: .get(key);
456: retVal += ms.calculateStats();
457: }
458:
459: return retVal;
460: }
461:
462: }
|