[jboss-svn-commits] JBL Code SVN: r35590 - in labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src: main/java/org/jboss/community/sbs/plugin/reports/monthly and 16 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Wed Oct 20 07:01:51 EDT 2010


Author: velias
Date: 2010-10-20 07:01:50 -0400 (Wed, 20 Oct 2010)
New Revision: 35590

Added:
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/ReportGenerator.java
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/Aggregator.java
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/AggregatorUtils.java
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/FISHEYEAggregator.java
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/JIRAAggregator.java
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/SBSAggregator.java
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/SingleKeyListAggregator.java
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/config/
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/config/FishEyeRepositoryConfig.java
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/config/ProjectConfig.java
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/config/ReportConfig.java
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/config/ReportConfigParser.java
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/config/SystemDataConfig.java
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/config/SystemDataConfigFISHEYE.java
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/config/SystemDataConfigJIRA.java
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/config/SystemDataConfigSBS.java
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/config/SystemId.java
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/valuesource/
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/valuesource/FISHEYEValueSource.java
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/valuesource/JIRAValueSource.java
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/valuesource/SBSValueKey.java
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/valuesource/SBSValueSource.java
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/valuesource/SBSValueType.java
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/valuesource/ValueSource.java
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/community/
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/community/sbs/
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/community/sbs/plugin/
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/community/sbs/plugin/reports/
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/community/sbs/plugin/reports/monthly/
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/AggregatorTestBase.java
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/AggregatorUtilsTest.java
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/FISHEYEAggregatorTest.java
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/JIRAAggregatorTest.java
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/SBSAggregatorTest.java
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/community/sbs/plugin/reports/monthly/config/
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/community/sbs/plugin/reports/monthly/config/ReportConfigParserTest.java
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/community/sbs/plugin/reports/monthly/config/SystemDataConfigTest.java
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/community/sbs/plugin/reports/monthly/valuesource/
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/community/sbs/plugin/reports/monthly/valuesource/SBSValueKeyTest.java
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/resources/
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/resources/monthly_report_config.xml
Log:
first commit of report aggregation code. Not complete yet.

Added: labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/ReportGenerator.java
===================================================================
--- labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/ReportGenerator.java	                        (rev 0)
+++ labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/ReportGenerator.java	2010-10-20 11:01:50 UTC (rev 35590)
@@ -0,0 +1,40 @@
+package org.jboss.community.sbs.plugin.reports.monthly;
+
+import java.io.InputStream;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.jboss.community.sbs.plugin.reports.monthly.aggregator.Aggregator;
+import org.jboss.community.sbs.plugin.reports.monthly.config.ReportConfigParser;
+import org.jboss.community.sbs.plugin.reports.monthly.config.SystemId;
+
+/**
+ * JBoss.org monthly report generator.
+ * 
+ * @author Vlastimil Elias (velias at redhat dot com)
+ */
+public class ReportGenerator {
+
+  /**
+   * 
+   * 
+   * @param configFile input stream with report content configuration file. See {@link ReportConfigParser}.
+   * @param dateFrom
+   * @param DateTo
+   * @return
+   */
+  public String generateReport(InputStream configFile, Date dateFrom, Date DateTo) {
+
+    // TODO RG parse config file
+    // TODO RG prepare value sources
+    // TODO RG prepare aggregators
+    // TODO RG generate report
+
+    Map<SystemId, Aggregator> agregators = new HashMap<SystemId, Aggregator>();
+
+    return null;
+
+  }
+
+}

Added: labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/Aggregator.java
===================================================================
--- labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/Aggregator.java	                        (rev 0)
+++ labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/Aggregator.java	2010-10-20 11:01:50 UTC (rev 35590)
@@ -0,0 +1,36 @@
+package org.jboss.community.sbs.plugin.reports.monthly.aggregator;
+
+import org.jboss.community.sbs.plugin.reports.monthly.config.SystemDataConfig;
+import org.jboss.community.sbs.plugin.reports.monthly.valuesource.ValueSource;
+
+/**
+ * Interface for data aggregator. Aggregator is used to aggregate report values from {@link ValueSource} for one
+ * configuration element ({@link SystemDataConfig}) for distinct project and system.
+ * 
+ * @author Vlastimil Elias (velias at redhat dot com)
+ */
+public interface Aggregator<T extends SystemDataConfig> {
+
+  /**
+   * Value used in report data if real value not available. Used in case when configuration doesn't contains any part
+   * relevant for given system.
+   */
+  public static final String VALUE_NOT_AVAILABLE = "N/A";
+
+  /**
+   * Get report column header labels.
+   * 
+   * @return array with column labels for report header
+   */
+  public abstract String[] getHeaderValues();
+
+  /**
+   * Get aggregated report values for given config element. Must return same length array in all cases so final csv file
+   * has same length rows!! Length must be same as returned from {@link #getHeaderValues()} too!!
+   * 
+   * @param config element to get data for
+   * @return String array with values.
+   */
+  public abstract String[] getReportValues(T config);
+
+}
\ No newline at end of file

Added: labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/AggregatorUtils.java
===================================================================
--- labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/AggregatorUtils.java	                        (rev 0)
+++ labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/AggregatorUtils.java	2010-10-20 11:01:50 UTC (rev 35590)
@@ -0,0 +1,127 @@
+package org.jboss.community.sbs.plugin.reports.monthly.aggregator;
+
+import java.util.List;
+
+import org.apache.commons.lang.StringUtils;
+
+/**
+ * Utility class for aggregator implementations.
+ * 
+ * @author Vlastimil Elias (velias at redhat dot com)
+ */
+public class AggregatorUtils {
+
+  /**
+   * Convert source String array into long array. Empty String is converted to 0. {@link Long#parseLong(String)} is used
+   * to convert value.
+   * 
+   * @param source string array
+   * @return long array
+   * @throws NumberFormatException
+   */
+  public static long[] stringArray2longArray(String[] source) {
+    if (source == null || source.length == 0) {
+      return null;
+    }
+    long[] ret = new long[source.length];
+    int index = 0;
+    for (String s : source) {
+      long v = 0;
+      if (StringUtils.isNotEmpty(s)) {
+        v = Long.parseLong(s);
+      }
+      ret[index++] = v;
+    }
+
+    return ret;
+  }
+
+  /**
+   * Add values from array2 to values in array1.
+   * 
+   * @param array1 target of add. Final values are here.
+   * @param array2 source of added values.
+   */
+  public static void arrayAdd(long[] array1, long[] array2) {
+    if (array1 == null || array1.length == 0)
+      return;
+
+    for (int i = 0; i < array1.length; i++) {
+      array1[i] += array2[i];
+    }
+  }
+
+  /**
+   * Convert source long array into String array.
+   * 
+   * @param source long array to convert
+   * @return String array
+   */
+  public static String[] longArray2stringArray(long[] source) {
+    if (source == null || source.length == 0) {
+      return null;
+    }
+    String[] ret = new String[source.length];
+    int index = 0;
+    for (long s : source) {
+      ret[index++] = s + "";
+    }
+
+    return ret;
+  }
+
+  /**
+   * Create String array filled with value.
+   * 
+   * @param length of array
+   * @param value to fill in
+   * @return filled array
+   */
+  public static String[] createFilledArray(int length, String value) {
+    String[] ret = new String[length];
+    for (int i = 0; i < length; i++) {
+      ret[i] = value;
+    }
+    return ret;
+  }
+
+  /**
+   * Create long array filled with value.
+   * 
+   * @param length of array
+   * @param value to fill in
+   * @return filled array
+   */
+  public static long[] createFilledArray(int length, long value) {
+    long[] ret = new long[length];
+    for (int i = 0; i < length; i++) {
+      ret[i] = value;
+    }
+    return ret;
+  }
+
+/**
+   * Get long value from first item in input array. If input is null or empty, then 0 is returned. {@link Long#parseLong(String)) is used to convert value.
+   * 
+   * @param input array to get value from
+   * @return long value
+   * @throws NumberFormatException
+   */
+  public static long getLongValueFromFirstItem(String[] input) {
+    if (input == null || input.length == 0) {
+      return 0l;
+    }
+    return Long.parseLong(input[0]);
+  }
+
+  /**
+   * Null safe check for empty List.
+   * 
+   * @param list to check (may be null)
+   * @return true if list is null or empty
+   */
+  public static boolean isEmptyList(List<?> list) {
+    return list == null || list.isEmpty();
+  }
+
+}

Added: labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/FISHEYEAggregator.java
===================================================================
--- labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/FISHEYEAggregator.java	                        (rev 0)
+++ labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/FISHEYEAggregator.java	2010-10-20 11:01:50 UTC (rev 35590)
@@ -0,0 +1,35 @@
+package org.jboss.community.sbs.plugin.reports.monthly.aggregator;
+
+import java.util.List;
+
+import org.jboss.community.sbs.plugin.reports.monthly.config.FishEyeRepositoryConfig;
+import org.jboss.community.sbs.plugin.reports.monthly.config.SystemDataConfigFISHEYE;
+import org.jboss.community.sbs.plugin.reports.monthly.valuesource.ValueSource;
+
+/**
+ * Data aggregator for FISHEYE system.
+ * 
+ * @author Vlastimil Elias (velias at redhat dot com)
+ */
+public class FISHEYEAggregator extends SingleKeyListAggregator<SystemDataConfigFISHEYE, FishEyeRepositoryConfig> {
+
+  /**
+   * Create FISHEYE aggregator to aggregate data from given data source.
+   * 
+   * @param valueSource to be used
+   */
+  public FISHEYEAggregator(ValueSource<FishEyeRepositoryConfig> valueSource) {
+    super(valueSource, 2);
+  }
+
+  @Override
+  protected List<FishEyeRepositoryConfig> getKeyList(SystemDataConfigFISHEYE config) {
+    return config.getRepositories();
+  }
+
+  @Override
+  public String[] getHeaderValues() {
+    return new String[] { "Source Code Commits (Red Hat)", "Source Code Commits (Community)" };
+  }
+
+}

Added: labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/JIRAAggregator.java
===================================================================
--- labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/JIRAAggregator.java	                        (rev 0)
+++ labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/JIRAAggregator.java	2010-10-20 11:01:50 UTC (rev 35590)
@@ -0,0 +1,35 @@
+package org.jboss.community.sbs.plugin.reports.monthly.aggregator;
+
+import java.util.List;
+
+import org.jboss.community.sbs.plugin.reports.monthly.config.SystemDataConfigJIRA;
+import org.jboss.community.sbs.plugin.reports.monthly.valuesource.ValueSource;
+
+/**
+ * Data aggregator for JIRA system.
+ * 
+ * @author Vlastimil Elias (velias at redhat dot com)
+ */
+public class JIRAAggregator extends SingleKeyListAggregator<SystemDataConfigJIRA, String> {
+
+  /**
+   * Create JIRA aggregator to aggregate data from given data source.
+   * 
+   * @param valueSource to be used
+   */
+  public JIRAAggregator(ValueSource<String> valueSource) {
+    super(valueSource, 4);
+  }
+
+  @Override
+  protected List<String> getKeyList(SystemDataConfigJIRA config) {
+    return config.getProjectKeys();
+  }
+
+  @Override
+  public String[] getHeaderValues() {
+    return new String[] { "Reported Issues (Red Hat)", "Reported Issues (Community)", "Resolved Issues (Red Hat)",
+        "Resolved Issues (Community)" };
+  }
+
+}

Added: labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/SBSAggregator.java
===================================================================
--- labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/SBSAggregator.java	                        (rev 0)
+++ labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/SBSAggregator.java	2010-10-20 11:01:50 UTC (rev 35590)
@@ -0,0 +1,118 @@
+package org.jboss.community.sbs.plugin.reports.monthly.aggregator;
+
+import java.util.List;
+
+import org.jboss.community.sbs.plugin.reports.monthly.config.SystemDataConfigSBS;
+import org.jboss.community.sbs.plugin.reports.monthly.valuesource.SBSValueKey;
+import org.jboss.community.sbs.plugin.reports.monthly.valuesource.SBSValueType;
+import org.jboss.community.sbs.plugin.reports.monthly.valuesource.ValueSource;
+
+/**
+ * Data aggregator for SBS system.
+ * 
+ * @author Vlastimil Elias (velias at redhat dot com)
+ */
+public class SBSAggregator implements Aggregator<SystemDataConfigSBS> {
+
+  private ValueSource<SBSValueKey> valueSource;
+
+  private static final int ARRAY_LEN = 16;
+
+  /**
+   * Create SBS aggregator to aggregate data from given data source.
+   * 
+   * @param valueSource to be used
+   */
+  public SBSAggregator(ValueSource<SBSValueKey> valueSource) {
+    this.valueSource = valueSource;
+  }
+
+  @Override
+  public String[] getHeaderValues() {
+    return new String[] { "New Wiki Articles (Red Hat)", "New Wiki Articles (Community)",
+        "Wiki Articles Edits (Red Hat)", "Wiki Articles Edits (Community)", "Wiki Comments (Red Hat)",
+        "Wiki Comments (Community)", "User Forum Questions (Red Hat)", "User Forum Questions (Community)",
+        "User Forum Helpful Answers (Red Hat)", "User Forum Correct Answers (Red Hat)",
+        "User Forum Helpful Answers (Community)", "User Forum Correct Answers (Community)",
+        "Dev Forum Threads (Red Hat)", "Dev Forum Threads (Community)", "Dev Forum Replies (Red Hat)",
+        "Dev Forum Replies (Community)" };
+  }
+
+  @Override
+  public String[] getReportValues(SystemDataConfigSBS config) {
+    List<String> devSpacesList = (config != null ? config.getDevSpaces() : null);
+    List<String> userSpacesList = (config != null ? config.getUserSpaces() : null);
+
+    String[] ret = AggregatorUtils.createFilledArray(ARRAY_LEN, VALUE_NOT_AVAILABLE);
+
+    if (!AggregatorUtils.isEmptyList(devSpacesList) || !AggregatorUtils.isEmptyList(userSpacesList)) {
+
+      ret[0] = getReportValue(SBSValueType.WIKI_NEW_ARTICLE_RH, devSpacesList, userSpacesList);
+      ret[1] = getReportValue(SBSValueType.WIKI_NEW_ARTICLE_CM, devSpacesList, userSpacesList);
+      ret[2] = getReportValue(SBSValueType.WIKI_EDIT_ARTICLE_RH, devSpacesList, userSpacesList);
+      ret[3] = getReportValue(SBSValueType.WIKI_EDIT_ARTICLE_CM, devSpacesList, userSpacesList);
+      ret[4] = getReportValue(SBSValueType.WIKI_COMMENT_RH, devSpacesList, userSpacesList);
+      ret[5] = getReportValue(SBSValueType.WIKI_COMMENT_CM, devSpacesList, userSpacesList);
+      ret[6] = getReportValue(SBSValueType.FORUM_QUESTION_RH, userSpacesList);
+      ret[7] = getReportValue(SBSValueType.FORUM_QUESTION_CM, userSpacesList);
+      ret[8] = getReportValue(SBSValueType.FORUM_ANSWER_HELPFUL_RH, userSpacesList);
+      ret[9] = getReportValue(SBSValueType.FORUM_ANSWER_CORRECT_RH, userSpacesList);
+      ret[10] = getReportValue(SBSValueType.FORUM_ANSWER_HELPFUL_CM, userSpacesList);
+      ret[11] = getReportValue(SBSValueType.FORUM_ANSWER_CORRECT_CM, userSpacesList);
+      ret[12] = getReportValue(SBSValueType.FORUM_THREAD_RH, devSpacesList);
+      ret[13] = getReportValue(SBSValueType.FORUM_THREAD_CM, devSpacesList);
+      ret[14] = getReportValue(SBSValueType.FORUM_REPLY_RH, devSpacesList);
+      ret[15] = getReportValue(SBSValueType.FORUM_REPLY_CM, devSpacesList);
+    }
+
+    return ret;
+
+  }
+
+  /**
+   * Get report value of given type, summed from all spaces in given list.
+   * 
+   * @param valueType type of value to get
+   * @param spaces list of Space identifiers to sum values for
+   * @return summed value. Return {@link Aggregator#VALUE_NOT_AVAILABLE} if input spaces list is empty.
+   * 
+   */
+  protected String getReportValue(SBSValueType valueType, List<String> spaces) {
+    return getReportValue(valueType, spaces, null);
+  }
+
+  /**
+   * Get report value of given type, summed from all spaces in both given lists.
+   * 
+   * @param valueType type of value to get
+   * @param spaces1 list of Space identifiers to sum values for
+   * @param spaces2 list of Space identifiers to sum values for
+   * @return summed value. Return {@link Aggregator#VALUE_NOT_AVAILABLE} if both input spaces lists are empty.
+   * 
+   */
+  protected String getReportValue(SBSValueType valueType, List<String> spaces1, List<String> spaces2) {
+
+    if (AggregatorUtils.isEmptyList(spaces1) && AggregatorUtils.isEmptyList(spaces2)) {
+      return VALUE_NOT_AVAILABLE;
+    }
+
+    long ret = 0;
+    SBSValueKey key = new SBSValueKey(valueType);
+    if (!AggregatorUtils.isEmptyList(spaces1)) {
+      for (String s : spaces1) {
+        // TODO move this conversion to configuration parsing
+        key.setSpaceId(Long.parseLong(s));
+        ret += AggregatorUtils.getLongValueFromFirstItem(valueSource.getValues(key));
+      }
+    }
+    if (!AggregatorUtils.isEmptyList(spaces2)) {
+      for (String s : spaces2) {
+        // TODO move this conversion to configuration parsing
+        key.setSpaceId(Long.parseLong(s));
+        ret += AggregatorUtils.getLongValueFromFirstItem(valueSource.getValues(key));
+      }
+    }
+    return ret + "";
+  }
+
+}

Added: labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/SingleKeyListAggregator.java
===================================================================
--- labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/SingleKeyListAggregator.java	                        (rev 0)
+++ labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/SingleKeyListAggregator.java	2010-10-20 11:01:50 UTC (rev 35590)
@@ -0,0 +1,58 @@
+package org.jboss.community.sbs.plugin.reports.monthly.aggregator;
+
+import java.util.List;
+
+import org.jboss.community.sbs.plugin.reports.monthly.config.SystemDataConfig;
+import org.jboss.community.sbs.plugin.reports.monthly.valuesource.ValueSource;
+
+/**
+ * Abstract Data aggregator for config with single list of keys.
+ * 
+ * @author Vlastimil Elias (velias at redhat dot com)
+ * 
+ * @param T type of config element this aggregator works with
+ * @param Z type of data row key obtained from config element and used to call {@link ValueSource}.
+ */
+public abstract class SingleKeyListAggregator<T extends SystemDataConfig, Z> implements Aggregator<T> {
+
+  private ValueSource<Z> valueSource;
+
+  private int arrayLen;
+
+  /**
+   * Create aggregator.
+   * 
+   * @param valueSource source used to obtain values for report from.
+   * @param arrayLen length of array returned by this aggregator. dataSource must return same lenght data too!
+   */
+  public SingleKeyListAggregator(ValueSource<Z> valueSource, int arrayLen) {
+    super();
+    this.valueSource = valueSource;
+    this.arrayLen = arrayLen;
+  }
+
+  @Override
+  public String[] getReportValues(T config) {
+    List<Z> keyList = (config != null ? getKeyList(config) : null);
+    if (!AggregatorUtils.isEmptyList(keyList)) {
+      long[] ret = AggregatorUtils.createFilledArray(arrayLen, 0l);
+      for (Z projectKey : keyList) {
+        String[] row = valueSource.getValues(projectKey);
+        AggregatorUtils.arrayAdd(ret, AggregatorUtils.stringArray2longArray(row));
+      }
+      return AggregatorUtils.longArray2stringArray(ret);
+    } else {
+      return AggregatorUtils.createFilledArray(arrayLen, VALUE_NOT_AVAILABLE);
+    }
+  }
+
+  /**
+   * Get list of keys from config element. Data are then aggregated for this list of keys. If list is null or empty,
+   * then aggregator return array of {@link Aggregator#VALUE_NOT_AVAILABLE}.
+   * 
+   * @param config element to get keys from
+   * @return list of keys
+   */
+  protected abstract List<Z> getKeyList(T config);
+
+}

Added: labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/config/FishEyeRepositoryConfig.java
===================================================================
--- labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/config/FishEyeRepositoryConfig.java	                        (rev 0)
+++ labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/config/FishEyeRepositoryConfig.java	2010-10-20 11:01:50 UTC (rev 35590)
@@ -0,0 +1,73 @@
+package org.jboss.community.sbs.plugin.reports.monthly.config;
+
+import org.apache.commons.lang.StringUtils;
+
+/**
+ * FishEye repository configuration.
+ * 
+ * @author Vlastimil Elias (velias at redhat dot com)
+ */
+public class FishEyeRepositoryConfig {
+
+  /**
+   * Name of FE repository.
+   */
+  private String name;
+
+  /**
+   * Path inside of FE repository. May be null. If present must begin with slash (/).
+   */
+  private String path;
+
+  /**
+   * Constructor.
+   */
+  public FishEyeRepositoryConfig() {
+  }
+
+  /**
+   * Constructor.
+   * 
+   * @param name repository name
+   */
+  public FishEyeRepositoryConfig(String name) {
+    this.name = name;
+  }
+
+  /**
+   * Gets the name of FE repository.
+   * 
+   * @return the name of FE repository
+   */
+  public String getName() {
+    return name;
+  }
+
+  /**
+   * Sets the name of FE repository.
+   * 
+   * @param name the new name of FE repository
+   */
+  public void setName(String name) {
+    this.name = StringUtils.trimToNull(name);
+  }
+
+  /**
+   * Gets the path inside of FE repository.
+   * 
+   * @return the path inside of FE repository
+   */
+  public String getPath() {
+    return path;
+  }
+
+  /**
+   * Sets the path inside of FE repository. May be null. If present must begin with slash (/).
+   * 
+   * @param path the new path inside of FE repository
+   */
+  public void setPath(String path) {
+    this.path = StringUtils.trimToNull(path);
+  }
+
+}

Added: labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/config/ProjectConfig.java
===================================================================
--- labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/config/ProjectConfig.java	                        (rev 0)
+++ labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/config/ProjectConfig.java	2010-10-20 11:01:50 UTC (rev 35590)
@@ -0,0 +1,77 @@
+package org.jboss.community.sbs.plugin.reports.monthly.config;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Report configuration for one project.
+ * 
+ * @author Vlastimil Elias (velias at redhat dot com)
+ */
+public class ProjectConfig {
+
+  /** Name of project. */
+  private String name;
+
+  /**
+   * Configuration how to obtain/consolidate data for this project from distinct systems.
+   */
+  private List<SystemDataConfig> systemDataConfig;
+
+  /**
+   * Gets the name of project.
+   * 
+   * @return the name of project
+   */
+  public String getName() {
+    return name;
+  }
+
+  /**
+   * Sets the name of project.
+   * 
+   * @param name the new name of project
+   */
+  public void setName(String name) {
+    this.name = name;
+  }
+
+  /**
+   * Gets the configuration how to obtain/consolidate data for this project from distinct systems.
+   * 
+   * @return the systemDataConfig
+   */
+  public List<SystemDataConfig> getSystemDataConfig() {
+    return systemDataConfig;
+  }
+
+  /**
+   * Add configuration how to obtain/consolidate data for this project from one system.
+   * 
+   * @param systemDataConfig the systemDataConfig to set
+   */
+  public void addSystemDataConfig(SystemDataConfig systemDataConfig) {
+    if (this.systemDataConfig == null) {
+      this.systemDataConfig = new ArrayList<SystemDataConfig>();
+    }
+    this.systemDataConfig.add(systemDataConfig);
+  }
+
+  /**
+   * Get config for specified system.
+   * 
+   * @param sid system to get config for
+   * @return config for given system or null
+   */
+  public SystemDataConfig getSystemDataConfigFor(SystemId sid) {
+    if (systemDataConfig == null)
+      return null;
+    for (SystemDataConfig sdc : systemDataConfig) {
+      if (sid.equals(sdc.getSystem())) {
+        return sdc;
+      }
+    }
+    return null;
+  }
+
+}

Added: labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/config/ReportConfig.java
===================================================================
--- labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/config/ReportConfig.java	                        (rev 0)
+++ labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/config/ReportConfig.java	2010-10-20 11:01:50 UTC (rev 35590)
@@ -0,0 +1,36 @@
+package org.jboss.community.sbs.plugin.reports.monthly.config;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Basic configuration object.
+ * 
+ * @author Vlastimil Elias (velias at redhat dot com)
+ */
+public class ReportConfig {
+
+  /**
+   * List of configured projects.
+   */
+  List<ProjectConfig> projects = new ArrayList<ProjectConfig>();
+
+  /**
+   * Get configured projects.
+   * 
+   * @return the projects
+   */
+  public List<ProjectConfig> getProjects() {
+    return projects;
+  }
+
+  /**
+   * Add project to configuration.
+   * 
+   * @param proj to add
+   */
+  public void addProjectConfig(ProjectConfig proj) {
+    projects.add(proj);
+  }
+
+}

Added: labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/config/ReportConfigParser.java
===================================================================
--- labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/config/ReportConfigParser.java	                        (rev 0)
+++ labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/config/ReportConfigParser.java	2010-10-20 11:01:50 UTC (rev 35590)
@@ -0,0 +1,89 @@
+package org.jboss.community.sbs.plugin.reports.monthly.config;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.commons.digester.Digester;
+import org.xml.sax.SAXException;
+
+/**
+ * Parser for report configuration file. Example of file:
+ * 
+ * <pre>
+ * &lt;projects>
+ *     &lt;project name="JBoss Microcontainer"&gt;
+ *         &lt;jira&gt;
+ *             &lt;project-key&gt;JBAS&lt;/project-key&gt;
+ *             &lt;project-key&gt;JBMC&lt;/project-key&gt;
+ *         &lt;/jira&gt;
+ *         &lt;sbs&gt;
+ *             &lt;user&gt;
+ *               &lt;space&gt;3333&lt;/space&gt;
+ *               &lt;space&gt;4443&lt;/space&gt;
+ *             &lt;/user&gt;
+ *             &lt;dev&gt;
+ *               &lt;space&gt;3334&lt;/space&gt;
+ *               &lt;space&gt;4444&lt;/space&gt;
+ *             &lt;/dev&gt;
+ *         &lt;/sbs&gt;
+ *         &lt;fisheye&gt;
+ *             &lt;repo name="JBAS_SVN" path="/trunk/projects/mc" /&gt;
+ *             &lt;repo name="JBMC_SVN" /&gt;
+ *         &lt;/fisheye&gt;
+ *     &lt;/project&gt;
+ *     &lt;project name="JBoss AS"&gt;
+ *     ...
+ *     &lt;/project&gt;
+ *     ...
+ * &lt;/projects>
+ * </pre>
+ * 
+ * @author Vlastimil Elias (velias at redhat dot com)
+ */
+public class ReportConfigParser {
+
+  /**
+   * Parse configuration file into object.
+   * 
+   * @param is stream with config XML file
+   * @return configuration in object representation
+   * @throws SAXException
+   * @throws IOException
+   */
+  public ReportConfig parseConfigFile(InputStream is) throws IOException, SAXException {
+
+    Digester dig = new Digester();
+    dig.setValidating(false);
+
+    dig.addObjectCreate("projects", ReportConfig.class);
+
+    dig.addObjectCreate("projects/project", ProjectConfig.class);
+    dig.addSetProperties("projects/project", "name", "name");
+    dig.addSetNext("projects/project", "addProjectConfig");
+
+    dig.addObjectCreate("projects/project/jira", SystemDataConfigJIRA.class);
+    dig.addSetNext("projects/project/jira", "addSystemDataConfig");
+    dig.addCallMethod("projects/project/jira/project-key", "addProjectKey", 1);
+    dig.addCallParam("projects/project/jira/project-key", 0);
+
+    dig.addObjectCreate("projects/project/sbs", SystemDataConfigSBS.class);
+    dig.addSetNext("projects/project/sbs", "addSystemDataConfig");
+    dig.addCallMethod("projects/project/sbs/user/space", "addUserSpace", 1);
+    dig.addCallParam("projects/project/sbs/user/space", 0);
+    dig.addCallMethod("projects/project/sbs/dev/space", "addDevSpace", 1);
+    dig.addCallParam("projects/project/sbs/dev/space", 0);
+
+    dig.addObjectCreate("projects/project/fisheye", SystemDataConfigFISHEYE.class);
+    dig.addSetNext("projects/project/fisheye", "addSystemDataConfig");
+
+    dig.addObjectCreate("projects/project/fisheye/repo", FishEyeRepositoryConfig.class);
+    dig.addSetProperties("projects/project/fisheye/repo");
+    dig.addSetNext("projects/project/fisheye/repo", "addRepository");
+
+    ReportConfig ret = (ReportConfig) dig.parse(is);
+
+    return ret;
+
+  }
+
+}

Added: labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/config/SystemDataConfig.java
===================================================================
--- labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/config/SystemDataConfig.java	                        (rev 0)
+++ labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/config/SystemDataConfig.java	2010-10-20 11:01:50 UTC (rev 35590)
@@ -0,0 +1,57 @@
+package org.jboss.community.sbs.plugin.reports.monthly.config;
+
+/**
+ * Abstract base for data obtaining/consolidation configuration for one system inside one project {@link ProjectConfig}.
+ * Subclasses must be created to hold system specific configuration (for JIRA, SBS, FishEye, ...).
+ * 
+ * @author Vlastimil Elias (velias at redhat dot com)
+ */
+public abstract class SystemDataConfig {
+
+  /**
+   * System this configuration is for.
+   */
+  private SystemId system;
+
+  /**
+   * Constructor.
+   * 
+   * @param system
+   */
+  protected SystemDataConfig(SystemId system) {
+    this.system = system;
+  }
+
+  /**
+   * @return the system
+   */
+  public SystemId getSystem() {
+    return system;
+  }
+
+  @Override
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((system == null) ? 0 : system.hashCode());
+    return result;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    SystemDataConfig other = (SystemDataConfig) obj;
+    if (system == null) {
+      if (other.system != null)
+        return false;
+    } else if (!system.equals(other.system))
+      return false;
+    return true;
+  }
+
+}

Added: labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/config/SystemDataConfigFISHEYE.java
===================================================================
--- labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/config/SystemDataConfigFISHEYE.java	                        (rev 0)
+++ labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/config/SystemDataConfigFISHEYE.java	2010-10-20 11:01:50 UTC (rev 35590)
@@ -0,0 +1,46 @@
+package org.jboss.community.sbs.plugin.reports.monthly.config;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Data obtaining/consolidation configuration for FishEye.
+ * 
+ * @author Vlastimil Elias (velias at redhat dot com)
+ */
+public class SystemDataConfigFISHEYE extends SystemDataConfig {
+
+  /**
+   * List of FE repositories to obtain data from.
+   */
+  private List<FishEyeRepositoryConfig> repositories;
+
+  /**
+   * Constructor.
+   */
+  public SystemDataConfigFISHEYE() {
+    super(SystemId.FISHEYE);
+  }
+
+  /**
+   * Gets the list of FE repositories to obtain data from.
+   * 
+   * @return the list of FE repositories to obtain data from
+   */
+  public List<FishEyeRepositoryConfig> getRepositories() {
+    return repositories;
+  }
+
+  /**
+   * Add repository configuration.
+   * 
+   * @param repo the repository configuration to add
+   */
+  public void addRepository(FishEyeRepositoryConfig repo) {
+    if (repositories == null) {
+      repositories = new ArrayList<FishEyeRepositoryConfig>();
+    }
+    repositories.add(repo);
+  }
+
+}

Added: labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/config/SystemDataConfigJIRA.java
===================================================================
--- labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/config/SystemDataConfigJIRA.java	                        (rev 0)
+++ labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/config/SystemDataConfigJIRA.java	2010-10-20 11:01:50 UTC (rev 35590)
@@ -0,0 +1,53 @@
+package org.jboss.community.sbs.plugin.reports.monthly.config;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.lang.StringUtils;
+
+/**
+ * Data obtaining/consolidation configuration for JIRA.
+ * 
+ * @author Vlastimil Elias (velias at redhat dot com)
+ */
+public class SystemDataConfigJIRA extends SystemDataConfig {
+
+  /**
+   * List of JIRA project keys to obtain data from.
+   */
+  private List<String> projectKeys;
+
+  /**
+   * Constructor.
+   */
+  public SystemDataConfigJIRA() {
+    super(SystemId.JIRA);
+  }
+
+  /**
+   * Gets the list of JIRA project keys to obtain data from.
+   * 
+   * @return the list of JIRA project keys to obtain data from
+   */
+  public List<String> getProjectKeys() {
+    return projectKeys;
+  }
+
+  /**
+   * Add project key into configuration.
+   * 
+   * @param projectKey to add
+   */
+  public void addProjectKey(String projectKey) {
+
+    projectKey = StringUtils.trimToNull(projectKey);
+    if (projectKey == null)
+      return;
+
+    if (projectKeys == null) {
+      projectKeys = new ArrayList<String>();
+    }
+    projectKeys.add(projectKey);
+  }
+
+}

Added: labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/config/SystemDataConfigSBS.java
===================================================================
--- labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/config/SystemDataConfigSBS.java	                        (rev 0)
+++ labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/config/SystemDataConfigSBS.java	2010-10-20 11:01:50 UTC (rev 35590)
@@ -0,0 +1,82 @@
+package org.jboss.community.sbs.plugin.reports.monthly.config;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.lang.StringUtils;
+
+/**
+ * Data obtaining/consolidation configuration for SBS.
+ * 
+ * @author Vlastimil Elias (velias at redhat dot com)
+ */
+public class SystemDataConfigSBS extends SystemDataConfig {
+
+  /**
+   * List of identifiers of USER spaces to obtain data from. SBS Space identifier is number.
+   */
+  private List<String> userSpaces;
+
+  /**
+   * List of identifiers of DEV spaces to obtain data from. SBS Space identifier is number.
+   */
+  private List<String> devSpaces;
+
+  /**
+   * Constructor.
+   */
+  public SystemDataConfigSBS() {
+    super(SystemId.SBS);
+  }
+
+  /**
+   * Gets the list of identifiers of USER spaces to obtain data from.
+   * 
+   * @return the list of identifiers of USER spaces to obtain data from
+   */
+  public List<String> getUserSpaces() {
+    return userSpaces;
+  }
+
+  /**
+   * Gets the list of identifiers of DEV spaces to obtain data from.
+   * 
+   * @return the list of identifiers of DEV spaces to obtain data from
+   */
+  public List<String> getDevSpaces() {
+    return devSpaces;
+  }
+
+  /**
+   * Add USER space into list of user spaces.
+   * 
+   * @param spaceId id of space to add
+   */
+  public void addUserSpace(String spaceId) {
+    spaceId = StringUtils.trimToNull(spaceId);
+    if (spaceId == null)
+      return;
+
+    if (userSpaces == null) {
+      userSpaces = new ArrayList<String>();
+    }
+    userSpaces.add(spaceId);
+  }
+
+  /**
+   * Add DEV space into list of user spaces.
+   * 
+   * @param spaceId id of space to add
+   */
+  public void addDevSpace(String spaceId) {
+    spaceId = StringUtils.trimToNull(spaceId);
+    if (spaceId == null)
+      return;
+
+    if (devSpaces == null) {
+      devSpaces = new ArrayList<String>();
+    }
+    devSpaces.add(spaceId);
+  }
+
+}

Added: labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/config/SystemId.java
===================================================================
--- labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/config/SystemId.java	                        (rev 0)
+++ labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/config/SystemId.java	2010-10-20 11:01:50 UTC (rev 35590)
@@ -0,0 +1,12 @@
+package org.jboss.community.sbs.plugin.reports.monthly.config;
+
+/**
+ * Identification of systems report data are aggregated from.
+ * 
+ * @author Vlastimil Elias (velias at redhat dot com)
+ */
+public enum SystemId {
+
+  JIRA, SBS, FISHEYE;
+
+}

Added: labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/valuesource/FISHEYEValueSource.java
===================================================================
--- labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/valuesource/FISHEYEValueSource.java	                        (rev 0)
+++ labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/valuesource/FISHEYEValueSource.java	2010-10-20 11:01:50 UTC (rev 35590)
@@ -0,0 +1,18 @@
+package org.jboss.community.sbs.plugin.reports.monthly.valuesource;
+
+import org.jboss.community.sbs.plugin.reports.monthly.config.FishEyeRepositoryConfig;
+
+/**
+ * Data source to obtain report value for one repository/path pair in FishEye.
+ * 
+ * @author Vlastimil Elias (velias at redhat dot com)
+ */
+public class FISHEYEValueSource implements ValueSource<FishEyeRepositoryConfig> {
+
+  @Override
+  public String[] getValues(FishEyeRepositoryConfig id) {
+    // TODO implement me
+    return null;
+  }
+
+}

Added: labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/valuesource/JIRAValueSource.java
===================================================================
--- labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/valuesource/JIRAValueSource.java	                        (rev 0)
+++ labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/valuesource/JIRAValueSource.java	2010-10-20 11:01:50 UTC (rev 35590)
@@ -0,0 +1,17 @@
+package org.jboss.community.sbs.plugin.reports.monthly.valuesource;
+
+
+/**
+ * Data source to obtain report value for one project in JIRA.
+ * 
+ * @author Vlastimil Elias (velias at redhat dot com)
+ */
+public class JIRAValueSource implements ValueSource<String> {
+
+  @Override
+  public String[] getValues(String projectKey) {
+    // TODO implement me
+    return null;
+  }
+
+}

Added: labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/valuesource/SBSValueKey.java
===================================================================
--- labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/valuesource/SBSValueKey.java	                        (rev 0)
+++ labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/valuesource/SBSValueKey.java	2010-10-20 11:01:50 UTC (rev 35590)
@@ -0,0 +1,97 @@
+package org.jboss.community.sbs.plugin.reports.monthly.valuesource;
+
+/**
+ * Value key used to call {@link SBSValueSource}.
+ * 
+ * @author Vlastimil Elias (velias at redhat dot com)
+ */
+public class SBSValueKey {
+
+  /**
+   * Identifier of SBS space. <code>-1</code> used when not set.
+   */
+  private long spaceId = -1;
+
+  /**
+   * Type of value we want to obtain.
+   */
+  private SBSValueType valueType;
+
+  /**
+   * Constructor with value type only. Useful on loops where <code>spaceId</code> is set by {@link #setSpaceId(long)}.
+   * 
+   * @param valueType this key is for. Can't be null.
+   */
+  public SBSValueKey(SBSValueType valueType) {
+    super();
+    if (valueType == null)
+      throw new IllegalArgumentException();
+    this.valueType = valueType;
+  }
+
+  /**
+   * 
+   * @param valueType this key is for.
+   * @param spaceId Identifier of SBS space this key is for
+   */
+  public SBSValueKey(SBSValueType valueType, long spaceId) {
+    this(valueType);
+    this.spaceId = spaceId;
+  }
+
+  /**
+   * Gets the identifier of SBS space.
+   * 
+   * @return the identifier of SBS space
+   */
+  public long getSpaceId() {
+    return spaceId;
+  }
+
+  /**
+   * Sets the identifier of SBS space.
+   * 
+   * @param spaceId the new identifier of SBS space
+   */
+  public void setSpaceId(long spaceId) {
+    this.spaceId = spaceId;
+  }
+
+  /**
+   * Gets the type of value we want to obtain.
+   * 
+   * @return the type of value we want to obtain
+   */
+  public SBSValueType getValueType() {
+    return valueType;
+  }
+
+  @Override
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + (int) (spaceId ^ (spaceId >>> 32));
+    result = prime * result + ((valueType == null) ? 0 : valueType.hashCode());
+    return result;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    SBSValueKey other = (SBSValueKey) obj;
+    if (spaceId != other.spaceId)
+      return false;
+    if (valueType == null) {
+      if (other.valueType != null)
+        return false;
+    } else if (!valueType.equals(other.valueType))
+      return false;
+    return true;
+  }
+
+}

Added: labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/valuesource/SBSValueSource.java
===================================================================
--- labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/valuesource/SBSValueSource.java	                        (rev 0)
+++ labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/valuesource/SBSValueSource.java	2010-10-20 11:01:50 UTC (rev 35590)
@@ -0,0 +1,16 @@
+package org.jboss.community.sbs.plugin.reports.monthly.valuesource;
+
+/**
+ * Data source to obtain report value for one Space from SBS.
+ * 
+ * @author Vlastimil Elias (velias at redhat dot com)
+ */
+public class SBSValueSource implements ValueSource<SBSValueKey> {
+
+  @Override
+  public String[] getValues(SBSValueKey id) {
+    // TODO LIBOR implement SBSDataSource, return single value array!
+    return null;
+  }
+
+}

Added: labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/valuesource/SBSValueType.java
===================================================================
--- labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/valuesource/SBSValueType.java	                        (rev 0)
+++ labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/valuesource/SBSValueType.java	2010-10-20 11:01:50 UTC (rev 35590)
@@ -0,0 +1,93 @@
+package org.jboss.community.sbs.plugin.reports.monthly.valuesource;
+
+/**
+ * Value types available from {@link SBSValueSource}.
+ * <p>
+ * Postfix defines <code>RH</code> - 'Red Hat', <code>CM</code> - 'Community'.
+ * 
+ * @author Vlastimil Elias (velias at redhat dot com)
+ * @see SBSValueKey
+ */
+public enum SBSValueType {
+
+  /**
+   * Used for: New Wiki Articles (Red Hat)
+   */
+  WIKI_NEW_ARTICLE_RH,
+
+  /**
+   * Used for: New Wiki Articles (Community)
+   */
+  WIKI_NEW_ARTICLE_CM,
+
+  /**
+   * Used for: Wiki Articles Edits (Red Hat)
+   */
+  WIKI_EDIT_ARTICLE_RH,
+
+  /**
+   * Used for: Wiki Articles Edits (Community)
+   */
+  WIKI_EDIT_ARTICLE_CM,
+
+  /**
+   * Used for: Wiki Comments (Red Hat)
+   */
+  WIKI_COMMENT_RH,
+
+  /**
+   * Used for: Wiki Comments (Community)
+   */
+  WIKI_COMMENT_CM,
+
+  /**
+   * Used for: User Forum Questions (Red Hat)
+   */
+  FORUM_QUESTION_RH,
+
+  /**
+   * Used for: User Forum Questions (Community)
+   */
+  FORUM_QUESTION_CM,
+
+  /**
+   * Used for: User Forum Helpful Answers (Red Hat)
+   */
+  FORUM_ANSWER_HELPFUL_RH,
+
+  /**
+   * Used for: User Forum Helpful Answers (Community)
+   */
+  FORUM_ANSWER_HELPFUL_CM,
+
+  /**
+   * Used for: User Forum Correct Answers (Red Hat)
+   */
+  FORUM_ANSWER_CORRECT_RH,
+
+  /**
+   * Used for: User Forum Correct Answers (Community)
+   */
+  FORUM_ANSWER_CORRECT_CM,
+
+  /**
+   * Used for: Dev Forum Threads (Red Hat)
+   */
+  FORUM_THREAD_RH,
+
+  /**
+   * Used for: Dev Forum Threads (Community)
+   */
+  FORUM_THREAD_CM,
+
+  /**
+   * Used for: Dev Forum Replies (Red Hat)
+   */
+  FORUM_REPLY_RH,
+
+  /**
+   * Used for: Dev Forum Replies (Community)
+   */
+  FORUM_REPLY_CM;
+
+}

Added: labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/valuesource/ValueSource.java
===================================================================
--- labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/valuesource/ValueSource.java	                        (rev 0)
+++ labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/valuesource/ValueSource.java	2010-10-20 11:01:50 UTC (rev 35590)
@@ -0,0 +1,22 @@
+package org.jboss.community.sbs.plugin.reports.monthly.valuesource;
+
+import org.jboss.community.sbs.plugin.reports.monthly.aggregator.Aggregator;
+
+/**
+ * Interface for DataSource. Data sources are used in {@link Aggregator} instances to obtain data from underlying
+ * system.
+ * 
+ * @author Vlastimil Elias (velias at redhat dot com)
+ * @param T data type of identifier used to identify row of data in this data source.
+ */
+public interface ValueSource<T> {
+
+  /**
+   * Get values from underlying system for given config element.
+   * 
+   * @param id identifier to read data for
+   * @return values for given id
+   */
+  public String[] getValues(T id);
+
+}

Added: labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/AggregatorTestBase.java
===================================================================
--- labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/AggregatorTestBase.java	                        (rev 0)
+++ labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/AggregatorTestBase.java	2010-10-20 11:01:50 UTC (rev 35590)
@@ -0,0 +1,27 @@
+package org.jboss.community.sbs.plugin.reports.monthly.aggregator;
+
+import org.junit.Assert;
+
+/**
+ * Abstract base class for Aggregator tests with some common methods.
+ * 
+ * @author Vlastimil Elias (velias at redhat dot com)
+ */
+public abstract class AggregatorTestBase {
+
+  /**
+   * Assert all values in array are equal to expected value. {@link Assert#assertEquals(Object, Object)} used on all
+   * array items.
+   * 
+   * @param values array to check
+   * @param expected value for all items in array
+   */
+  protected void assertAllValues(String[] values, String expected) {
+    if (values == null)
+      return;
+    for (String s : values) {
+      Assert.assertEquals(expected, s);
+    }
+  }
+
+}
\ No newline at end of file

Added: labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/AggregatorUtilsTest.java
===================================================================
--- labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/AggregatorUtilsTest.java	                        (rev 0)
+++ labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/AggregatorUtilsTest.java	2010-10-20 11:01:50 UTC (rev 35590)
@@ -0,0 +1,121 @@
+package org.jboss.community.sbs.plugin.reports.monthly.aggregator;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Unit test for {@link AggregatorUtils}.
+ * 
+ * @author Vlastimil Elias (velias at redhat dot com)
+ */
+public class AggregatorUtilsTest {
+
+  @Test
+  public void stringArray2longArray() {
+
+    Assert.assertNull(AggregatorUtils.stringArray2longArray(null));
+    Assert.assertNull(AggregatorUtils.stringArray2longArray(new String[] {}));
+
+    long[] ret = AggregatorUtils.stringArray2longArray(new String[] { "1" });
+    Assert.assertEquals(1l, ret[0]);
+
+    ret = AggregatorUtils.stringArray2longArray(new String[] { "1", "4", "6", "" });
+    Assert.assertEquals(1l, ret[0]);
+    Assert.assertEquals(4l, ret[1]);
+    Assert.assertEquals(6l, ret[2]);
+    Assert.assertEquals(0l, ret[3]);
+
+    try {
+      ret = AggregatorUtils.stringArray2longArray(new String[] { "N" });
+      Assert.fail("NumberFormatException not thrown");
+    } catch (NumberFormatException e) {
+
+    }
+  }
+
+  @Test
+  public void arrayAdd() {
+
+    AggregatorUtils.arrayAdd(null, null);
+    AggregatorUtils.arrayAdd(null, new long[] { 1l });
+    AggregatorUtils.arrayAdd(new long[] {}, new long[] { 1l });
+
+    long[] ret = new long[] { 1l };
+    long[] add = new long[] { 5l };
+
+    AggregatorUtils.arrayAdd(ret, add);
+    Assert.assertEquals(6l, ret[0]);
+
+    ret = new long[] { 1, 4, 7 };
+    add = new long[] { 5, 6, 2, 5 };
+
+    AggregatorUtils.arrayAdd(ret, add);
+    Assert.assertEquals(6l, ret[0]);
+    Assert.assertEquals(10l, ret[1]);
+    Assert.assertEquals(9l, ret[2]);
+
+  }
+
+  @Test
+  public void longArray2stringArray() {
+    Assert.assertNull(AggregatorUtils.longArray2stringArray(null));
+    Assert.assertNull(AggregatorUtils.longArray2stringArray(new long[] {}));
+
+    String[] ret = AggregatorUtils.longArray2stringArray(new long[] { 1l });
+    Assert.assertEquals("1", ret[0]);
+
+    ret = AggregatorUtils.longArray2stringArray(new long[] { 1, 4, 6 });
+    Assert.assertEquals("1", ret[0]);
+    Assert.assertEquals("4", ret[1]);
+    Assert.assertEquals("6", ret[2]);
+
+  }
+
+  @Test
+  public void createFilledArray_long() {
+    long[] a = AggregatorUtils.createFilledArray(4, 5l);
+    Assert.assertEquals(4, a.length);
+    Assert.assertEquals(5l, a[0]);
+    Assert.assertEquals(5l, a[1]);
+    Assert.assertEquals(5l, a[2]);
+    Assert.assertEquals(5l, a[3]);
+  }
+
+  @Test
+  public void createFilledArray_String() {
+    String[] a = AggregatorUtils.createFilledArray(4, "h");
+    Assert.assertEquals(4, a.length);
+    Assert.assertEquals("h", a[0]);
+    Assert.assertEquals("h", a[1]);
+    Assert.assertEquals("h", a[2]);
+    Assert.assertEquals("h", a[3]);
+  }
+
+  @Test
+  public void getLongValueFromFirstItem() {
+    Assert.assertEquals(0, AggregatorUtils.getLongValueFromFirstItem(null));
+    Assert.assertEquals(0, AggregatorUtils.getLongValueFromFirstItem(new String[] {}));
+    Assert.assertEquals(245l, AggregatorUtils.getLongValueFromFirstItem(new String[] { "245" }));
+    Assert.assertEquals(245l, AggregatorUtils.getLongValueFromFirstItem(new String[] { "245", "345" }));
+  }
+
+  @Test
+  public void isEmptyList() {
+    Assert.assertTrue(AggregatorUtils.isEmptyList(null));
+
+    List<String> l = new ArrayList<String>();
+    Assert.assertTrue(AggregatorUtils.isEmptyList(l));
+
+    l.add("a");
+    Assert.assertFalse(AggregatorUtils.isEmptyList(l));
+
+    l.add("b");
+    l.add("c");
+    Assert.assertFalse(AggregatorUtils.isEmptyList(l));
+
+  }
+
+}

Added: labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/FISHEYEAggregatorTest.java
===================================================================
--- labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/FISHEYEAggregatorTest.java	                        (rev 0)
+++ labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/FISHEYEAggregatorTest.java	2010-10-20 11:01:50 UTC (rev 35590)
@@ -0,0 +1,75 @@
+package org.jboss.community.sbs.plugin.reports.monthly.aggregator;
+
+import org.jboss.community.sbs.plugin.reports.monthly.config.FishEyeRepositoryConfig;
+import org.jboss.community.sbs.plugin.reports.monthly.config.SystemDataConfigFISHEYE;
+import org.jboss.community.sbs.plugin.reports.monthly.valuesource.ValueSource;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Unit test for {@link FISHEYEAggregator}.
+ * 
+ * @author Vlastimil Elias (velias at redhat dot com)
+ */
+public class FISHEYEAggregatorTest extends AggregatorTestBase {
+
+  /**
+   * Number of columns returned by FE aggregator. If you change this, review {@link #valueSourceMock} and whole tests to
+   * test correctly all values!!
+   */
+  public static final int COL_COUNT = 2;
+
+  @Test
+  public void getHeaderValues() {
+    FISHEYEAggregator tested = new FISHEYEAggregator(valueSourceMock);
+
+    String[] val = tested.getHeaderValues();
+    Assert.assertEquals(COL_COUNT, val.length);
+  }
+
+  @Test
+  public void getReportValues() {
+
+    FISHEYEAggregator tested = new FISHEYEAggregator(valueSourceMock);
+
+    String[] val = tested.getReportValues(null);
+    Assert.assertEquals(COL_COUNT, val.length);
+    assertAllValues(val, Aggregator.VALUE_NOT_AVAILABLE);
+
+    SystemDataConfigFISHEYE config = new SystemDataConfigFISHEYE();
+    val = tested.getReportValues(config);
+    Assert.assertEquals(COL_COUNT, val.length);
+    assertAllValues(val, Aggregator.VALUE_NOT_AVAILABLE);
+
+    config.addRepository(new FishEyeRepositoryConfig("P1"));
+    val = tested.getReportValues(config);
+    Assert.assertEquals(COL_COUNT, val.length);
+    Assert.assertEquals("1", val[0]);
+    Assert.assertEquals("2", val[1]);
+
+    config.addRepository(new FishEyeRepositoryConfig("P2"));
+    val = tested.getReportValues(config);
+    Assert.assertEquals(COL_COUNT, val.length);
+    Assert.assertEquals("11", val[0]);
+    Assert.assertEquals("22", val[1]);
+
+  }
+
+  /**
+   * Mock implementation of value source.
+   */
+  ValueSource<FishEyeRepositoryConfig> valueSourceMock = new ValueSource<FishEyeRepositoryConfig>() {
+
+    @Override
+    public String[] getValues(FishEyeRepositoryConfig id) {
+      if ("P1".equals(id.getName()))
+        return new String[] { "1", "2", "3", "4" };
+      else if ("P2".equals(id.getName()))
+        return new String[] { "10", "20", "30", "40" };
+
+      return new String[] { "100", "200", "300", "400" };
+    }
+
+  };
+
+}

Added: labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/JIRAAggregatorTest.java
===================================================================
--- labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/JIRAAggregatorTest.java	                        (rev 0)
+++ labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/JIRAAggregatorTest.java	2010-10-20 11:01:50 UTC (rev 35590)
@@ -0,0 +1,78 @@
+package org.jboss.community.sbs.plugin.reports.monthly.aggregator;
+
+import org.jboss.community.sbs.plugin.reports.monthly.config.SystemDataConfigJIRA;
+import org.jboss.community.sbs.plugin.reports.monthly.valuesource.ValueSource;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Unit test for {@link JIRAAggregator}.
+ * 
+ * @author Vlastimil Elias (velias at redhat dot com)
+ */
+public class JIRAAggregatorTest extends AggregatorTestBase {
+
+  /**
+   * Number of columns returned by JIRA aggregator. If you change this, review {@link #valueSourceMock} and whole tests
+   * to test correctly all values!!
+   */
+  public static final int COL_COUNT = 4;
+
+  @Test
+  public void getHeaderValues() {
+    JIRAAggregator tested = new JIRAAggregator(valueSourceMock);
+
+    String[] val = tested.getHeaderValues();
+    Assert.assertEquals(COL_COUNT, val.length);
+  }
+
+  @Test
+  public void getReportValues() {
+
+    JIRAAggregator tested = new JIRAAggregator(valueSourceMock);
+
+    String[] val = tested.getReportValues(null);
+    Assert.assertEquals(COL_COUNT, val.length);
+    assertAllValues(val, Aggregator.VALUE_NOT_AVAILABLE);
+
+    SystemDataConfigJIRA config = new SystemDataConfigJIRA();
+    val = tested.getReportValues(config);
+    Assert.assertEquals(COL_COUNT, val.length);
+    assertAllValues(val, Aggregator.VALUE_NOT_AVAILABLE);
+
+    config.addProjectKey("P1");
+    val = tested.getReportValues(config);
+    Assert.assertEquals(COL_COUNT, val.length);
+    Assert.assertEquals("1", val[0]);
+    Assert.assertEquals("2", val[1]);
+    Assert.assertEquals("3", val[2]);
+    Assert.assertEquals("4", val[3]);
+
+    config.addProjectKey("P2");
+    val = tested.getReportValues(config);
+    Assert.assertEquals(COL_COUNT, val.length);
+    Assert.assertEquals("11", val[0]);
+    Assert.assertEquals("22", val[1]);
+    Assert.assertEquals("33", val[2]);
+    Assert.assertEquals("44", val[3]);
+
+  }
+
+  /**
+   * Mock implementation of value source.
+   */
+  ValueSource<String> valueSourceMock = new ValueSource<String>() {
+
+    @Override
+    public String[] getValues(String id) {
+      if ("P1".equals(id))
+        return new String[] { "1", "2", "3", "4" };
+      else if ("P2".equals(id))
+        return new String[] { "10", "20", "30", "40" };
+
+      return new String[] { "100", "200", "300", "400" };
+    }
+
+  };
+
+}

Added: labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/SBSAggregatorTest.java
===================================================================
--- labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/SBSAggregatorTest.java	                        (rev 0)
+++ labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/community/sbs/plugin/reports/monthly/aggregator/SBSAggregatorTest.java	2010-10-20 11:01:50 UTC (rev 35590)
@@ -0,0 +1,239 @@
+package org.jboss.community.sbs.plugin.reports.monthly.aggregator;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jboss.community.sbs.plugin.reports.monthly.config.SystemDataConfigSBS;
+import org.jboss.community.sbs.plugin.reports.monthly.valuesource.SBSValueKey;
+import org.jboss.community.sbs.plugin.reports.monthly.valuesource.SBSValueType;
+import org.jboss.community.sbs.plugin.reports.monthly.valuesource.ValueSource;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Unit test for {@link SBSAggregator}.
+ * 
+ * @author Vlastimil Elias (velias at redhat dot com)
+ */
+public class SBSAggregatorTest extends AggregatorTestBase {
+  /**
+   * Number of columns returned by SBS aggregator. If you change this, review {@link #valueSourceMock} and whole tests
+   * to test correctly all values!!
+   */
+  public static final int COL_COUNT = 16;
+
+  @Test
+  public void getHeaderValues() {
+    SBSAggregator tested = new SBSAggregator(valueSourceMock);
+
+    String[] val = tested.getHeaderValues();
+    Assert.assertEquals(COL_COUNT, val.length);
+  }
+
+  @Test
+  public void getReportValues() {
+
+    SBSAggregator tested = new SBSAggregator(valueSourceMock);
+
+    // no spaces tests
+    String[] val = tested.getReportValues(null);
+    Assert.assertEquals(COL_COUNT, val.length);
+    assertAllValues(val, Aggregator.VALUE_NOT_AVAILABLE);
+
+    SystemDataConfigSBS config = new SystemDataConfigSBS();
+    val = tested.getReportValues(config);
+    Assert.assertEquals(COL_COUNT, val.length);
+    assertAllValues(val, Aggregator.VALUE_NOT_AVAILABLE);
+
+    // dev spaces only
+    config.addDevSpace("2345");
+    val = tested.getReportValues(config);
+    Assert.assertEquals(COL_COUNT, val.length);
+    assertReportValues(val, config.getDevSpaces(), config.getUserSpaces());
+
+    config.addDevSpace("4444");
+    config.addDevSpace("4445");
+    val = tested.getReportValues(config);
+    Assert.assertEquals(COL_COUNT, val.length);
+    assertReportValues(val, config.getDevSpaces(), config.getUserSpaces());
+
+    // user spaces only
+    config = new SystemDataConfigSBS();
+    config.addUserSpace("2345");
+    val = tested.getReportValues(config);
+    Assert.assertEquals(COL_COUNT, val.length);
+    assertReportValues(val, config.getDevSpaces(), config.getUserSpaces());
+
+    config.addUserSpace("4444");
+    config.addUserSpace("4445");
+    val = tested.getReportValues(config);
+    Assert.assertEquals(COL_COUNT, val.length);
+    assertReportValues(val, config.getDevSpaces(), config.getUserSpaces());
+
+    // both spaces tests
+    config.addDevSpace("2345");
+    val = tested.getReportValues(config);
+    Assert.assertEquals(COL_COUNT, val.length);
+    assertReportValues(val, config.getDevSpaces(), config.getUserSpaces());
+
+    config.addDevSpace("2346");
+    config.addDevSpace("2347");
+    val = tested.getReportValues(config);
+    Assert.assertEquals(COL_COUNT, val.length);
+    assertReportValues(val, config.getDevSpaces(), config.getUserSpaces());
+
+  }
+
+  @Test
+  public void getReportValue_1() {
+
+    SBSAggregator tested = new SBSAggregator(valueSourceMock);
+
+    SBSValueType testedType = SBSValueType.FORUM_ANSWER_CORRECT_CM;
+
+    String val = tested.getReportValue(testedType, null);
+    Assert.assertEquals(Aggregator.VALUE_NOT_AVAILABLE, val);
+
+    List<String> spaces = new ArrayList<String>();
+    val = tested.getReportValue(testedType, spaces);
+    Assert.assertEquals(Aggregator.VALUE_NOT_AVAILABLE, val);
+
+    spaces.add("1111");
+    val = tested.getReportValue(testedType, spaces);
+    Assert.assertEquals(expectedValue(testedType, spaces), val);
+
+    spaces.add("1112");
+    spaces.add("1113");
+    val = tested.getReportValue(testedType, spaces);
+    Assert.assertEquals(expectedValue(testedType, spaces), val);
+
+  }
+
+  @Test
+  public void getReportValue_2() {
+
+    SBSAggregator tested = new SBSAggregator(valueSourceMock);
+
+    SBSValueType testedType = SBSValueType.FORUM_ANSWER_CORRECT_RH;
+
+    String val = tested.getReportValue(testedType, null, null);
+    Assert.assertEquals(Aggregator.VALUE_NOT_AVAILABLE, val);
+
+    List<String> spaces1 = new ArrayList<String>();
+    val = tested.getReportValue(testedType, spaces1, null);
+    Assert.assertEquals(Aggregator.VALUE_NOT_AVAILABLE, val);
+    val = tested.getReportValue(testedType, null, spaces1);
+    Assert.assertEquals(Aggregator.VALUE_NOT_AVAILABLE, val);
+
+    List<String> spaces2 = new ArrayList<String>();
+    val = tested.getReportValue(testedType, spaces1, spaces2);
+    Assert.assertEquals(Aggregator.VALUE_NOT_AVAILABLE, val);
+
+    spaces1.add("1111");
+    val = tested.getReportValue(testedType, spaces1, null);
+    Assert.assertEquals(expectedValue(testedType, spaces1), val);
+    val = tested.getReportValue(testedType, null, spaces1);
+    Assert.assertEquals(expectedValue(testedType, spaces1), val);
+    val = tested.getReportValue(testedType, spaces1, spaces2);
+    Assert.assertEquals(expectedValue(testedType, spaces1), val);
+    val = tested.getReportValue(testedType, spaces2, spaces1);
+    Assert.assertEquals(expectedValue(testedType, spaces1), val);
+
+    spaces1.add("1112");
+    spaces1.add("1113");
+    val = tested.getReportValue(testedType, spaces1, null);
+    Assert.assertEquals(expectedValue(testedType, spaces1), val);
+    val = tested.getReportValue(testedType, null, spaces1);
+    Assert.assertEquals(expectedValue(testedType, spaces1), val);
+    val = tested.getReportValue(testedType, spaces1, spaces2);
+    Assert.assertEquals(expectedValue(testedType, spaces1), val);
+    val = tested.getReportValue(testedType, spaces2, spaces1);
+    Assert.assertEquals(expectedValue(testedType, spaces1), val);
+
+    spaces2.add("2112");
+    spaces2.add("2113");
+    val = tested.getReportValue(testedType, spaces1, spaces2);
+    List<String> ret = new ArrayList<String>();
+    ret.addAll(spaces1);
+    ret.addAll(spaces2);
+    Assert.assertEquals(expectedValue(testedType, ret), val);
+  }
+
+  /**
+   * Mock implementation of value source.
+   */
+  private ValueSource<SBSValueKey> valueSourceMock = new ValueSource<SBSValueKey>() {
+
+    @Override
+    public String[] getValues(SBSValueKey id) {
+      return new String[] { "" + getMockValueForKey(id) };
+    }
+
+  };
+
+  /**
+   * Get mock report value for given key. Used in mock implementation of value source.
+   * 
+   * @param id to get value for
+   * @return report value for given key
+   */
+  protected long getMockValueForKey(SBSValueKey id) {
+    return id.hashCode();
+  }
+
+  /**
+   * Count expected report value.
+   * 
+   * @param testedType
+   * @param spaces
+   * @return expected value
+   */
+  protected String expectedValue(SBSValueType testedType, List<String> spaces) {
+    SBSValueKey key = new SBSValueKey(testedType);
+    if (AggregatorUtils.isEmptyList(spaces)) {
+      return Aggregator.VALUE_NOT_AVAILABLE;
+    }
+
+    long ret = 0;
+    for (String s : spaces) {
+      key.setSpaceId(Long.parseLong(s));
+      ret += getMockValueForKey(key);
+    }
+    return ret + "";
+  }
+
+  /**
+   * Assert report values are correct. {@link Assert#assertEquals(Object, Object)} used on all array items.
+   * 
+   * @param values report values to check
+   * @param devSpaces list of identifiers of developer Spaces used to generate report
+   * @param userSpaces list of identifiers of user Spaces used to generate report
+   */
+  protected void assertReportValues(String[] values, List<String> devSpaces, List<String> userSpaces) {
+
+    List<String> allSpaces = new ArrayList<String>();
+    if (devSpaces != null)
+      allSpaces.addAll(devSpaces);
+    if (userSpaces != null)
+      allSpaces.addAll(userSpaces);
+
+    Assert.assertEquals(expectedValue(SBSValueType.WIKI_NEW_ARTICLE_RH, allSpaces), values[0]);
+    Assert.assertEquals(expectedValue(SBSValueType.WIKI_NEW_ARTICLE_CM, allSpaces), values[1]);
+    Assert.assertEquals(expectedValue(SBSValueType.WIKI_EDIT_ARTICLE_RH, allSpaces), values[2]);
+    Assert.assertEquals(expectedValue(SBSValueType.WIKI_EDIT_ARTICLE_CM, allSpaces), values[3]);
+    Assert.assertEquals(expectedValue(SBSValueType.WIKI_COMMENT_RH, allSpaces), values[4]);
+    Assert.assertEquals(expectedValue(SBSValueType.WIKI_COMMENT_CM, allSpaces), values[5]);
+    Assert.assertEquals(expectedValue(SBSValueType.FORUM_QUESTION_RH, userSpaces), values[6]);
+    Assert.assertEquals(expectedValue(SBSValueType.FORUM_QUESTION_CM, userSpaces), values[7]);
+    Assert.assertEquals(expectedValue(SBSValueType.FORUM_ANSWER_HELPFUL_RH, userSpaces), values[8]);
+    Assert.assertEquals(expectedValue(SBSValueType.FORUM_ANSWER_CORRECT_RH, userSpaces), values[9]);
+    Assert.assertEquals(expectedValue(SBSValueType.FORUM_ANSWER_HELPFUL_CM, userSpaces), values[10]);
+    Assert.assertEquals(expectedValue(SBSValueType.FORUM_ANSWER_CORRECT_CM, userSpaces), values[11]);
+    Assert.assertEquals(expectedValue(SBSValueType.FORUM_THREAD_RH, devSpaces), values[12]);
+    Assert.assertEquals(expectedValue(SBSValueType.FORUM_THREAD_CM, devSpaces), values[13]);
+    Assert.assertEquals(expectedValue(SBSValueType.FORUM_REPLY_RH, devSpaces), values[14]);
+    Assert.assertEquals(expectedValue(SBSValueType.FORUM_REPLY_CM, devSpaces), values[15]);
+
+  }
+
+}

Added: labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/community/sbs/plugin/reports/monthly/config/ReportConfigParserTest.java
===================================================================
--- labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/community/sbs/plugin/reports/monthly/config/ReportConfigParserTest.java	                        (rev 0)
+++ labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/community/sbs/plugin/reports/monthly/config/ReportConfigParserTest.java	2010-10-20 11:01:50 UTC (rev 35590)
@@ -0,0 +1,117 @@
+package org.jboss.community.sbs.plugin.reports.monthly.config;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.jboss.community.sbs.plugin.reports.monthly.config.ReportConfig;
+import org.jboss.community.sbs.plugin.reports.monthly.config.ReportConfigParser;
+import org.jboss.community.sbs.plugin.reports.monthly.config.SystemDataConfigFISHEYE;
+import org.jboss.community.sbs.plugin.reports.monthly.config.SystemDataConfigJIRA;
+import org.jboss.community.sbs.plugin.reports.monthly.config.SystemDataConfigSBS;
+import org.jboss.community.sbs.plugin.reports.monthly.config.SystemId;
+import org.junit.Assert;
+import org.junit.Test;
+import org.xml.sax.SAXException;
+
+/**
+ * Unit test for {@link ReportConfigParser}.
+ * 
+ * @author Vlastimil Elias (velias at redhat dot com)
+ */
+public class ReportConfigParserTest {
+
+  protected ReportConfig parseConfigFile() throws IOException, SAXException {
+
+    InputStream is = getClass().getResourceAsStream("/monthly_report_config.xml");
+
+    ReportConfigParser cp = new ReportConfigParser();
+
+    return cp.parseConfigFile(is);
+
+  }
+
+  @Test
+  public void parseConfigFile_ProjectConfig() throws IOException, SAXException {
+
+    ReportConfig c = parseConfigFile();
+
+    Assert.assertEquals(2, c.getProjects().size());
+    Assert.assertEquals("Project 1", c.getProjects().get(0).getName());
+    Assert.assertEquals("Project 2", c.getProjects().get(1).getName());
+
+    Assert.assertEquals(3, c.getProjects().get(0).getSystemDataConfig().size());
+    Assert.assertEquals(3, c.getProjects().get(1).getSystemDataConfig().size());
+
+  }
+
+  @Test
+  public void parseConfigFile_JIRAConfig() throws IOException, SAXException {
+
+    ReportConfig c = parseConfigFile();
+
+    SystemDataConfigJIRA jc = (SystemDataConfigJIRA) c.getProjects().get(0).getSystemDataConfigFor(SystemId.JIRA);
+    Assert.assertNotNull(jc);
+    Assert.assertEquals(2, jc.getProjectKeys().size());
+    Assert.assertEquals("PR_1_1", jc.getProjectKeys().get(0));
+    Assert.assertEquals("PR_1_2", jc.getProjectKeys().get(1));
+
+    jc = (SystemDataConfigJIRA) c.getProjects().get(1).getSystemDataConfigFor(SystemId.JIRA);
+    Assert.assertNotNull(jc);
+    Assert.assertEquals(2, jc.getProjectKeys().size());
+    Assert.assertEquals("PR_2_1", jc.getProjectKeys().get(0));
+    Assert.assertEquals("PR_2_2", jc.getProjectKeys().get(1));
+
+  }
+
+  @Test
+  public void parseConfigFile_SBSConfig() throws IOException, SAXException {
+
+    ReportConfig c = parseConfigFile();
+
+    SystemDataConfigSBS jc = (SystemDataConfigSBS) c.getProjects().get(0).getSystemDataConfigFor(SystemId.SBS);
+    Assert.assertNotNull(jc);
+    Assert.assertEquals(2, jc.getUserSpaces().size());
+    Assert.assertEquals("SP_USR_1_1", jc.getUserSpaces().get(0));
+    Assert.assertEquals("SP_USR_1_2", jc.getUserSpaces().get(1));
+
+    Assert.assertEquals(2, jc.getDevSpaces().size());
+    Assert.assertEquals("SP_DEV_1_1", jc.getDevSpaces().get(0));
+    Assert.assertEquals("SP_DEV_1_2", jc.getDevSpaces().get(1));
+
+    jc = (SystemDataConfigSBS) c.getProjects().get(1).getSystemDataConfigFor(SystemId.SBS);
+    Assert.assertNotNull(jc);
+    Assert.assertEquals(2, jc.getUserSpaces().size());
+    Assert.assertEquals("SP_USR_2_1", jc.getUserSpaces().get(0));
+    Assert.assertEquals("SP_USR_2_2", jc.getUserSpaces().get(1));
+
+    Assert.assertEquals(2, jc.getDevSpaces().size());
+    Assert.assertEquals("SP_DEV_2_1", jc.getDevSpaces().get(0));
+    Assert.assertEquals("SP_DEV_2_2", jc.getDevSpaces().get(1));
+
+  }
+
+  @Test
+  public void parseConfigFile_FISHEYEConfig() throws IOException, SAXException {
+
+    ReportConfig c = parseConfigFile();
+
+    SystemDataConfigFISHEYE jc = (SystemDataConfigFISHEYE) c.getProjects().get(0).getSystemDataConfigFor(
+        SystemId.FISHEYE);
+    Assert.assertNotNull(jc);
+    Assert.assertEquals(2, jc.getRepositories().size());
+    Assert.assertEquals("Repo_1_1", jc.getRepositories().get(0).getName());
+    Assert.assertEquals("/path_1_1", jc.getRepositories().get(0).getPath());
+    Assert.assertEquals("Repo_1_2", jc.getRepositories().get(1).getName());
+    Assert.assertNull(jc.getRepositories().get(1).getPath());
+
+    jc = (SystemDataConfigFISHEYE) c.getProjects().get(1).getSystemDataConfigFor(SystemId.FISHEYE);
+    Assert.assertNotNull(jc);
+    Assert.assertEquals(2, jc.getRepositories().size());
+    Assert.assertEquals("Repo_2_1", jc.getRepositories().get(0).getName());
+    Assert.assertEquals("/path_2_1", jc.getRepositories().get(0).getPath());
+    Assert.assertEquals("Repo_2_2", jc.getRepositories().get(1).getName());
+    Assert.assertNull(jc.getRepositories().get(1).getPath());
+
+  }
+
+}

Added: labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/community/sbs/plugin/reports/monthly/config/SystemDataConfigTest.java
===================================================================
--- labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/community/sbs/plugin/reports/monthly/config/SystemDataConfigTest.java	                        (rev 0)
+++ labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/community/sbs/plugin/reports/monthly/config/SystemDataConfigTest.java	2010-10-20 11:01:50 UTC (rev 35590)
@@ -0,0 +1,36 @@
+package org.jboss.community.sbs.plugin.reports.monthly.config;
+
+import junit.framework.Assert;
+
+import org.jboss.community.sbs.plugin.reports.monthly.config.SystemDataConfig;
+import org.jboss.community.sbs.plugin.reports.monthly.config.SystemDataConfigFISHEYE;
+import org.jboss.community.sbs.plugin.reports.monthly.config.SystemDataConfigJIRA;
+import org.junit.Test;
+
+/**
+ * Unit test for {@link SystemDataConfig}.
+ * 
+ * @author Vlastimil Elias (velias at redhat dot com)
+ */
+public class SystemDataConfigTest {
+
+  @Test
+  public void testEquals() {
+
+    Assert.assertTrue(new SystemDataConfigFISHEYE().equals(new SystemDataConfigFISHEYE()));
+    SystemDataConfigFISHEYE i = new SystemDataConfigFISHEYE();
+    Assert.assertTrue(i.equals(i));
+
+    Assert.assertFalse(new SystemDataConfigFISHEYE().equals(new SystemDataConfigJIRA()));
+    Assert.assertFalse(new SystemDataConfigFISHEYE().equals(null));
+
+  }
+
+  @Test
+  public void tesHahCode() {
+
+    Assert.assertEquals((new SystemDataConfigFISHEYE()).hashCode(), (new SystemDataConfigFISHEYE()).hashCode());
+    Assert.assertFalse((new SystemDataConfigFISHEYE()).hashCode() == (new SystemDataConfigJIRA()).hashCode());
+  }
+
+}

Added: labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/community/sbs/plugin/reports/monthly/valuesource/SBSValueKeyTest.java
===================================================================
--- labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/community/sbs/plugin/reports/monthly/valuesource/SBSValueKeyTest.java	                        (rev 0)
+++ labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/community/sbs/plugin/reports/monthly/valuesource/SBSValueKeyTest.java	2010-10-20 11:01:50 UTC (rev 35590)
@@ -0,0 +1,79 @@
+package org.jboss.community.sbs.plugin.reports.monthly.valuesource;
+
+import org.jboss.community.sbs.plugin.reports.monthly.valuesource.SBSValueKey;
+import org.jboss.community.sbs.plugin.reports.monthly.valuesource.SBSValueType;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Unit test for {@link SBSValueKey}.
+ * 
+ * @author Vlastimil Elias (velias at redhat dot com)
+ */
+public class SBSValueKeyTest {
+
+  @Test
+  public void constructor_1() {
+    SBSValueKey tested = new SBSValueKey(SBSValueType.FORUM_ANSWER_CORRECT_CM);
+
+    Assert.assertEquals(SBSValueType.FORUM_ANSWER_CORRECT_CM, tested.getValueType());
+
+    try {
+      tested = new SBSValueKey(null);
+      Assert.fail();
+    } catch (IllegalArgumentException e) {
+      // nothing to do
+    }
+
+  }
+
+  @Test
+  public void constructor_2() {
+    SBSValueKey tested = new SBSValueKey(SBSValueType.FORUM_ANSWER_CORRECT_CM, 55l);
+
+    Assert.assertEquals(SBSValueType.FORUM_ANSWER_CORRECT_CM, tested.getValueType());
+    Assert.assertEquals(55l, tested.getSpaceId());
+
+    try {
+      tested = new SBSValueKey(null, 22l);
+      Assert.fail();
+    } catch (IllegalArgumentException e) {
+      // nothing to do
+    }
+  }
+
+  @Test
+  public void setSpaceId() {
+    SBSValueKey tested = new SBSValueKey(SBSValueType.FORUM_ANSWER_CORRECT_CM, 55l);
+
+    Assert.assertEquals(55l, tested.getSpaceId());
+
+    tested.setSpaceId(22l);
+    Assert.assertEquals(22l, tested.getSpaceId());
+  }
+
+  @Test
+  public void testHashCode() {
+    SBSValueKey tested1 = new SBSValueKey(SBSValueType.FORUM_ANSWER_CORRECT_CM, 55l);
+    SBSValueKey tested2 = new SBSValueKey(SBSValueType.FORUM_ANSWER_CORRECT_CM, 55l);
+
+    Assert.assertEquals(tested1.hashCode(), tested2.hashCode());
+  }
+
+  @Test
+  public void testEquals() {
+
+    SBSValueKey tested1 = new SBSValueKey(SBSValueType.FORUM_ANSWER_CORRECT_CM, 55l);
+    SBSValueKey tested2 = new SBSValueKey(SBSValueType.FORUM_ANSWER_CORRECT_CM, 55l);
+    SBSValueKey tested3 = new SBSValueKey(SBSValueType.FORUM_ANSWER_CORRECT_CM, 22l);
+
+    Assert.assertFalse(tested1.equals(null));
+    Assert.assertFalse(tested1.equals(""));
+    Assert.assertFalse(tested1.equals(tested3));
+
+    Assert.assertTrue(tested1.equals(tested1));
+    Assert.assertTrue(tested1.equals(tested2));
+
+  }
+
+}

Added: labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/resources/monthly_report_config.xml
===================================================================
--- labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/resources/monthly_report_config.xml	                        (rev 0)
+++ labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/resources/monthly_report_config.xml	2010-10-20 11:01:50 UTC (rev 35590)
@@ -0,0 +1,46 @@
+<projects>
+    <project name="Project 1">
+        <jira>
+            <project-key>PR_1_1</project-key>
+            <project-key>PR_1_2</project-key>
+            <project-key></project-key>
+        </jira>
+        <sbs>
+            <user>
+              <space>SP_USR_1_1</space>
+              <space>SP_USR_1_2</space>
+            </user>
+            <dev>
+              <space>SP_DEV_1_1</space>
+              <space>SP_DEV_1_2</space>
+              <space></space>
+            </dev>
+        </sbs>
+        <fisheye>
+            <repo name="Repo_1_1" path="/path_1_1" />
+            <repo name="Repo_1_2" path="" />
+        </fisheye>
+    </project>
+    <project name="Project 2">
+        <jira>
+            <project-key>PR_2_1</project-key>
+            <project-key>PR_2_2</project-key>
+        </jira>
+        <sbs>
+            <user>
+              <space>SP_USR_2_1</space>
+              <space>SP_USR_2_2</space>
+              <space></space>
+              <space></space>
+            </user>
+            <dev>
+              <space>SP_DEV_2_1</space>
+              <space>SP_DEV_2_2</space>
+            </dev>
+        </sbs>
+        <fisheye>
+            <repo name="Repo_2_1" path="/path_2_1" />
+            <repo name="Repo_2_2" />
+        </fisheye>
+    </project>
+</projects> 
\ No newline at end of file



More information about the jboss-svn-commits mailing list