Index: xwiki-core/src/main/java/com/xpn/xwiki/api/StatsService.java =================================================================== --- xwiki-core/src/main/java/com/xpn/xwiki/api/StatsService.java (revision 6076) +++ xwiki-core/src/main/java/com/xpn/xwiki/api/StatsService.java (working copy) @@ -38,7 +38,7 @@ import com.xpn.xwiki.stats.impl.ScopeFactory; /** - * Statistics api. The statistics module need to be activated (xwiki.stats=1 in xwiki.cfg) + * Statistics api. The Statistics module need to be activated (xwiki.stats=1 in xwiki.cfg) */ public class StatsService extends Api { @@ -48,7 +48,12 @@ } /** - * @return true if the statistics application is activated in the xwiki.cfg + * The Statistics module is disabled by default for improved performances. It can be globally + * activated by setting the value of xwiki.stats to 1 + * in the xwiki.cfg configuration file. Use this method to test if at + * some point the Statistics module is enabled or disabled. + * + * @return true if the Statistics module is enabled */ public boolean isEnabled() { @@ -56,7 +61,8 @@ } /** - * @return A helper factory for creating Scope objects in velocity. + * @return A helper factory for creating {@link com.xpn.xwiki.stats.impl.Scope} objects in + * velocity. */ public ScopeFactory getScopeFactory() { @@ -64,7 +70,8 @@ } /** - * @return A helper factory for creating a Period objects in velocity. + * @return A helper factory for creating {@link com.xpn.xwiki.stats.impl.Period} objects in + * velocity. */ public PeriodFactory getPeriodFactory() { @@ -72,7 +79,8 @@ } /** - * @return A helper factory for creating a Period objects in velocity. + * @return A helper factory for creating {@link com.xpn.xwiki.stats.impl.Duration} objects in + * velocity. */ public DurationFactory getDurationFactory() { @@ -80,7 +88,8 @@ } /** - * @return A helper factory for creating Interval objects in velocity. + * @return A helper factory for creating {@link com.xpn.xwiki.stats.impl.Interval} objects in + * velocity. */ public IntervalFactory getIntervalFactory() { @@ -90,7 +99,9 @@ /** * Retrieves document statistics. * - * @param action Can be one of: "view", "save", "download" + * @param action The action the results should be ordered by. It can be one of: "view", "save" + * or "download". If the action is "view" then the documents are ordered by the + * number of times they have been viewed so far. * @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 @@ -108,7 +119,9 @@ /** * Retrieves visit statistics * - * @param action The action the results should be ordered by + * @param action The action the results should be ordered by. It can be one of: "view", "save" + * or "download". If the action is "view" then the visitors are ordered by the number + * of pages they have viewed so far. * @param period The period of time * @param interval The sub-interval to return from the entire result set. Use this parameter for * pagination @@ -163,7 +176,7 @@ * Shows how the statistics for the specified action have evolved over the specified period of * time. * - * @param action + * @param action The action for which to retrieve statistics * @param scope The set of documents to consider * @param period The period of time * @param step The step used for sampling the period Index: xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/Duration.java =================================================================== --- xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/Duration.java (revision 6076) +++ xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/Duration.java (working copy) @@ -23,7 +23,10 @@ /** * 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. + * span. For instance, a duration of 3 minutes doesn't imply a specific start time. It can start at + * any time, but it takes just 3 minutes. A Duration can be used to sample a Period of time. For + * instance the period between November 1th 2007 and December 1th 2007 can be divided in samples + * each having a duration of 3 days. */ public class Duration { @@ -29,6 +32,14 @@ { private org.joda.time.Period span; + /** + * Creates a duration by specifying a value for each of its fields. + * + * @param years The number of years + * @param months The number of months + * @param weeks The number of weeks + * @param days The number of days + */ public Duration(int years, int months, int weeks, int days) { span = new org.joda.time.Period(years, months, weeks, days, 0, 0, 0, 0); @@ -34,6 +45,9 @@ span = new org.joda.time.Period(years, months, weeks, days, 0, 0, 0, 0); } + /** + * @return The number of years this duration has + */ public int getYears() { return span.getYears(); @@ -39,6 +53,9 @@ return span.getYears(); } + /** + * @return The number of months this duration has + */ public int getMonths() { return span.getMonths(); @@ -44,6 +61,9 @@ return span.getMonths(); } + /** + * @return The number of weeks this duration has + */ public int getWeeks() { return span.getWeeks(); @@ -49,6 +69,9 @@ return span.getWeeks(); } + /** + * @return The number of days this duration has + */ public int getDays() { return span.getDays(); Index: xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/DurationFactory.java =================================================================== --- xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/DurationFactory.java (revision 6076) +++ xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/DurationFactory.java (working copy) @@ -26,14 +26,29 @@ */ public class DurationFactory { + /** + * A duration of exactly one day + */ public static final Duration DAY = createDuration(0, 0, 0, 1); + /** + * A duration of exactly one week + */ public static final Duration WEEK = createDuration(0, 0, 1, 0); + /** + * A duration of exactly one month + */ public static final Duration MONTH = createDuration(0, 1, 0, 0); + /** + * A duration of exactly one year + */ public static final Duration YEAR = createDuration(1, 0, 0, 0); + /** + * This factory is implemented as a singleton. This is its only instance. + */ private static final DurationFactory instance = new DurationFactory(); private DurationFactory() @@ -40,6 +55,9 @@ { } + /** + * @return The only instance of this singleton factory + */ public static DurationFactory getInstance() { return instance; @@ -45,6 +63,9 @@ return instance; } + /** + * @see Duration#Duration(int, int, int, int) + */ public static Duration createDuration(int years, int months, int weeks, int days) { return new Duration(years, months, weeks, days); @@ -50,6 +71,13 @@ return new Duration(years, months, weeks, days); } + /** + * Creates a new Duration instance having just the specified number of days. All the other + * fields are 0. + * + * @param days The number of days + * @return A new Duration instance + */ public static Duration createDays(int days) { return createDuration(0, 0, 0, days); @@ -55,6 +83,13 @@ return createDuration(0, 0, 0, days); } + /** + * Creates a new Duration instance having just the specified number of weeks. All the other + * fields are 0. + * + * @param weeks The number of weeks + * @return A new Duration instance + */ public static Duration createWeeks(int weeks) { return createDuration(0, 0, weeks, 0); @@ -60,6 +95,13 @@ return createDuration(0, 0, weeks, 0); } + /** + * Creates a new Duration instance having just the specified number of months. All the other + * fields are 0. + * + * @param months The number of months + * @return A new Duration instance + */ public static Duration createMonths(int months) { return createDuration(0, months, 0, 0); @@ -65,6 +107,13 @@ return createDuration(0, months, 0, 0); } + /** + * Creates a new Duration instance having just the specified number of years. All the other + * fields are 0. + * + * @param years The number of years + * @return A new Duration instance + */ public static Duration createYears(int years) { return createDuration(years, 0, 0, 0); Index: xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/Interval.java =================================================================== --- xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/Interval.java (revision 6076) +++ xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/Interval.java (working copy) @@ -26,10 +26,24 @@ */ public class Interval { + /** + * The start of the interval. It can be both positive and negative. A negative start is usually + * associated with an interval which is relative to the end of the list it is applied to. + */ private int start; + /** + * The size of the interval. It can be both positive and negative. A negative size is usually + * associated with an interval which is relative to the end of the list it is applied to. + */ private int size; + /** + * Creates a new interval having the specified start and size. + * + * @param start The start of the interval + * @param size The size of the interval + */ public Interval(int start, int size) { this.start = start; @@ -36,6 +50,9 @@ this.size = size; } + /** + * @see #start + */ public int getStart() { return start; @@ -41,6 +58,9 @@ return start; } + /** + * @return The absolute value (nonnegative) of this interval's start + */ public int getAbsoluteStart() { return Math.abs(start); @@ -46,6 +66,9 @@ return Math.abs(start); } + /** + * @see #size + */ public int getSize() { return size; @@ -51,6 +74,9 @@ return size; } + /** + * @return The absolute value (nonnegative) of this interval's size + */ public int getAbsoluteSize() { return Math.abs(size); Index: xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/IntervalFactory.java =================================================================== --- xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/IntervalFactory.java (revision 6076) +++ xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/IntervalFactory.java (working copy) @@ -26,12 +26,24 @@ */ public class IntervalFactory { + /** + * The interval that matches the entire list it is applied to. + */ public static final Interval ALL = createInterval(0, 0); + /** + * The interval that matches just the first element of the list it is applied to. + */ public static final Interval FIRST = createInterval(0, 1); + /** + * The interval that matches just the last element of the list it is applied to. + */ public static final Interval LAST = createInterval(0, -1); + /** + * This factory is implemented as a singleton. This is its only instance. + */ private static final IntervalFactory instance = new IntervalFactory(); private IntervalFactory() @@ -38,6 +50,9 @@ { } + /** + * @return The only instance of this singleton factory + */ public static IntervalFactory getInstance() { return instance; @@ -43,6 +58,9 @@ return instance; } + /** + * @see Interval#Interval(int, int) + */ public static Interval createInterval(int start, int size) { return new Interval(start, size); @@ -48,14 +66,28 @@ return new Interval(start, size); } + /** + * Creates a new Interval starting from 0 and having the specified size. It matches the first + * size elements of the list it is applied to. + * + * @param size The size of the interval + * @return A new Interval instance + */ public static Interval createHeadInterval(int size) { - return createInterval(0, size); + return createInterval(0, Math.abs(size)); } + /** + * Creates a new Interval starting from the end of the list it is applied to and having the + * specified size. It matches the last size elements of the list. + * + * @param size The size of the interval + * @return A new Interval instance + */ public static Interval createTailInterval(int size) { - return createInterval(0, -size); + return createInterval(0, -Math.abs(size)); } /** Index: xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/Period.java =================================================================== --- xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/Period.java (revision 6076) +++ xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/Period.java (working copy) @@ -27,13 +27,20 @@ /** * Immutable period for retrieving statistics. A period of time is uniquely identified by its - * bounds, and not by its span. + * bounds, and not by its span. Two periods of time with the same span are different if they don't + * start at the same time. */ public class Period { + /** + * Formatter associated with periods that have less than a month + */ private static final DateTimeFormatter DAY_PERIOD_FORMATTER = DateTimeFormat.forPattern("yyyyMMdd"); + /** + * Formatter associated with periods that have at least one month + */ private static final DateTimeFormatter MONTH_PERIOD_FORMATTER = DateTimeFormat.forPattern("yyyyMM"); @@ -39,6 +46,13 @@ private Interval interval; + /** + * Creates a new time Period from the specified start time to the specified end time. Both ends + * of the period are given as time stamps (the number of milliseconds from 1970-01-01T00:00:00Z) + * + * @param start The period start as the number of milliseconds from 1970-01-01T00:00:00Z + * @param end The period end as the number of milliseconds from 1970-01-01T00:00:00Z + */ public Period(long start, long end) { interval = new Interval(start, end); @@ -44,6 +58,9 @@ interval = new Interval(start, end); } + /** + * @return The period start as the number of milliseconds from 1970-01-01T00:00:00Z + */ public long getStart() { return interval.getStartMillis(); @@ -49,6 +66,9 @@ return interval.getStartMillis(); } + /** + * @return The period end as the number of milliseconds from 1970-01-01T00:00:00Z + */ public long getEnd() { return interval.getEndMillis(); @@ -54,6 +74,11 @@ return interval.getEndMillis(); } + /** + * @return The start of the period formatted with the associated formatter. Usually this is how + * the start of the period is stored in the database. + * @see #getFormatter() + */ public int getStartCode() { return Integer.parseInt(getFormatter().print(interval.getStart())); @@ -59,6 +84,11 @@ return Integer.parseInt(getFormatter().print(interval.getStart())); } + /** + * @return The end of the period formatted with the associated formatter. Usually this is how + * the end of the period is stored in the database. + * @see #getFormatter() + */ public int getEndCode() { return Integer.parseInt(getFormatter().print(interval.getEnd())); @@ -64,6 +94,11 @@ return Integer.parseInt(getFormatter().print(interval.getEnd())); } + /** + * @return The formatter associated with this Period instance + * @see #DAY_PERIOD_FORMATTER + * @see #MONTH_PERIOD_FORMATTER + */ private DateTimeFormatter getFormatter() { if (interval.toPeriod().getMonths() >= 1) { Index: xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/PeriodFactory.java =================================================================== --- xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/PeriodFactory.java (revision 6076) +++ xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/PeriodFactory.java (working copy) @@ -41,6 +41,9 @@ */ private static final DateTime MAX_DATE = new DateTime(9999, 12, 31, 23, 59, 59, 999); + /** + * The period of time between {@link #MIN_DATE} and {@link #MAX_DATE} + */ public static final Period ALL_TIME = createPeriod(MIN_DATE.getMillis(), MAX_DATE.getMillis()); @@ -46,6 +49,9 @@ private static final DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyyMMdd"); + /** + * This factory is implemented as a singleton. This is its only instance. + */ private static final PeriodFactory instance = new PeriodFactory(); private PeriodFactory() @@ -52,6 +58,9 @@ { } + /** + * @return The only instance of this singleton factory + */ public static PeriodFactory getInstance() { return instance; @@ -57,6 +66,9 @@ return instance; } + /** + * @see Period#Period(long, long) + */ public static Period createPeriod(long start, long end) { return new Period(start, end); @@ -76,6 +88,13 @@ return createPeriod(formatter.parseMillis(start), formatter.parseMillis(end)); } + /** + * Creates a new Period instance that matches exactly the day that includes the specified time + * stamp. + * + * @param timestamp The milliseconds from 1970-01-01T00:00:00Z + * @return A new Period instance + */ public static Period createDayPeriod(long timestamp) { MutableDateTime mdt = new MutableDateTime(timestamp); @@ -83,8 +102,10 @@ } /** - * @param date The string representation of a date uniquely identifying a day. Use the "yyyyMMdd" - * format. + * Creates a new Period instance that matches exactly the day that includes the specified date. + * + * @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 */ @@ -93,6 +114,9 @@ return createDayPeriod(formatter.parseMillis(date)); } + /** + * @return The period of time matching the current day + */ public static Period getCurrentDay() { return createDayPeriod(new DateTime().getMillis()); @@ -98,6 +122,13 @@ return createDayPeriod(new DateTime().getMillis()); } + /** + * Creates a new Period instance that matches exactly the week that includes the specified time + * stamp. + * + * @param timestamp The milliseconds from 1970-01-01T00:00:00Z + * @return A new Period instance + */ public static Period createWeekPeriod(long timestamp) { MutableDateTime mdt = new MutableDateTime(timestamp); @@ -105,6 +136,8 @@ } /** + * Creates a new Period instance that matches exactly the week that includes the specified date. + * * @param date The string representation of a date uniquely identifying a week. Use the * "yyyyMMdd" format. * @return The corresponding Period object @@ -115,6 +148,9 @@ return createWeekPeriod(formatter.parseMillis(date)); } + /** + * @return The period of time matching the current week + */ public static Period getCurrentWeek() { return createWeekPeriod(new DateTime().getMillis()); @@ -120,6 +156,13 @@ return createWeekPeriod(new DateTime().getMillis()); } + /** + * Creates a new Period instance that matches exactly the month that includes the specified time + * stamp. + * + * @param timestamp The milliseconds from 1970-01-01T00:00:00Z + * @return A new Period instance + */ public static Period createMonthPeriod(long timestamp) { MutableDateTime mdt = new MutableDateTime(timestamp); @@ -127,6 +170,9 @@ } /** + * Creates a new Period instance that matches exactly the month that includes the specified + * date. + * * @param date The string representation of a date uniquely identifying a month. Use the * "yyyyMMdd" format. * @return The corresponding Period object @@ -137,6 +183,9 @@ return createMonthPeriod(formatter.parseMillis(date)); } + /** + * @return The period of time matching the current month + */ public static Period getCurrentMonth() { return createMonthPeriod(new DateTime().getMillis()); @@ -142,6 +191,13 @@ return createMonthPeriod(new DateTime().getMillis()); } + /** + * Creates a new Period instance that matches exactly the year that includes the specified time + * stamp. + * + * @param timestamp The milliseconds from 1970-01-01T00:00:00Z + * @return A new Period instance + */ public static Period createYearPeriod(long timestamp) { MutableDateTime mdt = new MutableDateTime(timestamp); @@ -149,6 +205,8 @@ } /** + * Creates a new Period instance that matches exactly the year that includes the specified date. + * * @param date The string representation of a date uniquely identifying a year. Use the * "yyyyMMdd" format. * @return The corresponding Period object @@ -159,6 +217,9 @@ return createYearPeriod(formatter.parseMillis(date)); } + /** + * @return The period of time matching the current year + */ public static Period getCurrentYear() { return createYearPeriod(new DateTime().getMillis()); Index: xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/Scope.java =================================================================== --- xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/Scope.java (revision 6076) +++ xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/Scope.java (working copy) @@ -22,24 +22,66 @@ package com.xpn.xwiki.stats.impl; /** - * Immutable scope for retrieving statistics + * Immutable scope for retrieving statistics. A scope is associated with a single document but it + * can match any number of documents. Here, a document can be a page, a space, a wiki or the entire + * application as a unit. For instance, a scope associated with a space can match all the pages + * within that space. */ public class Scope { + /** + * Any scope that is associated with a page + */ public static final int PAGE_SCOPE = 1; + /** + * Any scope that is associated with a space + */ public static final int SPACE_SCOPE = 2; + /** + * Any scope that is associated with a wiki + */ public static final int WIKI_SCOPE = 3; + /** + * The scope that is associated with the entire application as a unit + */ public static final int GLOBAL_SCOPE = 4; + /** + * The type of the scope. It can be {@link #PAGE_SCOPE}, {@link #SPACE_SCOPE}, + * {@link #WIKI_SCOPE} or {@link #GLOBAL_SCOPE} + */ private int type; + /** + * Depending on the scope type it can mean: + * + */ private String name; + /** + * Specifies whether the document given by the {@link #name} field should be considered as a + * unit or not. When {@link #deep} is false the scope matches only the document + * with the given {@link #name} (taken as a unit). Otherwise the scope matches all its sub + * documents (like all pages within a space). + */ private boolean deep; + /** + * Creates a new Scope instance with the specified field values. + * + * @param type The type of the scope + * @param name The name of the document associated with this scope + * @param deep true for matching all sub documents; false for + * matching the associated document as a unit + */ public Scope(int type, String name, boolean deep) { this.type = type; @@ -47,6 +89,9 @@ this.deep = deep; } + /** + * @see #type + */ public int getType() { return type; @@ -52,6 +97,9 @@ return type; } + /** + * @see #name + */ public String getName() { return name; @@ -57,6 +105,9 @@ return name; } + /** + * @see #deep + */ public boolean isDeep() { return deep; @@ -62,6 +113,9 @@ return deep; } + /** + * @return The pattern used for matching document names in the database + */ public String getPattern() { switch (type) { @@ -74,6 +128,10 @@ } } + /** + * @return The pattern used in the case of a {@link #PAGE_SCOPE} + * @see #getPattern() + */ private String getPagePattern() { // ignore deep @@ -84,6 +142,10 @@ return name; } + /** + * @return The pattern used in the case of a {@link #SPACE_SCOPE} + * @see #getPattern() + */ private String getSpacePattern() { if ("".equals(name)) { @@ -95,6 +157,10 @@ return name; } + /** + * @return The pattern used in the case of a {@link #GLOBAL_SCOPE} + * @see #getPattern() + */ private String getGlobalPattern() { return ""; Index: xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/ScopeFactory.java =================================================================== --- xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/ScopeFactory.java (revision 6076) +++ xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/ScopeFactory.java (working copy) @@ -26,14 +26,29 @@ */ public class ScopeFactory { + /** + * This factory is implemented as a singleton. This is its only instance. + */ private static final ScopeFactory instance = new ScopeFactory(); + /** + * A scope that matches all pages within any space and any wiki + */ public static final Scope ALL_PAGES = createScope(Scope.PAGE_SCOPE, "", false); + /** + * A scope that matches all spaces within any wiki + */ public static final Scope ALL_SPACES = createScope(Scope.SPACE_SCOPE, "", false); + /** + * A scope that matches all wikis within the application + */ public static final Scope ALL_WIKIS = createScope(Scope.WIKI_SCOPE, "", false); + /** + * A scope that matches the entire application as a unit + */ public static final Scope ALL = createScope(Scope.GLOBAL_SCOPE, "", false); private ScopeFactory() @@ -40,6 +55,9 @@ { } + /** + * @return The only instance of this singleton factory + */ public static ScopeFactory getInstance() { return instance; @@ -45,6 +63,9 @@ return instance; } + /** + * @see Scope#Scope(int, String, boolean) + */ public static Scope createScope(int type, String name, boolean deep) { return new Scope(type, name, deep); @@ -50,6 +71,12 @@ return new Scope(type, name, deep); } + /** + * Creates a new scope associated with the specified page. + * + * @param pageName A page name + * @return A new Scope instance + */ public static Scope createPageScope(String pageName) { return createScope(Scope.PAGE_SCOPE, pageName, false); @@ -55,6 +82,12 @@ return createScope(Scope.PAGE_SCOPE, pageName, false); } + /** + * Creates a new scope associated with the specified space and matching all its pages. + * + * @param spaceName A space name + * @return A new Scope instance + */ public static Scope createSpaceScope(String spaceName) { return createSpaceScope(spaceName, true); @@ -60,6 +93,14 @@ return createSpaceScope(spaceName, true); } + /** + * Creates a new scope associated with the specified space. + * + * @param spaceName A space name + * @param deep true for matching all its pages; false for matching + * this space as a unit + * @return A new Scope instance + */ public static Scope createSpaceScope(String spaceName, boolean deep) { return createScope(Scope.SPACE_SCOPE, spaceName, deep); @@ -65,6 +106,12 @@ return createScope(Scope.SPACE_SCOPE, spaceName, deep); } + /** + * Creates a new scope associated with the specified wiki and matching all its spaces. + * + * @param wikiName A wiki name + * @return A new Scope instance + */ public static Scope createWikiScope(String wikiName) { return createWikiScope(wikiName, true); @@ -70,6 +117,14 @@ return createWikiScope(wikiName, true); } + /** + * Creates a new scope associated with the specified wiki. + * + * @param wikiName A wiki name + * @param deep true for matching all its spaces; false for + * matching this wiki as a unit + * @return A new Scope instance + */ public static Scope createWikiScope(String wikiName, boolean deep) { return createScope(Scope.WIKI_SCOPE, wikiName, deep); Index: xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/XWikiStatsServiceImpl.java =================================================================== --- xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/XWikiStatsServiceImpl.java (revision 6076) +++ xwiki-core/src/main/java/com/xpn/xwiki/stats/impl/XWikiStatsServiceImpl.java (working copy) @@ -572,6 +572,8 @@ /** * {@inheritDoc} + * + * @see XWikiStatsService#getActionStatistics(String, Scope, Period, Duration, XWikiContext) */ public Map getActionStatistics(String action, Scope scope, Period period, Duration step, XWikiContext context) @@ -602,6 +604,8 @@ /** * {@inheritDoc} + * + * @see XWikiStatsService#getDocumentStatistics(String, Scope, Period, Interval, XWikiContext) */ public List getDocumentStatistics(String action, Scope scope, Period period, Interval interval, XWikiContext context) @@ -678,6 +682,8 @@ /** * {@inheritDoc} + * + * @see XWikiStatsService#getBackLinkStatistics(String, Scope, Period, Interval, XWikiContext) */ public List getBackLinkStatistics(String domain, Scope scope, Period period, Interval interval, XWikiContext context) @@ -732,6 +738,8 @@ /** * {@inheritDoc} + * + * @see XWikiStatsService#getRefererStatistics(String, Scope, Period, Interval, XWikiContext) */ public List getRefererStatistics(String domain, Scope scope, Period period, Interval interval, XWikiContext context) @@ -811,6 +819,8 @@ /** * {@inheritDoc} + * + * @see XWikiStatsService#getVisitStatistics(String, Period, Interval, XWikiContext) */ public List getVisitStatistics(String action, Period period, Interval interval, XWikiContext context) @@ -836,7 +846,7 @@ 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 " + .createQuery("select name, 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())); @@ -875,13 +885,13 @@ 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(); + String uniqueID = ""; + String cookie = ""; + String ip = ""; + String userAgent = ""; + int pageSaves = ((Integer) result[1]).intValue(); + int pageViews = ((Integer) result[2]).intValue(); + int downloads = ((Integer) result[3]).intValue(); VisitStats vs = new VisitStats(name, uniqueID, cookie, ip, userAgent, new Date(startDate .getMillis()), StatsUtil.PERIOD_DAY); Index: xwiki-core/src/test/java/com/xpn/xwiki/stats/impl/DurationFactoryTest.java =================================================================== --- xwiki-core/src/test/java/com/xpn/xwiki/stats/impl/DurationFactoryTest.java (revision 0) +++ xwiki-core/src/test/java/com/xpn/xwiki/stats/impl/DurationFactoryTest.java (revision 0) @@ -0,0 +1,146 @@ +/* + * 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 junit.framework.TestCase; + +/** + * Unit tests for the {@link DurationFactory} class. + */ +public class DurationFactoryTest extends TestCase +{ + /** + * Test for {@link DurationFactory#DAY} + */ + public void testDay() + { + doDurationTest(DurationFactory.DAY, 0, 0, 0, 1); + } + + /** + * Test for {@link DurationFactory#WEEK} + */ + public void testWeek() + { + doDurationTest(DurationFactory.WEEK, 0, 0, 1, 0); + } + + /** + * Test for {@link DurationFactory#MONTH} + */ + public void testMonth() + { + doDurationTest(DurationFactory.MONTH, 0, 1, 0, 0); + } + + /** + * Test for {@link DurationFactory#YEAR} + */ + public void testYear() + { + doDurationTest(DurationFactory.YEAR, 1, 0, 0, 0); + } + + /** + * Test for {@link DurationFactory#createDuration(int, int, int, int)} + */ + public void testCreateDuration() + { + doCreateDurationTest(0, 0, 0, 0); + doCreateDurationTest(1, 2, 5, 4); + doCreateDurationTest(-1, -2, -3, -14); + doCreateDurationTest(0, -2, 3, 0); + } + + private void doCreateDurationTest(int years, int months, int weeks, int days) + { + doDurationTest(DurationFactory.createDuration(years, months, weeks, days), years, months, + weeks, days); + } + + /** + * Test for {@link DurationFactory#createDays(int)} + */ + public void testCreateDays() + { + doCreateDaysTest(0); + doCreateDaysTest(-3); + doCreateDaysTest(15); + } + + private void doCreateDaysTest(int days) + { + doDurationTest(DurationFactory.createDays(days), 0, 0, 0, days); + } + + /** + * Test for {@link DurationFactory#createWeeks(int)} + */ + public void testCreateWeeks() + { + doCreateWeeksTest(0); + doCreateWeeksTest(-1); + doCreateWeeksTest(5); + } + + private void doCreateWeeksTest(int weeks) + { + doDurationTest(DurationFactory.createWeeks(weeks), 0, 0, weeks, 0); + } + + /** + * Test for {@link DurationFactory#createMonths(int)} + */ + public void testCreateMonths() + { + doCreateMonthsTest(0); + doCreateMonthsTest(-13); + doCreateMonthsTest(1); + } + + private void doCreateMonthsTest(int months) + { + doDurationTest(DurationFactory.createMonths(months), 0, months, 0, 0); + } + + /** + * Test for {@link DurationFactory#createYears(int)} + */ + public void testCreateYears() + { + doCreateYearsTest(0); + doCreateYearsTest(-2); + doCreateYearsTest(103); + } + + private void doCreateYearsTest(int years) + { + doDurationTest(DurationFactory.createYears(years), years, 0, 0, 0); + } + + private void doDurationTest(Duration d, int years, int months, int weeks, int days) + { + assertEquals(d.getDays(), days); + assertEquals(d.getWeeks(), weeks); + assertEquals(d.getMonths(), months); + assertEquals(d.getYears(), years); + } +} Index: xwiki-core/src/test/java/com/xpn/xwiki/stats/impl/DurationTest.java =================================================================== --- xwiki-core/src/test/java/com/xpn/xwiki/stats/impl/DurationTest.java (revision 0) +++ xwiki-core/src/test/java/com/xpn/xwiki/stats/impl/DurationTest.java (revision 0) @@ -0,0 +1,49 @@ +/* + * 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 junit.framework.TestCase; + +/** + * Unit tests for the {@link Duration} class. + */ +public class DurationTest extends TestCase +{ + /** + * Test for {@link Duration#Duration(int, int, int, int)} + */ + public void testConstructor() + { + doConstructorTest(0, 0, 0, 0); + doConstructorTest(1, 2, 3, 4); + doConstructorTest(-1, -2, -3, -4); + doConstructorTest(0, -2, 3, 0); + } + + private void doConstructorTest(int years, int months, int weeks, int days) + { + Duration d = new Duration(years, months, weeks, days); + assertEquals(years, d.getYears()); + assertEquals(months, d.getMonths()); + assertEquals(weeks, d.getWeeks()); + assertEquals(days, d.getDays()); + } +} Index: xwiki-core/src/test/java/com/xpn/xwiki/stats/impl/IntervalFactoryTest.java =================================================================== --- xwiki-core/src/test/java/com/xpn/xwiki/stats/impl/IntervalFactoryTest.java (revision 0) +++ xwiki-core/src/test/java/com/xpn/xwiki/stats/impl/IntervalFactoryTest.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; + +import junit.framework.TestCase; + +/** + * Unit tests for the {@link IntervalFactory} class. + */ +public class IntervalFactoryTest extends TestCase +{ + /** + * Test for {@link IntervalFactory#ALL} + */ + public void testAll() + { + doIntervalTest(IntervalFactory.ALL, 0, 0); + } + + /** + * Test for {@link IntervalFactory#FIRST} + */ + public void testFirst() + { + doIntervalTest(IntervalFactory.FIRST, 0, 1); + } + + /** + * Test for {@link IntervalFactory#LAST} + */ + public void testLast() + { + doIntervalTest(IntervalFactory.LAST, 0, -1); + } + + /** + * Test for {@link IntervalFactory#createInterval(int, int)} + */ + public void testCreateInterval() + { + doCreateIntervalTest(0, 0); + doCreateIntervalTest(0, 3); + doCreateIntervalTest(0, -4); + doCreateIntervalTest(-10, 0); + doCreateIntervalTest(-10, 5); + doCreateIntervalTest(-10, -9); + } + + private void doCreateIntervalTest(int start, int size) + { + doIntervalTest(IntervalFactory.createInterval(start, size), start, size); + } + + /** + * Test for {@link IntervalFactory#createHeadInterval(int)} + */ + public void testCreateHeadInterval() + { + doCreateHeadIntervalTest(0); + doCreateHeadIntervalTest(3); + doCreateHeadIntervalTest(-7); + } + + private void doCreateHeadIntervalTest(int size) + { + doIntervalTest(IntervalFactory.createHeadInterval(size), 0, Math.abs(size)); + } + + /** + * Test for {@link IntervalFactory#createTailInterval(int)} + */ + public void testCreateTailInterval() + { + doCreateTailIntervalTest(0); + doCreateTailIntervalTest(3); + doCreateTailIntervalTest(-7); + } + + private void doCreateTailIntervalTest(int size) + { + doIntervalTest(IntervalFactory.createTailInterval(size), 0, -Math.abs(size)); + } + + private void doIntervalTest(Interval i, int start, int size) + { + assertEquals(i.getStart(), start); + assertEquals(i.getSize(), size); + assertEquals(i.getAbsoluteStart(), Math.abs(start)); + assertEquals(i.getAbsoluteSize(), Math.abs(size)); + } +} Index: xwiki-core/src/test/java/com/xpn/xwiki/stats/impl/IntervalTest.java =================================================================== --- xwiki-core/src/test/java/com/xpn/xwiki/stats/impl/IntervalTest.java (revision 0) +++ xwiki-core/src/test/java/com/xpn/xwiki/stats/impl/IntervalTest.java (revision 0) @@ -0,0 +1,51 @@ +/* + * 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 junit.framework.TestCase; + +/** + * Unit tests for the {@link Interval} class. + */ +public class IntervalTest extends TestCase +{ + /** + * Test for {@link Interval#Interval(int, int)} + */ + public void testConstructor() + { + doConstructorTest(0, 0); + doConstructorTest(0, 5); + doConstructorTest(0, -7); + doConstructorTest(-10, 0); + doConstructorTest(-10, 4); + doConstructorTest(-10, -1); + } + + private void doConstructorTest(int start, int size) + { + Interval i = new Interval(start, size); + assertEquals(i.getStart(), start); + assertEquals(i.getSize(), size); + assertEquals(i.getAbsoluteStart(), Math.abs(start)); + assertEquals(i.getAbsoluteSize(), Math.abs(size)); + } +} Index: xwiki-core/src/test/java/com/xpn/xwiki/stats/impl/StatsUtilTest.java =================================================================== --- xwiki-core/src/test/java/com/xpn/xwiki/stats/impl/StatsUtilTest.java (revision 6076) +++ xwiki-core/src/test/java/com/xpn/xwiki/stats/impl/StatsUtilTest.java (working copy) @@ -26,8 +26,6 @@ /** * Unit tests for the {@link StatsUtil} class. - * - * @version $Id: $ */ public class StatsUtilTest extends TestCase {