Index: xwiki-platform-core/xwiki-core/pom.xml
===================================================================
--- xwiki-platform-core/xwiki-core/pom.xml (revision 5888)
+++ xwiki-platform-core/xwiki-core/pom.xml (working copy)
@@ -485,6 +485,11 @@
xwiki-core-component
${version}
+
+ joda-time
+ joda-time
+ 1.4
+
Index: xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/api/StatsService.java
===================================================================
--- xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/api/StatsService.java (revision 0)
+++ xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/api/StatsService.java (revision 0)
@@ -0,0 +1,208 @@
+/*
+ * See the NOTICE file distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ */
+package com.xpn.xwiki.api;
+
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import com.xpn.xwiki.XWikiContext;
+import com.xpn.xwiki.stats.api.XWikiStatsService;
+import com.xpn.xwiki.stats.impl.DocumentStats;
+import com.xpn.xwiki.stats.impl.Duration;
+import com.xpn.xwiki.stats.impl.DurationFactory;
+import com.xpn.xwiki.stats.impl.Interval;
+import com.xpn.xwiki.stats.impl.IntervalFactory;
+import com.xpn.xwiki.stats.impl.Period;
+import com.xpn.xwiki.stats.impl.PeriodFactory;
+import com.xpn.xwiki.stats.impl.Scope;
+import com.xpn.xwiki.stats.impl.ScopeFactory;
+
+/**
+ * Statistics api. The statistics module need to be activated (xwiki.stats=1 in xwiki.cfg)
+ */
+public class StatsService extends Api
+{
+ public StatsService(XWikiContext context)
+ {
+ super(context);
+ }
+
+ /**
+ * @return A helper factory for creating Scope objects in velocity.
+ */
+ public ScopeFactory getScopeFactory()
+ {
+ return ScopeFactory.getInstance();
+ }
+
+ /**
+ * @return A helper factory for creating a Period objects in velocity.
+ */
+ public PeriodFactory getPeriodFactory()
+ {
+ return PeriodFactory.getInstance();
+ }
+
+ /**
+ * @return A helper factory for creating a Period objects in velocity.
+ */
+ public DurationFactory getDurationFactory()
+ {
+ return DurationFactory.getInstance();
+ }
+
+ /**
+ * @return A helper factory for creating Interval objects in velocity.
+ */
+ public IntervalFactory getIntervalFactory()
+ {
+ return IntervalFactory.getInstance();
+ }
+
+ /**
+ * Retrieves document statistics.
+ *
+ * @param action Can be one of: "view", "save", "download"
+ * @param scope The set of documents for which to retrieve statistics
+ * @param period The period of time
+ * @param interval The sub-interval to return from the entire result set. Use this parameter for
+ * pagination
+ * @return A list of DocumentStats objects
+ */
+ public List getDocumentStatistics(String action, Scope scope, Period period, Interval interval)
+ {
+ XWikiStatsService stats = getXWikiContext().getWiki().getStatsService(getXWikiContext());
+ if (stats == null)
+ return Collections.EMPTY_LIST;
+ return stats.getDocumentStatistics(action, scope, period, interval, getXWikiContext());
+ }
+
+ /**
+ * Retrieves visit statistics
+ *
+ * @param action The action the results should be ordered by
+ * @param period The period of time
+ * @param interval The sub-interval to return from the entire result set. Use this parameter for
+ * pagination
+ * @return A list of VisitStats objects
+ */
+ public List getVisitStatistics(String action, Period period, Interval interval)
+ {
+ XWikiStatsService stats = getXWikiContext().getWiki().getStatsService(getXWikiContext());
+ if (stats == null)
+ return Collections.EMPTY_LIST;
+ return stats.getVisitStatistics(action, period, interval, getXWikiContext());
+ }
+
+ /**
+ * Retrieves referer statistics.
+ *
+ * @param period The period of time
+ * @param interval The sub-interval to return from the entire result set. Use this parameter for
+ * pagination
+ * @return A list of RefererStats objects
+ */
+ public List getRefererStatistics(Period period, Interval interval)
+ {
+ XWikiStatsService stats = getXWikiContext().getWiki().getStatsService(getXWikiContext());
+ if (stats == null)
+ return Collections.EMPTY_LIST;
+ return stats.getRefererStatistics(period, interval, getXWikiContext());
+ }
+
+ /**
+ * Shows how the statistics for the specified action have evolved over the specified period of
+ * time.
+ *
+ * @param action
+ * @param scope The set of documents to consider
+ * @param period The period of time
+ * @param step The step used for sampling the period
+ * @return A map of (date, actionCount) pairs
+ */
+ public Map getActionStatistics(String action, Scope scope, Period period, Duration step)
+ {
+ XWikiStatsService stats = getXWikiContext().getWiki().getStatsService(getXWikiContext());
+ if (stats == null)
+ return Collections.EMPTY_MAP;
+ return stats.getActionStatistics(action, scope, period, step, getXWikiContext());
+ }
+
+ /**
+ * Retrieves user agent statistics.
+ *
+ * @param period The period of time
+ * @return A map of (userAgentName, visitCount) pairs
+ */
+ public Map getUserAgentStatistics(Period period)
+ {
+ XWikiStatsService stats = getXWikiContext().getWiki().getStatsService(getXWikiContext());
+ if (stats == null)
+ return Collections.EMPTY_MAP;
+ return stats.getUserAgentStatistics(period, getXWikiContext());
+ }
+
+ /**
+ * Retrieves operating system statistics
+ *
+ * @param period The period of time
+ * @return A map of (operatingSystem, visitCount) pairs
+ */
+ public Map getOperatingSystemStatistics(Period period)
+ {
+ XWikiStatsService stats = getXWikiContext().getWiki().getStatsService(getXWikiContext());
+ if (stats == null)
+ return Collections.EMPTY_MAP;
+ return stats.getOperatingSystemStatistics(period, getXWikiContext());
+ }
+
+ /**
+ * API to access the current starts for the Wiki for a specific action It retrieves the number
+ * of times the action was performed for the whole wiki.
+ *
+ * @param action action for which to retrieve statistics (view/save/download)
+ * @return A DocumentStats object with number of actions performed, unique visitors, number of
+ * visits
+ * @deprecated use {@link #getDocumentStatistics(String, Scope, Period, Interval)} instead
+ */
+ public DocumentStats getCurrentMonthXWikiStats(String action)
+ {
+ return getXWikiContext().getWiki().getStatsService(getXWikiContext()).getDocMonthStats(
+ "", action, new Date(), getXWikiContext());
+ }
+
+ /**
+ * Returns the recently visited pages for a specific action
+ *
+ * @param action ("view" or "edit")
+ * @param size how many recent actions to retrieve
+ * @return a ArrayList of document names
+ */
+ public java.util.Collection getRecentActions(String action, int size)
+ {
+ XWikiStatsService stats = getXWikiContext().getWiki().getStatsService(getXWikiContext());
+ if (stats == null)
+ return Collections.EMPTY_LIST;
+ return stats.getRecentActions(action, size, getXWikiContext());
+ }
+}
Index: xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/api/XWiki.java
===================================================================
--- xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/api/XWiki.java (revision 5888)
+++ xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/api/XWiki.java (working copy)
@@ -50,6 +50,11 @@
protected static final Log LOG = LogFactory.getLog(XWiki.class);
private com.xpn.xwiki.XWiki xwiki;
+
+ /**
+ * @see #getStatsService()
+ */
+ private StatsService statsService;
/**
* XWiki API Constructor
@@ -61,6 +66,7 @@
{
super(context);
this.xwiki = xwiki;
+ this.statsService = new StatsService(context);
}
/**
@@ -1821,6 +1827,7 @@
* @param action action for which to retrieve statistics (view/save/download)
* @return A DocumentStats object with number of actions performed, unique visitors, number of
* visits
+ * @deprecated use {@link #getStatsService()} instead
*/
public DocumentStats getCurrentMonthXWikiStats(String action)
{
@@ -2099,6 +2106,7 @@
* @param action ("view" or "edit")
* @param size how many recent actions to retrieve
* @return a ArrayList of document names
+ * @deprecated use {@link #getStatsService()} instead
*/
public java.util.Collection getRecentActions(String action, int size)
{
@@ -2933,4 +2941,14 @@
long c = Long.parseLong(a) + Long.parseLong(b);
return "" + c;
}
+
+ /**
+ * Access statistics api
+ *
+ * @return a StatsService instance that can be used to retrieve different xwiki statistics
+ */
+ public StatsService getStatsService()
+ {
+ return this.statsService;
+ }
}
Index: xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/stats/api/XWikiStatsService.java
===================================================================
--- xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/stats/api/XWikiStatsService.java (revision 5888)
+++ xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/stats/api/XWikiStatsService.java (working copy)
@@ -21,6 +21,11 @@
package com.xpn.xwiki.stats.api;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.XWikiException;
import com.xpn.xwiki.notify.XWikiActionNotificationInterface;
@@ -25,16 +30,64 @@
import com.xpn.xwiki.XWikiException;
import com.xpn.xwiki.notify.XWikiActionNotificationInterface;
import com.xpn.xwiki.stats.impl.DocumentStats;
-
-import java.util.Collection;
-import java.util.Date;
-import java.util.List;
+import com.xpn.xwiki.stats.impl.Duration;
+import com.xpn.xwiki.stats.impl.Interval;
+import com.xpn.xwiki.stats.impl.Period;
+import com.xpn.xwiki.stats.impl.Scope;
public interface XWikiStatsService extends XWikiActionNotificationInterface {
public void init(XWikiContext context);
+
+ /**
+ * @deprecated use {@link #getDocumentStatistics(String, Scope, Period, Interval, XWikiContext)} instead
+ */
public DocumentStats getDocTotalStats(String docname, String action, XWikiContext context);
+
+ /**
+ * @deprecated use {@link #getDocumentStatistics(String, Scope, Period, Interval, XWikiContext)} instead
+ */
public DocumentStats getDocMonthStats(String docname, String action, Date month, XWikiContext context);
+
+ /**
+ * @deprecated use {@link #getDocumentStatistics(String, Scope, Period, Interval, XWikiContext)} instead
+ */
public DocumentStats getDocDayStats(String docname, String action, Date day, XWikiContext context);
+
+ /**
+ * @deprecated use {@link #getRefererStatistics(Period, Interval, XWikiContext)} instead
+ */
public List getRefMonthStats(String docName, Date month, XWikiContext context) throws XWikiException;
public Collection getRecentActions(String action, int size, XWikiContext context);
+
+ /**
+ * @see com.xpn.xwiki.api.StatsService#getDocumentStatistics(String, Scope, Period, Interval)
+ */
+ List getDocumentStatistics(String action, Scope scope, Period period, Interval interval,
+ XWikiContext context);
+
+ /**
+ * @see com.xpn.xwiki.api.StatsService#getActionStatistics(String, Scope, Period, Period)
+ */
+ List getVisitStatistics(String action, Period period, Interval interval, XWikiContext context);
+
+ /**
+ * @see com.xpn.xwiki.api.StatsService#getRefererStatistics(Period, Interval)
+ */
+ List getRefererStatistics(Period period, Interval interval, XWikiContext context);
+
+ /**
+ * @see com.xpn.xwiki.api.StatsService#getActionStatistics(String, Scope, Period, Period)
+ */
+ Map getActionStatistics(String action, Scope scope, Period period, Duration step,
+ XWikiContext context);
+
+ /**
+ * @see com.xpn.xwiki.api.StatsService#getUserAgentStatistics(Period)
+ */
+ Map getUserAgentStatistics(Period period, XWikiContext context);
+
+ /**
+ * @see com.xpn.xwiki.api.StatsService#getOperatingSystemStatistics(Period)
+ */
+ Map getOperatingSystemStatistics(Period period, XWikiContext context);
}
Index: xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/Duration.java
===================================================================
--- xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/Duration.java (revision 0)
+++ xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/Duration.java (revision 0)
@@ -0,0 +1,56 @@
+/*
+ * See the NOTICE file distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ */
+
+package com.xpn.xwiki.stats.impl;
+
+/**
+ * Immutable duration for retrieving statistics. A duration of time is uniquely identified by its
+ * span. It does not depend on the bounds used for its creation.
+ */
+public class Duration
+{
+ private org.joda.time.Period span;
+
+ public Duration(int years, int months, int weeks, int days)
+ {
+ span = new org.joda.time.Period(years, months, weeks, days, 0, 0, 0, 0);
+ }
+
+ public int getYears()
+ {
+ return span.getYears();
+ }
+
+ public int getMonths()
+ {
+ return span.getMonths();
+ }
+
+ public int getWeeks()
+ {
+ return span.getWeeks();
+ }
+
+ public int getDays()
+ {
+ return span.getDays();
+ }
+}
Index: xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/DurationFactory.java
===================================================================
--- xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/DurationFactory.java (revision 0)
+++ xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/DurationFactory.java (revision 0)
@@ -0,0 +1,104 @@
+/*
+ * See the NOTICE file distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ */
+
+package com.xpn.xwiki.stats.impl;
+
+/**
+ * Helper factory class for creating Duration objects in velocity
+ */
+public class DurationFactory
+{
+ public static final Duration DAY = createDuration(0, 0, 0, 1);
+
+ public static final Duration WEEK = createDuration(0, 0, 1, 0);
+
+ public static final Duration MONTH = createDuration(0, 1, 0, 0);
+
+ public static final Duration YEAR = createDuration(1, 0, 0, 0);
+
+ private static final DurationFactory instance = new DurationFactory();
+
+ private DurationFactory()
+ {
+ }
+
+ public static DurationFactory getInstance()
+ {
+ return instance;
+ }
+
+ public static Duration createDuration(int years, int months, int weeks, int days)
+ {
+ return new Duration(years, months, weeks, days);
+ }
+
+ public static Duration createDays(int days)
+ {
+ return createDuration(0, 0, 0, days);
+ }
+
+ public static Duration createWeeks(int weeks)
+ {
+ return createDuration(0, 0, weeks, 0);
+ }
+
+ public static Duration createMonths(int months)
+ {
+ return createDuration(0, months, 0, 0);
+ }
+
+ public static Duration createYears(int years)
+ {
+ return createDuration(years, 0, 0, 0);
+ }
+
+ /**
+ * Helper method for accessing {@link #DAY} static field in velocity
+ */
+ public static Duration getDAY()
+ {
+ return DAY;
+ }
+
+ /**
+ * Helper method for accessing {@link #WEEK} static field in velocity
+ */
+ public static Duration getWEEK()
+ {
+ return WEEK;
+ }
+
+ /**
+ * Helper method for accessing {@link #MONTH} static field in velocity
+ */
+ public static Duration getMONTH()
+ {
+ return MONTH;
+ }
+
+ /**
+ * Helper method for accessing {@link #YEAR} static field in velocity
+ */
+ public static Duration getYEAR()
+ {
+ return YEAR;
+ }
+}
Index: xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/Interval.java
===================================================================
--- xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/Interval.java (revision 0)
+++ xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/Interval.java (revision 0)
@@ -0,0 +1,58 @@
+/*
+ * See the NOTICE file distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ */
+
+package com.xpn.xwiki.stats.impl;
+
+/**
+ * Immutable continuous integer interval. It can be used for pagination
+ */
+public class Interval
+{
+ private int start;
+
+ private int size;
+
+ public Interval(int start, int size)
+ {
+ this.start = start;
+ this.size = size;
+ }
+
+ public int getStart()
+ {
+ return start;
+ }
+
+ public int getAbsoluteStart()
+ {
+ return Math.abs(start);
+ }
+
+ public int getSize()
+ {
+ return size;
+ }
+
+ public int getAbsoluteSize()
+ {
+ return Math.abs(size);
+ }
+}
Index: xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/IntervalFactory.java
===================================================================
--- xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/IntervalFactory.java (revision 0)
+++ xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/IntervalFactory.java (revision 0)
@@ -0,0 +1,84 @@
+/*
+ * See the NOTICE file distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ */
+
+package com.xpn.xwiki.stats.impl;
+
+/**
+ * Helper factory class for creating Interval objects in velocity
+ */
+public class IntervalFactory
+{
+ public static final Interval ALL = createInterval(0, 0);
+
+ public static final Interval FIRST = createInterval(0, 1);
+
+ public static final Interval LAST = createInterval(0, -1);
+
+ private static final IntervalFactory instance = new IntervalFactory();
+
+ private IntervalFactory()
+ {
+ }
+
+ public static IntervalFactory getInstance()
+ {
+ return instance;
+ }
+
+ public static Interval createInterval(int start, int size)
+ {
+ return new Interval(start, size);
+ }
+
+ public static Interval createHeadInterval(int size)
+ {
+ return createInterval(0, size);
+ }
+
+ public static Interval createTailInterval(int size)
+ {
+ return createInterval(0, -size);
+ }
+
+ /**
+ * Helper method for accessing {@link #ALL} static field in velocity
+ */
+ public static Interval getALL()
+ {
+ return ALL;
+ }
+
+ /**
+ * Helper method for accessing {@link #FIRST} static field in velocity
+ */
+ public static Interval getFIRST()
+ {
+ return FIRST;
+ }
+
+ /**
+ * Helper method for accessing {@link #LAST} static field in velocity
+ */
+ public static Interval getLAST()
+ {
+ return LAST;
+ }
+}
Index: xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/Period.java
===================================================================
--- xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/Period.java (revision 0)
+++ xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/Period.java (revision 0)
@@ -0,0 +1,74 @@
+/*
+ * See the NOTICE file distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ */
+
+package com.xpn.xwiki.stats.impl;
+
+import org.joda.time.Interval;
+import org.joda.time.format.DateTimeFormat;
+import org.joda.time.format.DateTimeFormatter;
+
+/**
+ * Immutable period for retrieving statistics. A period of time is uniquely identified by its
+ * bounds, and not by its span.
+ */
+public class Period
+{
+ private static final DateTimeFormatter DAY_PERIOD_FORMATTER =
+ DateTimeFormat.forPattern("yyyyMMdd");
+
+ private static final DateTimeFormatter MONTH_PERIOD_FORMATTER =
+ DateTimeFormat.forPattern("yyyyMM");
+
+ private Interval interval;
+
+ public Period(long start, long end)
+ {
+ interval = new Interval(start, end);
+ }
+
+ public long getStart()
+ {
+ return interval.getStartMillis();
+ }
+
+ public long getEnd()
+ {
+ return interval.getEndMillis();
+ }
+
+ public int getStartCode()
+ {
+ return Integer.parseInt(getFormatter().print(interval.getStart()));
+ }
+
+ public int getEndCode()
+ {
+ return Integer.parseInt(getFormatter().print(interval.getEnd()));
+ }
+
+ private DateTimeFormatter getFormatter()
+ {
+ if (interval.toPeriod().getMonths() > 1) {
+ return MONTH_PERIOD_FORMATTER;
+ }
+ return DAY_PERIOD_FORMATTER;
+ }
+}
Index: xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/PeriodFactory.java
===================================================================
--- xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/PeriodFactory.java (revision 0)
+++ xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/PeriodFactory.java (revision 0)
@@ -0,0 +1,225 @@
+/*
+ * See the NOTICE file distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ */
+
+package com.xpn.xwiki.stats.impl;
+
+import org.joda.time.DateTime;
+import org.joda.time.MutableDateTime;
+import org.joda.time.format.DateTimeFormat;
+import org.joda.time.format.DateTimeFormatter;
+
+/**
+ * Helper factory class for creating Period objects in velocity
+ */
+public class PeriodFactory
+{
+ /**
+ * The minimum date considered when retrieving all-time statistics
+ */
+ private static final DateTime MIN_DATE = new DateTime(1000, 1, 1, 0, 0, 0, 0);
+
+ /**
+ * The maximum date considered when retrieving all-time statistics
+ */
+ private static final DateTime MAX_DATE = new DateTime(9999, 12, 31, 23, 59, 59, 999);
+
+ public static final Period ALL_TIME =
+ createPeriod(MIN_DATE.getMillis(), MAX_DATE.getMillis());
+
+ private static final DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyyMMdd");
+
+ private static final PeriodFactory instance = new PeriodFactory();
+
+ private PeriodFactory()
+ {
+ }
+
+ public static PeriodFactory getInstance()
+ {
+ return instance;
+ }
+
+ public static Period createPeriod(long start, long end)
+ {
+ return new Period(start, end);
+ }
+
+ /**
+ * Creates a new custom period. The start and end dates must have the following format:
+ * "yyyyMMdd"
+ *
+ * @param start The start date
+ * @param end The end date
+ * @return A new Period instance
+ * @see java.text.SimpleDateFormat
+ */
+ public static Period createPeriod(String start, String end)
+ {
+ return createPeriod(formatter.parseMillis(start), formatter.parseMillis(end));
+ }
+
+ public static Period createDayPeriod(long timestamp)
+ {
+ MutableDateTime mdt = new MutableDateTime(timestamp);
+ return createPeriod(toDayStart(mdt).getMillis(), toDayEnd(mdt).getMillis());
+ }
+
+ /**
+ * @param date The string representation of a date uniquely identifying a day. Use the "yyyyMMdd"
+ * format.
+ * @return The corresponding Period object
+ * @see java.text.SimpleDateFormat
+ */
+ public static Period createDayPeriod(String date)
+ {
+ return createDayPeriod(formatter.parseMillis(date));
+ }
+
+ public static Period getCurrentDay()
+ {
+ return createDayPeriod(new DateTime().getMillis());
+ }
+
+ public static Period createWeekPeriod(long timestamp)
+ {
+ MutableDateTime mdt = new MutableDateTime(timestamp);
+ return createPeriod(toWeekStart(mdt).getMillis(), toWeekEnd(mdt).getMillis());
+ }
+
+ /**
+ * @param date The string representation of a date uniquely identifying a week. Use the
+ * "yyyyMMdd" format.
+ * @return The corresponding Period object
+ * @see java.text.SimpleDateFormat
+ */
+ public static Period createWeekPeriod(String date)
+ {
+ return createWeekPeriod(formatter.parseMillis(date));
+ }
+
+ public static Period getCurrentWeek()
+ {
+ return createWeekPeriod(new DateTime().getMillis());
+ }
+
+ public static Period createMonthPeriod(long timestamp)
+ {
+ MutableDateTime mdt = new MutableDateTime(timestamp);
+ return createPeriod(toMonthStart(mdt).getMillis(), toMonthEnd(mdt).getMillis());
+ }
+
+ /**
+ * @param date The string representation of a date uniquely identifying a month. Use the
+ * "yyyyMMdd" format.
+ * @return The corresponding Period object
+ * @see java.text.SimpleDateFormat
+ */
+ public static Period createMonthPeriod(String date)
+ {
+ return createMonthPeriod(formatter.parseMillis(date));
+ }
+
+ public static Period getCurrentMonth()
+ {
+ return createMonthPeriod(new DateTime().getMillis());
+ }
+
+ public static Period createYearPeriod(long timestamp)
+ {
+ MutableDateTime mdt = new MutableDateTime(timestamp);
+ return createPeriod(toYearStart(mdt).getMillis(), toYearEnd(mdt).getMillis());
+ }
+
+ /**
+ * @param date The string representation of a date uniquely identifying a year. Use the
+ * "yyyyMMdd" format.
+ * @return The corresponding Period object
+ * @see java.text.SimpleDateFormat
+ */
+ public static Period createYearPeriod(String date)
+ {
+ return createYearPeriod(formatter.parseMillis(date));
+ }
+
+ public static Period getCurrentYear()
+ {
+ return createYearPeriod(new DateTime().getMillis());
+ }
+
+ private static MutableDateTime toDayStart(MutableDateTime mdt)
+ {
+ mdt.setHourOfDay(mdt.hourOfDay().getMinimumValue());
+ mdt.setMinuteOfHour(mdt.minuteOfHour().getMinimumValue());
+ mdt.setSecondOfMinute(mdt.secondOfMinute().getMinimumValue());
+ mdt.setMillisOfSecond(mdt.millisOfSecond().getMinimumValue());
+ return mdt;
+ }
+
+ private static MutableDateTime toDayEnd(MutableDateTime mdt)
+ {
+ mdt.addDays(1);
+ return toDayStart(mdt);
+ }
+
+ private static MutableDateTime toWeekStart(MutableDateTime mdt)
+ {
+ mdt.setDayOfWeek(mdt.dayOfWeek().getMinimumValue());
+ return toDayStart(mdt);
+ }
+
+ private static MutableDateTime toWeekEnd(MutableDateTime mdt)
+ {
+ mdt.setDayOfWeek(mdt.dayOfWeek().getMaximumValue());
+ return toDayEnd(mdt);
+ }
+
+ private static MutableDateTime toMonthStart(MutableDateTime mdt)
+ {
+ mdt.setDayOfMonth(mdt.dayOfMonth().getMinimumValue());
+ return toDayStart(mdt);
+ }
+
+ private static MutableDateTime toMonthEnd(MutableDateTime mdt)
+ {
+ mdt.setDayOfMonth(mdt.dayOfMonth().getMaximumValue());
+ return toDayEnd(mdt);
+ }
+
+ private static MutableDateTime toYearStart(MutableDateTime mdt)
+ {
+ mdt.setDayOfYear(mdt.dayOfYear().getMinimumValue());
+ return toDayStart(mdt);
+ }
+
+ private static MutableDateTime toYearEnd(MutableDateTime mdt)
+ {
+ mdt.setDayOfYear(mdt.dayOfYear().getMaximumValue());
+ return toDayEnd(mdt);
+ }
+
+ /**
+ * Helper method for accessing {@link #ALL_TIME} static field in velocity
+ */
+ public static Period getALL_TIME()
+ {
+ return ALL_TIME;
+ }
+}
Index: xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/Scope.java
===================================================================
--- xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/Scope.java (revision 0)
+++ xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/Scope.java (revision 0)
@@ -0,0 +1,102 @@
+/*
+ * See the NOTICE file distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ */
+
+package com.xpn.xwiki.stats.impl;
+
+/**
+ * Immutable scope for retrieving statistics
+ */
+public class Scope
+{
+ public static final int PAGE_SCOPE = 1;
+
+ public static final int SPACE_SCOPE = 2;
+
+ public static final int WIKI_SCOPE = 3;
+
+ public static final int GLOBAL_SCOPE = 4;
+
+ private int type;
+
+ private String name;
+
+ private boolean deep;
+
+ public Scope(int type, String name, boolean deep)
+ {
+ this.type = type;
+ this.name = name;
+ this.deep = deep;
+ }
+
+ public int getType()
+ {
+ return type;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public boolean isDeep()
+ {
+ return deep;
+ }
+
+ public String getPattern()
+ {
+ switch (type) {
+ case PAGE_SCOPE:
+ return getPagePattern();
+ case SPACE_SCOPE:
+ return getSpacePattern();
+ default:
+ return getGlobalPattern();
+ }
+ }
+
+ private String getPagePattern()
+ {
+ // ignore deep
+ if ("".equals(name)) {
+ // a pattern to match any page name
+ return "%.%";
+ }
+ return name;
+ }
+
+ private String getSpacePattern()
+ {
+ if ("".equals(name)) {
+ // TODO a pattern to match any space name
+ return null;
+ } else if (deep) {
+ return name + ".%";
+ }
+ return name;
+ }
+
+ private String getGlobalPattern()
+ {
+ return "";
+ }
+}
Index: xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/ScopeFactory.java
===================================================================
--- xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/ScopeFactory.java (revision 0)
+++ xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/ScopeFactory.java (revision 0)
@@ -0,0 +1,109 @@
+/*
+ * See the NOTICE file distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ */
+
+package com.xpn.xwiki.stats.impl;
+
+/**
+ * Helper factory class for creating Scope objects in velocity
+ */
+public class ScopeFactory
+{
+ private static final ScopeFactory instance = new ScopeFactory();
+
+ public static final Scope ALL_PAGES = createScope(Scope.PAGE_SCOPE, "", false);
+
+ public static final Scope ALL_SPACES = createScope(Scope.SPACE_SCOPE, "", false);
+
+ public static final Scope ALL_WIKIS = createScope(Scope.WIKI_SCOPE, "", false);
+
+ public static final Scope ALL = createScope(Scope.GLOBAL_SCOPE, "", false);
+
+ private ScopeFactory()
+ {
+ }
+
+ public static ScopeFactory getInstance()
+ {
+ return instance;
+ }
+
+ public static Scope createScope(int type, String name, boolean deep)
+ {
+ return new Scope(type, name, deep);
+ }
+
+ public static Scope createPageScope(String pageName)
+ {
+ return createScope(Scope.PAGE_SCOPE, pageName, false);
+ }
+
+ public static Scope createSpaceScope(String spaceName)
+ {
+ return createSpaceScope(spaceName, true);
+ }
+
+ public static Scope createSpaceScope(String spaceName, boolean deep)
+ {
+ return createScope(Scope.SPACE_SCOPE, spaceName, deep);
+ }
+
+ public static Scope createWikiScope(String wikiName)
+ {
+ return createWikiScope(wikiName, true);
+ }
+
+ public static Scope createWikiScope(String wikiName, boolean deep)
+ {
+ return createScope(Scope.WIKI_SCOPE, wikiName, deep);
+ }
+
+ /**
+ * Helper method for accessing {@link #ALL_PAGES} static field in velocity
+ */
+ public static Scope getALL_PAGES()
+ {
+ return ALL_PAGES;
+ }
+
+ /**
+ * Helper method for accessing {@link #ALL_SPACES} static field in velocity
+ */
+ public static Scope getALL_SPACES()
+ {
+ return ALL_SPACES;
+ }
+
+ /**
+ * Helper method for accessing {@link #ALL_WIKIS} static field in velocity
+ */
+ public static Scope getALL_WIKIS()
+ {
+ return ALL_WIKIS;
+ }
+
+ /**
+ * Helper method for accessing {@link #ALL} static field in velocity
+ */
+ public static Scope getALL()
+ {
+ return ALL;
+ }
+}
Index: xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/XWikiStats.java
===================================================================
--- xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/XWikiStats.java (revision 5888)
+++ xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/XWikiStats.java (working copy)
@@ -63,11 +63,7 @@
}
public int hashCode() {
- String str = getName()+getClassName();
- int nb = getNumber();
- if (nb>0)
- str += "_" + nb;
- return str.hashCode();
+ return (getName() + getClassName() + "_" + getNumber()).hashCode();
}
public void setId(int id) {
Index: xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/XWikiStatsServiceImpl.java
===================================================================
--- xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/XWikiStatsServiceImpl.java (revision 5888)
+++ xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/XWikiStatsServiceImpl.java (working copy)
@@ -27,6 +27,9 @@
import com.xpn.xwiki.notify.XWikiActionRule;
import com.xpn.xwiki.notify.XWikiNotificationRule;
import com.xpn.xwiki.stats.api.XWikiStatsService;
+import com.xpn.xwiki.stats.impl.DocumentStats;
+import com.xpn.xwiki.stats.impl.StatsUtil;
+import com.xpn.xwiki.stats.impl.VisitStats;
import com.xpn.xwiki.store.XWikiHibernateStore;
import com.xpn.xwiki.store.XWikiStoreInterface;
import com.xpn.xwiki.store.jcr.XWikiJcrStore;
@@ -43,6 +46,7 @@
import org.apache.portals.graffito.jcr.query.QueryManager;
import org.hibernate.Query;
import org.hibernate.Session;
+import org.joda.time.DateTime;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpSession;
@@ -566,6 +570,206 @@
return cookie;
}
-}
+ /**
+ * {@inheritDoc}
+ */
+ public Map getActionStatistics(String action, Scope scope, Period period, Duration step,
+ XWikiContext context)
+ {
+ DateTime stepStart = new DateTime(period.getStart());
+ DateTime periodEnd = new DateTime(period.getEnd());
+ org.joda.time.Period stepDuration =
+ new org.joda.time.Period(step.getYears(), step.getMonths(), step.getWeeks(), step
+ .getDays(), 0, 0, 0, 0);
+ Map activity = new HashMap();
+ while (stepStart.compareTo(periodEnd) < 0) {
+ DateTime stepEnd = stepStart.plus(stepDuration);
+ if (stepEnd.compareTo(periodEnd) > 0) {
+ stepEnd = periodEnd;
+ }
+ List stats =
+ this.getDocumentStatistics(action, scope, new Period(stepStart.getMillis(),
+ stepEnd.getMillis()), IntervalFactory.FIRST, context);
+ int actionCount = 0;
+ if (stats.size() > 0) {
+ actionCount = ((DocumentStats) stats.get(0)).getPageViews();
+ }
+ activity.put(stepStart, new Integer(actionCount));
+ stepStart = stepEnd;
+ }
+ return activity;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List getDocumentStatistics(String action, Scope scope, Period period,
+ Interval interval, XWikiContext context)
+ {
+ String nameFilter = "name like :name";
+ if (scope.getType() == Scope.SPACE_SCOPE && "".equals(scope.getName())) {
+ nameFilter = "name not like %.% and name is not empty";
+ }
+ String sortOrder = "desc";
+ if (interval.getSize() < 0) {
+ sortOrder = "asc";
+ }
+ XWikiHibernateStore store = null;
+ try {
+ store = context.getWiki().getHibernateStore();
+ store.beginTransaction(context);
+ Session session = store.getSession(context);
+ Query query =
+ session
+ .createQuery("select name, sum(pageViews) from DocumentStats where action=:action and "
+ + nameFilter
+ + " and :startDate <= period and period <= :endDate group by name order by sum(pageViews) "
+ + sortOrder);
+ query.setString("action", action);
+ query.setString("name", scope.getPattern());
+ query.setInteger("startDate", period.getStartCode());
+ query.setInteger("endDate", period.getEndCode());
+
+ List results =
+ getDocumentStatistics(store.search(query, interval.getAbsoluteSize(), interval
+ .getAbsoluteStart(), context), action);
+ if (interval.getSize() < 0) {
+ Collections.reverse(results);
+ }
+ return results;
+ } catch (XWikiException e) {
+ return Collections.EMPTY_LIST;
+ } finally {
+ try {
+ store.endTransaction(context, false);
+ } catch (Exception e) {
+ }
+ }
+ }
+
+ /**
+ * Converts the rows retrieved from the database to a list of DocumentStats instances
+ *
+ * @param resultSet the result of a database query for document statistics
+ * @param action the action for which the statistics were retrieved
+ * @return a list of {@link com.xpn.xwiki.stats.impl.DocumentStats} objects
+ * @see #getDocumentStatistics(String, Scope, Period, Interval, XWikiContext)
+ */
+ private List getDocumentStatistics(List resultSet, String action)
+ {
+ Date now = Calendar.getInstance().getTime();
+ List stats = new ArrayList(resultSet.size());
+ Iterator it = resultSet.iterator();
+ while (it.hasNext()) {
+ Object[] result = (Object[]) it.next();
+ // We can't represent a custom period (e.g. year, week or some time interval) in the
+ // database and thus we use a default one, which sould be ignored
+ DocumentStats docStats =
+ new DocumentStats((String) result[0], action, now, StatsUtil.PERIOD_DAY);
+ docStats.setPageViews(((Integer) result[1]).intValue());
+ stats.add(docStats);
+ }
+ return stats;
+ }
+
+ public Map getOperatingSystemStatistics(Period period, XWikiContext context)
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public List getRefererStatistics(Period period, Interval interval, XWikiContext context)
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public Map getUserAgentStatistics(Period period, XWikiContext context)
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public List getVisitStatistics(String action, Period period, Interval interval,
+ XWikiContext context)
+ {
+ String sortOrder = "desc";
+ if (interval.getSize() < 0) {
+ sortOrder = "asc";
+ }
+ String orderByClause =
+ "order by sum(pageSaves) " + sortOrder + ", sum(pageViews) " + sortOrder
+ + ", sum(downloads) " + sortOrder;
+ if (action.equals("save")) {
+ orderByClause = "order by sum(pageSaves) " + sortOrder;
+ } else if (action.equals("view")) {
+ orderByClause = "order by sum(pageViews) " + sortOrder;
+ } else if (action.equals("download")) {
+ orderByClause = "order by sum(downloads) " + sortOrder;
+ }
+ XWikiHibernateStore store = null;
+ try {
+ store = context.getWiki().getHibernateStore();
+ store.beginTransaction(context);
+ Session session = store.getSession(context);
+ Query query =
+ session
+ .createQuery("select name, uniqueID, cookie, IP, userAgent, sum(pageSaves), sum(pageViews), sum(downloads) from VisitStats where :startDate <= startDate and endDate < :endDate group by name "
+ + orderByClause);
+ query.setDate("startDate", new Date(period.getStart()));
+ query.setDate("endDate", new Date(period.getEnd()));
+ List results =
+ getVisitStatistics(store.search(query, interval.getAbsoluteSize(), interval
+ .getAbsoluteStart(), context), new DateTime(period.getStart()),
+ new DateTime(period.getEnd()));
+ if (interval.getSize() < 0) {
+ Collections.reverse(results);
+ }
+ return results;
+ } catch (XWikiException e) {
+ return Collections.EMPTY_LIST;
+ } finally {
+ try {
+ store.endTransaction(context, false);
+ } catch (Exception e) {
+ }
+ }
+ }
+ /**
+ * Converts the rows retrieved from the database to a list of VisitStats instances
+ *
+ * @param resultSet the result of a database query for visitor statistics
+ * @param startDate the start date used in the query
+ * @param endDate the end date used in the query
+ * @return a list of {@link com.xpn.xwiki.stats.impl.VisitStats} objects
+ * @see #getVisitStatistics(Period, Interval, XWikiContext)
+ */
+ private List getVisitStatistics(List resultSet, DateTime startDate, DateTime endDate)
+ {
+ List stats = new ArrayList(resultSet.size());
+ Iterator it = resultSet.iterator();
+ while (it.hasNext()) {
+ Object[] result = (Object[]) it.next();
+ String name = (String) result[0];
+ String uniqueID = (String) result[1];
+ String cookie = (String) result[2];
+ String ip = (String) result[3];
+ String userAgent = (String) result[4];
+ int pageSaves = ((Integer) result[5]).intValue();
+ int pageViews = ((Integer) result[6]).intValue();
+ int downloads = ((Integer) result[7]).intValue();
+ VisitStats vs =
+ new VisitStats(name, uniqueID, cookie, ip, userAgent, new Date(startDate
+ .getMillis()), StatsUtil.PERIOD_DAY);
+ vs.setStartDate(new Date(startDate.getMillis()));
+ vs.setEndDate(new Date(endDate.getMillis()));
+ vs.setPageSaves(pageSaves);
+ vs.setPageViews(pageViews);
+ vs.setDownloads(downloads);
+ stats.add(vs);
+ }
+ return stats;
+ }
+}