Index: xwiki-platform-core/xwiki-core/pom.xml =================================================================== --- xwiki-platform-core/xwiki-core/pom.xml (revision 5846) +++ 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,206 @@ +/* + * 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 org.joda.time.DateTime; + +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.Interval; +import com.xpn.xwiki.stats.impl.Period; +import com.xpn.xwiki.stats.impl.Scope; + +/** + * 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); + } + + /** + * Helper method for creating an empty scope in velocity. + * + * @return + */ + public Scope createScope() + { + return new Scope(); + } + + /** + * Helper method for creating a period of time in velocity. + * + * @param start The start date + * @param end The end date + * @return A new period of time, bounded by the specified start and end dates. + */ + public Period createPeriod(DateTime start, DateTime end) + { + return new Period(start, end); + } + + /** + * Helper method for creating an integer interval in velocity. It may be needed at pagination. + * + * @param start The start of the interval + * @param size The size of the interval + * @return A new Interval instance + */ + public Interval createInterval(int start, int size) + { + return new Interval(start, size); + } + + /** + * 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 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(Period period, Interval interval) + { + XWikiStatsService stats = getXWikiContext().getWiki().getStatsService(getXWikiContext()); + if (stats == null) + return Collections.EMPTY_LIST; + return stats.getVisitStatistics(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, Period 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 5846) +++ 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 5846) +++ xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/stats/api/XWikiStatsService.java (working copy) @@ -21,6 +21,13 @@ package com.xpn.xwiki.stats.api; +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.Map; + +import org.joda.time.DateTime; + import com.xpn.xwiki.XWikiContext; import com.xpn.xwiki.XWikiException; import com.xpn.xwiki.notify.XWikiActionNotificationInterface; @@ -25,10 +32,9 @@ 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.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); @@ -37,4 +43,36 @@ public DocumentStats getDocDayStats(String docname, String action, Date day, XWikiContext context); 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#getVisitStatistics(Period, Interval) + */ + List getVisitStatistics(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, Period 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/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,55 @@ +/* + * 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; + +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 void setStart(int start) + { + this.start = start; + } + + public int getSize() + { + return size; + } + + public void setSize(int size) + { + this.size = size; + } +} 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,81 @@ +/* + * 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.MutableInterval; +import org.joda.time.format.DateTimeFormat; +import org.joda.time.format.DateTimeFormatter; + +public class Period +{ + private MutableInterval interval; + + public Period(DateTime start, DateTime end) + { + interval = new MutableInterval(start, end); + } + + public DateTime getStart() + { + return interval.getStart(); + } + + public void setStart(DateTime start) + { + interval.setStart(start); + } + + public DateTime getEnd() + { + return interval.getEnd(); + } + + public void setEnd(DateTime end) + { + interval.setEnd(end); + } + + public int getStartAsInt() + { + return Integer.parseInt(format(getStart(), getPattern())); + } + + public int getEndAsInt() + { + return Integer.parseInt(format(getEnd(), getPattern())); + } + + private String getPattern() + { + if (interval.toPeriod().getMonths() < 0) { + return "yyyMMdd"; + } + return "yyyMM"; + } + + private static String format(DateTime date, String pattern) + { + DateTimeFormatter dtf = DateTimeFormat.forPattern(pattern); + return dtf.print(date); + } +} 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,110 @@ +/* + * 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 java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +public class Scope +{ + public static class Entry + { + private String name; + + private boolean deep; + + public Entry(String name, boolean deep) + { + this.name = name; + this.deep = deep; + } + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public boolean isDeep() + { + return deep; + } + + public void setDeep(boolean deep) + { + this.deep = deep; + } + + public int hashCode() + { + return name.hashCode(); + } + + public boolean equals(Object obj) + { + if (this == obj) + return true; + if (obj == null) + return false; + if (!(obj instanceof Entry)) + return false; + final Entry other = (Entry) obj; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + return true; + } + } + + private Set entries = new HashSet(); + + public Scope() + { + } + + public void addDocument(String name) + { + addDocument(name, false); + } + + public void addDocument(String name, boolean deep) + { + entries.add(new Entry(name, deep)); + } + + public void removeDocument(String name) + { + entries.remove(new Entry(name, false)); + } + + public Iterator iterator() + { + return entries.iterator(); + } +} Index: xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/StatsUtil.java =================================================================== --- xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/StatsUtil.java (revision 5846) +++ xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/StatsUtil.java (working copy) @@ -24,6 +24,8 @@ import java.util.Calendar; import java.util.Date; +import org.joda.time.DateTime; + /** * Utility class for statistics * @@ -62,4 +64,12 @@ + cal.get(Calendar.DAY_OF_MONTH); } } + + /** + * @see #getPeriodAsInt(Date, int) + */ + public static int getPeriodAsInt(DateTime period, int type) + { + return getPeriodAsInt(new Date(period.getMillis()), type); + } } 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 5846) +++ 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,8 @@ import org.apache.portals.graffito.jcr.query.QueryManager; import org.hibernate.Query; import org.hibernate.Session; +import org.joda.time.DateTime; +import org.joda.time.MutableDateTime; import javax.servlet.http.Cookie; import javax.servlet.http.HttpSession; @@ -566,6 +571,41 @@ return cookie; } -} + public Map getActionStatistics(String action, Scope scope, Period period, Period step, + XWikiContext context) + { + // TODO Auto-generated method stub + return null; + } + + public List getDocumentStatistics(String action, Scope scope, Period period, + Interval interval, XWikiContext context) + { + // TODO Auto-generated method stub + return null; + } + + 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(Period period, Interval interval, XWikiContext context) + { + // TODO Auto-generated method stub + return null; + } +}