← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 7641: Implemented data set report using spring jdbc template instead of statement manager

 

------------------------------------------------------------
revno: 7641
committer: Lars Helge Overland <larshelge@xxxxxxxxx>
branch nick: dhis2
timestamp: Thu 2012-07-19 21:20:26 +0200
message:
  Implemented data set report using spring jdbc template instead of statement manager
added:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/datasetreport/DataSetReportStore.java
  dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/datasetreport/jdbc/
  dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/datasetreport/jdbc/JdbcDataSetReportStore.java
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/i18n/I18nFormat.java
  dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/datasetreport/impl/DefaultDataSetReportService.java
  dhis-2/dhis-services/dhis-service-reporting/src/main/resources/META-INF/dhis/beans.xml
  dhis-2/dhis-support/dhis-support-system/src/test/java/org/hisp/dhis/system/util/TextUtilsTest.java


--
lp:dhis2
https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk

Your team DHIS 2 developers is subscribed to branch lp:dhis2.
To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
=== added file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/datasetreport/DataSetReportStore.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/datasetreport/DataSetReportStore.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/datasetreport/DataSetReportStore.java	2012-07-19 19:20:26 +0000
@@ -0,0 +1,50 @@
+package org.hisp.dhis.datasetreport;
+
+/*
+ * Copyright (c) 2004-2012, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this
+ *   list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of the HISP project nor the names of its contributors may
+ *   be used to endorse or promote products derived from this software without
+ *   specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.util.Map;
+
+import org.hisp.dhis.dataset.DataSet;
+import org.hisp.dhis.organisationunit.OrganisationUnit;
+import org.hisp.dhis.period.Period;
+
+/**
+ * @author Lars Helge Overland
+ */
+public interface DataSetReportStore
+{
+    final String SEPARATOR = "-";
+    
+    Map<String, Double> getAggregatedValues( DataSet dataSet, Period period, OrganisationUnit unit, boolean rawData );
+
+    Map<String, Double> getAggregatedSubTotals( DataSet dataSet, Period period, OrganisationUnit unit );
+    
+    Map<String, Double> getAggregatedTotals( DataSet dataSet, Period period, OrganisationUnit unit );
+    
+    Map<String, Double> getAggregatedIndicatorValues( DataSet dataSet, Period period, OrganisationUnit unit );
+}

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/i18n/I18nFormat.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/i18n/I18nFormat.java	2012-03-07 14:05:05 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/i18n/I18nFormat.java	2012-07-19 19:20:26 +0000
@@ -45,7 +45,7 @@
  */
 public class I18nFormat
 {
-    private static final DecimalFormat FORMAT_VALUE = new DecimalFormat( "#.#;#.#" ); // Fixed for now
+    private static final DecimalFormat FORMAT_VALUE = new DecimalFormat( "#.#" ); // Fixed for now
     private static final String EMPTY = "";
     private static final String NAN = "NaN";
     private static final String INVALID_DATE="Invalid date format";

=== modified file 'dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/datasetreport/impl/DefaultDataSetReportService.java'
--- dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/datasetreport/impl/DefaultDataSetReportService.java	2012-03-05 16:37:17 +0000
+++ dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/datasetreport/impl/DefaultDataSetReportService.java	2012-07-19 19:20:26 +0000
@@ -31,18 +31,16 @@
 import static org.hisp.dhis.dataentryform.DataEntryFormService.IDENTIFIER_PATTERN;
 import static org.hisp.dhis.dataentryform.DataEntryFormService.INDICATOR_PATTERN;
 import static org.hisp.dhis.dataentryform.DataEntryFormService.INPUT_PATTERN;
+import static org.hisp.dhis.datasetreport.DataSetReportStore.SEPARATOR;
 
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.TreeMap;
 import java.util.regex.Matcher;
 
-import org.hisp.dhis.aggregation.AggregatedDataValueService;
 import org.hisp.dhis.common.Grid;
 import org.hisp.dhis.common.GridHeader;
 import org.hisp.dhis.common.comparator.IdentifiableObjectNameComparator;
@@ -55,6 +53,7 @@
 import org.hisp.dhis.dataset.Section;
 import org.hisp.dhis.dataset.comparator.SectionOrderComparator;
 import org.hisp.dhis.datasetreport.DataSetReportService;
+import org.hisp.dhis.datasetreport.DataSetReportStore;
 import org.hisp.dhis.datavalue.DataValue;
 import org.hisp.dhis.datavalue.DataValueService;
 import org.hisp.dhis.i18n.I18n;
@@ -74,7 +73,6 @@
     implements DataSetReportService
 {
     private static final String NULL_REPLACEMENT = "";
-    private static final String SEPARATOR = ":";
     private static final String DEFAULT_HEADER = "Value";
     private static final String TOTAL_HEADER = "Total";
     private static final String SPACE = " ";
@@ -89,12 +87,12 @@
     {
         this.dataValueService = dataValueService;
     }
-
-    private AggregatedDataValueService aggregatedDataValueService;
-
-    public void setAggregatedDataValueService( AggregatedDataValueService aggregatedDataValueService )
+    
+    private DataSetReportStore dataSetReportStore;
+
+    public void setDataSetReportStore( DataSetReportStore dataSetReportStore )
     {
-        this.aggregatedDataValueService = aggregatedDataValueService;
+        this.dataSetReportStore = dataSetReportStore;
     }
 
     // -------------------------------------------------------------------------
@@ -104,12 +102,12 @@
     public String getCustomDataSetReport( DataSet dataSet, OrganisationUnit unit, Period period,
         boolean selectedUnitOnly, I18nFormat format )
     {
-        Map<String, String> aggregatedDataValueMap = getAggregatedValueMap( dataSet, unit, period, selectedUnitOnly,
-            format );
-
-        Map<Integer, String> aggregatedIndicatorMap = getAggregatedIndicatorValueMap( dataSet, unit, period, format );
-
-        return prepareReportContent( dataSet.getDataEntryForm(), aggregatedDataValueMap, aggregatedIndicatorMap );
+        Map<String, Double> valueMap = dataSetReportStore.getAggregatedValues( dataSet, period, unit, selectedUnitOnly );
+        valueMap.putAll( dataSetReportStore.getAggregatedTotals( dataSet, period, unit ) );
+        
+        Map<String, Double> indicatorValueMap = dataSetReportStore.getAggregatedIndicatorValues( dataSet, period, unit );
+        
+        return prepareReportContent( dataSet.getDataEntryForm(), valueMap, indicatorValueMap, format );
     }
 
     public List<Grid> getSectionDataSetReport( DataSet dataSet, Period period, OrganisationUnit unit,
@@ -118,6 +116,10 @@
         List<Section> sections = new ArrayList<Section>( dataSet.getSections() );
         Collections.sort( sections, new SectionOrderComparator() );
 
+        Map<String, Double> valueMap = dataSetReportStore.getAggregatedValues( dataSet, period, unit, selectedUnitOnly );
+        Map<String, Double> subTotalMap = dataSetReportStore.getAggregatedSubTotals( dataSet, period, unit );
+        Map<String, Double> totalMap = dataSetReportStore.getAggregatedTotals( dataSet, period, unit );
+
         List<Grid> grids = new ArrayList<Grid>();
 
         // ---------------------------------------------------------------------
@@ -164,7 +166,7 @@
 
             List<DataElement> dataElements = new ArrayList<DataElement>( section.getDataElements() );
             FilterUtils.filter( dataElements, new AggregatableDataElementFilter() );
-
+            
             for ( DataElement dataElement : dataElements )
             {
                 grid.addRow();
@@ -182,7 +184,7 @@
                     }
                     else
                     {
-                        value = aggregatedDataValueService.getAggregatedValue( dataElement, optionCombo, period, unit );
+                        value = valueMap.get( dataElement.getId() + SEPARATOR + optionCombo.getId() );
                     }
 
                     grid.addValue( value );
@@ -192,7 +194,7 @@
                 {
                     for ( DataElementCategoryOption categoryOption : categoryCombo.getCategoryOptions() )
                     {
-                        Double value = aggregatedDataValueService.getAggregatedValue( dataElement, categoryOption, period, unit );
+                        Double value = subTotalMap.get( dataElement.getId() + SEPARATOR + categoryOption.getId() );
 
                         grid.addValue( value );
                     }
@@ -200,7 +202,7 @@
 
                 if ( categoryCombo.doTotal() && !selectedUnitOnly ) // Total
                 {
-                    Double value = aggregatedDataValueService.getAggregatedValue( dataElement, period, unit );
+                    Double value = totalMap.get( String.valueOf( dataElement.getId() ) );
 
                     grid.addValue( value );
                 }
@@ -219,6 +221,9 @@
         Collections.sort( dataElements, IdentifiableObjectNameComparator.INSTANCE );
         FilterUtils.filter( dataElements, new AggregatableDataElementFilter() );
 
+        Map<String, Double> valueMap = dataSetReportStore.getAggregatedValues( dataSet, period, unit, selectedUnitOnly );
+        Map<String, Double> indicatorValueMap = dataSetReportStore.getAggregatedIndicatorValues( dataSet, period, unit );
+        
         // ---------------------------------------------------------------------
         // Get category option combos
         // ---------------------------------------------------------------------
@@ -274,10 +279,10 @@
                 }
                 else
                 {
-                    value = aggregatedDataValueService.getAggregatedValue( dataElement, optionCombo, period, unit );
+                    value = valueMap.get( dataElement.getId() + SEPARATOR + optionCombo.getId() );
                 }
 
-                grid.addValue( value );
+                grid.addValue( format.formatValue( value ) );
 
             }
         }
@@ -294,9 +299,9 @@
 
             grid.addValue( indicator.getName() );
             
-            Double value = aggregatedDataValueService.getAggregatedValue( indicator, period, unit );
+            Double value = indicatorValueMap.get( String.valueOf( indicator.getId() ) );
             
-            grid.addValue( value );
+            grid.addValue( format.formatValue( value ) );
             
             for ( int i = 0; i < orderedOptionCombos.size() - 1; i++ )
             {
@@ -312,95 +317,6 @@
     // -------------------------------------------------------------------------
 
     /**
-     * Generates a map with aggregated data values or regular data values
-     * (depending on the selectedUnitOnly argument) mapped to a DataElemenet
-     * operand identifier.
-     * 
-     * @param dataSet the DataSet.
-     * @param unit the OrganisationUnit.
-     * @param period the Period.
-     * @param selectedUnitOnly whether to include aggregated or regular data in
-     *        the map.
-     * @param format the I18nFormat.
-     * @return a map.
-     */
-    private Map<String, String> getAggregatedValueMap( DataSet dataSet, OrganisationUnit unit, Period period,
-        boolean selectedUnitOnly, I18nFormat format )
-    {
-        Collection<DataElement> dataElements = new ArrayList<DataElement>( dataSet.getDataElements() );
-
-        FilterUtils.filter( dataElements, new AggregatableDataElementFilter() );
-
-        Map<String, String> map = new TreeMap<String, String>();
-
-        for ( DataElement dataElement : dataElements )
-        {
-            for ( DataElementCategoryOptionCombo categoryOptionCombo : dataElement.getCategoryCombo().getOptionCombos() )
-            {
-                String value;
-
-                if ( selectedUnitOnly )
-                {
-                    DataValue dataValue = dataValueService.getDataValue( unit, dataElement, period, categoryOptionCombo );
-                    value = (dataValue != null) ? dataValue.getValue() : null;
-                }
-                else
-                {
-                    Double aggregatedValue = aggregatedDataValueService.getAggregatedValue( dataElement, categoryOptionCombo, period, unit );
-
-                    value = format.formatValue( aggregatedValue );
-                }
-
-                if ( value != null )
-                {
-                    map.put( dataElement.getId() + SEPARATOR + categoryOptionCombo.getId(), value );
-                }
-            }
-            
-            Double aggregatedValue = aggregatedDataValueService.getAggregatedValue( dataElement, period, unit );
-                
-            String value = format.formatValue( aggregatedValue );
-            
-            if ( value != null )
-            {
-                map.put( String.valueOf( dataElement.getId() ), value );
-            }
-        }
-
-        return map;
-    }
-
-    /**
-     * Generates a map with aggregated indicator values mapped to an Indicator
-     * identifier.
-     * 
-     * @param dataSet the DataSet.
-     * @param unit the OrganisationUnit.
-     * @param period the Period.
-     * @param format the I18nFormat.
-     * @return a map.
-     */
-    private Map<Integer, String> getAggregatedIndicatorValueMap( DataSet dataSet, OrganisationUnit unit, Period period,
-        I18nFormat format )
-    {
-        Map<Integer, String> map = new TreeMap<Integer, String>();
-
-        for ( Indicator indicator : dataSet.getIndicators() )
-        {
-            Double aggregatedValue = aggregatedDataValueService.getAggregatedValue( indicator, period, unit );
-
-            String value = format.formatValue( aggregatedValue );
-
-            if ( value != null )
-            {
-                map.put( indicator.getId(), value );
-            }
-        }
-
-        return map;
-    }
-
-    /**
      * Puts in aggregated datavalues in the custom dataentry form and returns
      * whole report text.
      * 
@@ -409,8 +325,8 @@
      * @return data entry form HTML code populated with aggregated data in the
      *         input fields.
      */
-    private String prepareReportContent( DataEntryForm dataEntryForm, Map<String, String> dataValues,
-        Map<Integer, String> indicatorValues )
+    private String prepareReportContent( DataEntryForm dataEntryForm, Map<String, Double> dataValues,
+        Map<String, Double> indicatorValues, I18nFormat format )
     {
         StringBuffer buffer = new StringBuffer();
 
@@ -438,34 +354,28 @@
 
             if ( identifierMatcher.find() && identifierMatcher.groupCount() > 0 )
             {
-                Integer dataElementId = Integer.parseInt( identifierMatcher.group( 1 ) );
-                Integer optionComboId = Integer.parseInt( identifierMatcher.group( 2 ) );
-
-                String dataValue = dataValues.get( dataElementId + SEPARATOR + optionComboId );
-
-                dataValue = dataValue != null ? dataValue : NULL_REPLACEMENT;
-
-                inputMatcher.appendReplacement( buffer, dataValue );
+                String dataElementId = identifierMatcher.group( 1 );
+                String optionComboId = identifierMatcher.group( 2 );
+
+                Double dataValue = dataValues.get( dataElementId + SEPARATOR + optionComboId );
+
+                inputMatcher.appendReplacement( buffer, format.formatValue( dataValue ) );
             }
             else if ( dataElementTotalMatcher.find() && dataElementTotalMatcher.groupCount() > 0 )
             {
-                Integer dataElementId = Integer.parseInt( dataElementTotalMatcher.group( 1 ) );
+                String dataElementId = dataElementTotalMatcher.group( 1 );
                 
-                String dataValue = dataValues.get( String.valueOf( dataElementId ) );
-
-                dataValue = dataValue != null ? dataValue : NULL_REPLACEMENT;
-
-                inputMatcher.appendReplacement( buffer, dataValue );
+                Double dataValue = dataValues.get( dataElementId );
+
+                inputMatcher.appendReplacement( buffer, format.formatValue( dataValue ) );
             }
             else if ( indicatorMatcher.find() && indicatorMatcher.groupCount() > 0 )
             {
-                Integer indicatorId = Integer.parseInt( indicatorMatcher.group( 1 ) );
-
-                String indicatorValue = indicatorValues.get( indicatorId );
-
-                indicatorValue = indicatorValue != null ? indicatorValue : NULL_REPLACEMENT;
-
-                inputMatcher.appendReplacement( buffer, indicatorValue );
+                String indicatorId = indicatorMatcher.group( 1 );
+
+                Double indicatorValue = indicatorValues.get( indicatorId );
+
+                inputMatcher.appendReplacement( buffer, format.formatValue( indicatorValue ) );
             }
         }
 

=== added directory 'dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/datasetreport/jdbc'
=== added file 'dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/datasetreport/jdbc/JdbcDataSetReportStore.java'
--- dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/datasetreport/jdbc/JdbcDataSetReportStore.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/datasetreport/jdbc/JdbcDataSetReportStore.java	2012-07-19 19:20:26 +0000
@@ -0,0 +1,195 @@
+package org.hisp.dhis.datasetreport.jdbc;
+
+/*
+ * Copyright (c) 2004-2012, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this
+ *   list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of the HISP project nor the names of its contributors may
+ *   be used to endorse or promote products derived from this software without
+ *   specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import static org.hisp.dhis.system.util.ConversionUtils.getIdentifiers;
+import static org.hisp.dhis.system.util.TextUtils.getCommaDelimitedString;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.hisp.dhis.dataelement.DataElement;
+import org.hisp.dhis.dataelement.DataElementCategoryCombo;
+import org.hisp.dhis.dataelement.DataElementCategoryOption;
+import org.hisp.dhis.dataelement.DataElementCategoryOptionCombo;
+import org.hisp.dhis.dataset.DataSet;
+import org.hisp.dhis.dataset.Section;
+import org.hisp.dhis.datasetreport.DataSetReportStore;
+import org.hisp.dhis.indicator.Indicator;
+import org.hisp.dhis.organisationunit.OrganisationUnit;
+import org.hisp.dhis.period.Period;
+import org.hisp.dhis.system.filter.AggregatableDataElementFilter;
+import org.hisp.dhis.system.util.FilterUtils;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.support.rowset.SqlRowSet;
+
+/**
+ * @author Lars Helge Overland
+ */
+public class JdbcDataSetReportStore
+    implements DataSetReportStore
+{
+    private JdbcTemplate jdbcTemplate;
+    
+    public void setJdbcTemplate( JdbcTemplate jdbcTemplate )
+    {
+        this.jdbcTemplate = jdbcTemplate;
+    }
+
+    // -------------------------------------------------------------------------
+    // DataSetReportStore implementation
+    // -------------------------------------------------------------------------
+
+    public Map<String, Double> getAggregatedValues( DataSet dataSet, Period period, OrganisationUnit unit, boolean rawData )
+    {
+        Map<String, Double> map = new HashMap<String, Double>();
+        
+        Set<DataElement> dataElements = new HashSet<DataElement>( dataSet.getDataElements() );
+
+        FilterUtils.filter( dataElements, new AggregatableDataElementFilter() );
+
+        final String sql = rawData ?
+            "select dataelementid, categoryoptioncomboid, value " +
+            "from datavalue " +
+            "where dataelementid in (" + getCommaDelimitedString( getIdentifiers( DataElement.class, dataElements ) ) + ") " +
+            "and periodid = " + period.getId() + " " +
+            "and sourceid = " + unit.getId()
+            :
+            "select dataelementid, categoryoptioncomboid, value " +
+            "from aggregateddatavalue " +
+            "where dataelementid in (" + getCommaDelimitedString( getIdentifiers( DataElement.class, dataElements ) ) + ") " +
+            "and periodid = " + period.getId() + " " +
+            "and organisationunitid = " + unit.getId();            
+        
+        SqlRowSet rowSet = jdbcTemplate.queryForRowSet( sql );
+        
+        while ( rowSet.next() )
+        {
+            int dataElementId = rowSet.getInt( "dataelementid" );
+            int categoryOptionComboId = rowSet.getInt( "categoryoptioncomboid" );
+            Double value = rowSet.getDouble( "value" );
+            
+            map.put( dataElementId + SEPARATOR + categoryOptionComboId, value );
+        }
+        
+        return map;
+    }
+    
+    public Map<String, Double> getAggregatedSubTotals( DataSet dataSet, Period period, OrganisationUnit unit )
+    {
+        Map<String, Double> map = new HashMap<String, Double>();
+        
+        for ( Section section : dataSet.getSections() )
+        {
+            DataElementCategoryCombo categoryCombo = section.getCategoryCombo();
+            Set<DataElement> dataElements = new HashSet<DataElement>( section.getDataElements() );
+            
+            for ( DataElementCategoryOption categoryOption : categoryCombo.getCategoryOptions() )
+            {
+                final String sql = 
+                    "select dataelementid, sum(value) as total " +
+                    "from aggregateddatavalue " +
+                    "where dataelementid in (" + getCommaDelimitedString( getIdentifiers( DataElement.class, dataElements ) ) + ") " +
+                    "and categoryoptioncomboid in (" + getCommaDelimitedString( getIdentifiers( DataElementCategoryOptionCombo.class, categoryOption.getCategoryOptionCombos() ) ) + ") " +
+                    "and periodid = " + period.getId() + " " +
+                    "and organisationunitid = " + unit.getId() + " " +
+                    "group by dataelementid";
+                
+                SqlRowSet rowSet = jdbcTemplate.queryForRowSet( sql );
+                
+                while ( rowSet.next() )
+                {
+                    int dataElementId = rowSet.getInt( "dataelementid" );
+                    Double value = rowSet.getDouble( "total" );
+                    
+                    map.put( dataElementId + SEPARATOR + categoryOption.getId(), value );
+                }
+            }
+        }
+        
+        return map;
+    }
+    
+    public Map<String, Double> getAggregatedTotals( DataSet dataSet, Period period, OrganisationUnit unit )
+    {
+        Map<String, Double> map = new HashMap<String, Double>();
+        
+        Set<DataElement> dataElements = new HashSet<DataElement>( dataSet.getDataElements() );
+
+        FilterUtils.filter( dataElements, new AggregatableDataElementFilter() );
+
+        final String sql = 
+            "select dataelementid, sum(value) as total " +
+            "from aggregateddatavalue " +
+            "where dataelementid in (" + getCommaDelimitedString( getIdentifiers( DataElement.class, dataElements ) ) + ") " +
+            "and periodid = " + period.getId() + " " +
+            "and organisationunitid = " + unit.getId() + " " +
+            "group by dataelementid";
+
+        SqlRowSet rowSet = jdbcTemplate.queryForRowSet( sql );
+        
+        while ( rowSet.next() )
+        {
+            int dataElementId = rowSet.getInt( "dataelementid" );
+            Double value = rowSet.getDouble( "total" );
+            
+            map.put( String.valueOf( dataElementId ), value );
+        }
+        
+        return map;
+    }
+    
+    public Map<String, Double> getAggregatedIndicatorValues( DataSet dataSet, Period period, OrganisationUnit unit )
+    {
+        Map<String, Double> map = new HashMap<String, Double>();
+        
+        Set<Indicator> indicators = new HashSet<Indicator>( dataSet.getIndicators() );
+        
+        final String sql =
+            "select indicatorid, sum(value) as total " +
+            "from aggregatedindicatorvalue " +
+            "where indicatorid in (" + getCommaDelimitedString( getIdentifiers( Indicator.class, indicators ) ) + ") " +
+            "and periodid = " + period.getId() + " " +
+            "and organisationunitid = " + unit.getId() + " " +
+            "group by indicatorid";
+
+        SqlRowSet rowSet = jdbcTemplate.queryForRowSet( sql );
+        
+        while ( rowSet.next() )
+        {
+            int indicatorid = rowSet.getInt( "indicatorid" );
+            Double value = rowSet.getDouble( "total" );
+            
+            map.put( String.valueOf( indicatorid ), value );
+        }
+        
+        return map;
+    }
+}

=== modified file 'dhis-2/dhis-services/dhis-service-reporting/src/main/resources/META-INF/dhis/beans.xml'
--- dhis-2/dhis-services/dhis-service-reporting/src/main/resources/META-INF/dhis/beans.xml	2012-07-01 07:33:25 +0000
+++ dhis-2/dhis-services/dhis-service-reporting/src/main/resources/META-INF/dhis/beans.xml	2012-07-19 19:20:26 +0000
@@ -144,7 +144,11 @@
 
   <bean id="org.hisp.dhis.datasetreport.DataSetReportService" class="org.hisp.dhis.datasetreport.impl.DefaultDataSetReportService">
     <property name="dataValueService" ref="org.hisp.dhis.datavalue.DataValueService" />
-    <property name="aggregatedDataValueService" ref="org.hisp.dhis.aggregation.AggregatedDataValueService" />
+	<property name="dataSetReportStore" ref="org.hisp.dhis.datasetreport.DataSetReportStore" />
+  </bean>
+  
+  <bean id="org.hisp.dhis.datasetreport.DataSetReportStore" class="org.hisp.dhis.datasetreport.jdbc.JdbcDataSetReportStore">
+	<property name="jdbcTemplate" ref="jdbcTemplate" />
   </bean>
 
   <!-- Dashboard -->
@@ -354,12 +358,6 @@
         method="intercept" />
       <aop:around pointcut="execution( * org.hisp.dhis.completeness.DataSetCompletenessService.getDataSetCompleteness(..) )"
         method="intercept" />
-      <aop:around pointcut="execution( * org.hisp.dhis.datasetreport.DataSetReportService.getCustomDataSetReport(..) )"
-        method="intercept" />
-      <aop:around pointcut="execution( * org.hisp.dhis.datasetreport.DataSetReportService.getSectionDataSetReport(..) )"
-        method="intercept" />
-      <aop:around pointcut="execution( * org.hisp.dhis.datasetreport.DataSetReportService.getDefaultDataSetReport(..) )"
-        method="intercept" />
     </aop:aspect>
 
   </aop:config>

=== modified file 'dhis-2/dhis-support/dhis-support-system/src/test/java/org/hisp/dhis/system/util/TextUtilsTest.java'
--- dhis-2/dhis-support/dhis-support-system/src/test/java/org/hisp/dhis/system/util/TextUtilsTest.java	2012-02-08 16:08:43 +0000
+++ dhis-2/dhis-support/dhis-support-system/src/test/java/org/hisp/dhis/system/util/TextUtilsTest.java	2012-07-19 19:20:26 +0000
@@ -30,7 +30,7 @@
 import static junit.framework.Assert.assertEquals;
 import static org.hisp.dhis.system.util.TextUtils.subString;
 import static org.hisp.dhis.system.util.TextUtils.trimEnd;
-import static org.hisp.dhis.system.util.TextUtils.htmlLinks;
+import static org.hisp.dhis.system.util.TextUtils.*;
 
 import org.junit.Test;