← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 2636: Implemented export of yearly as well as monthly aggregate data

 

------------------------------------------------------------
revno: 2636
committer: Bob Jolliffe bobjolliffe@xxxxxxxxx
branch nick: trunk
timestamp: Wed 2011-01-19 11:57:37 +0000
message:
  Implemented export of yearly as well as monthly aggregate data
  Put count of csv rows into custom http-header
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/aggregation/AggregatedDataValueService.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/aggregation/AggregatedDataValueStore.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/aggregation/DefaultAggregatedDataValueService.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/aggregation/jdbc/JdbcAggregatedDataValueStore.java
  dhis-2/dhis-services/dhis-service-importexport/src/main/java/org/hisp/dhis/importexport/synchronous/ExportPivotViewService.java
  dhis-2/dhis-web/dhis-web-importexport/src/main/java/org/hisp/dhis/importexport/action/exp/ExportDataMartAction.java
  dhis-2/dhis-web/dhis-web-importexport/src/main/resources/struts.xml


--
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
=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/aggregation/AggregatedDataValueService.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/aggregation/AggregatedDataValueService.java	2011-01-10 07:58:36 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/aggregation/AggregatedDataValueService.java	2011-01-19 11:57:37 +0000
@@ -126,6 +126,16 @@
      */
     public StoreIterator<AggregatedDataValue> getAggregateDataValuesAtLevel(OrganisationUnit orgunit, OrganisationUnitLevel level, Collection<Period> periods);
 
+    /**
+     * Returns count of agg data values for children of an orgunit at a particular level
+     * @param orgunit the root organisationunit
+     * @param level the level to retrieve values at
+     * @param periods the periods to retrieve values for
+     * @return an iterator type object for retrieving the values
+     */
+    public int countDataValuesAtLevel( OrganisationUnit orgunit, OrganisationUnitLevel level, Collection<Period> periods );
+
+
     // ----------------------------------------------------------------------
     // AggregatedDataMapValue
     // ----------------------------------------------------------------------
@@ -201,6 +211,15 @@
      */
     public StoreIterator<AggregatedIndicatorValue> getAggregateIndicatorValuesAtLevel(OrganisationUnit orgunit, OrganisationUnitLevel level, Collection<Period> periods);
 
+    /**
+     * Returns count of agg indicator values for children of an orgunit at a particular level
+     * @param orgunit the root organisationunit
+     * @param level the level to retrieve values at
+     * @param periods the periods to retrieve values for
+     * @return an iterator type object for retrieving the values
+     */
+    public int countIndicatorValuesAtLevel( OrganisationUnit orgunit, OrganisationUnitLevel level, Collection<Period> periods );
+
     // ----------------------------------------------------------------------
     // AggregatedIndicatorMapValue
     // ----------------------------------------------------------------------

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/aggregation/AggregatedDataValueStore.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/aggregation/AggregatedDataValueStore.java	2011-01-10 07:58:36 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/aggregation/AggregatedDataValueStore.java	2011-01-19 11:57:37 +0000
@@ -92,7 +92,7 @@
      */
     int deleteAggregatedDataValues();
 
-        /**
+    /**
      * Returns values for children of an orgunit at a particular level
      * @param orgunit the root organisationunit
      * @param level the level to retrieve values at
@@ -101,6 +101,15 @@
      */
     public StoreIterator<AggregatedDataValue> getAggregatedDataValuesAtLevel(OrganisationUnit orgunit, OrganisationUnitLevel level, Collection<Period> periods);
 
+    /**
+     * Returns count of agg data values for children of an orgunit at a particular level
+     * @param orgunit the root organisationunit
+     * @param level the level to retrieve values at
+     * @param periods the periods to retrieve values for
+     * @return an iterator type object for retrieving the values
+     */
+    public int countDataValuesAtLevel( OrganisationUnit orgunit, OrganisationUnitLevel level, Collection<Period> periods );
+
     // ----------------------------------------------------------------------
     // AggregatedDataMapValue
     // ----------------------------------------------------------------------
@@ -177,6 +186,14 @@
      */
     public StoreIterator<AggregatedIndicatorValue> getAggregatedIndicatorValuesAtLevel(OrganisationUnit orgunit, OrganisationUnitLevel level, Collection<Period> periods);
 
+    /**
+     * Returns count of agg indicator values for children of an orgunit at a particular level
+     * @param orgunit the root organisationunit
+     * @param level the level to retrieve values at
+     * @param periods the periods to retrieve values for
+     * @return an iterator type object for retrieving the values
+     */
+    public int countIndicatorValuesAtLevel( OrganisationUnit orgunit, OrganisationUnitLevel level, Collection<Period> periods );
 
     // ----------------------------------------------------------------------
     // AggregatedIndicatorMapValue

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/aggregation/DefaultAggregatedDataValueService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/aggregation/DefaultAggregatedDataValueService.java	2011-01-10 07:58:36 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/aggregation/DefaultAggregatedDataValueService.java	2011-01-19 11:57:37 +0000
@@ -83,6 +83,12 @@
        return aggregatedDataValueStore.getAggregatedDataValuesAtLevel(orgunit, level, periods);
     }
 
+    @Override
+    public int countDataValuesAtLevel( OrganisationUnit orgunit, OrganisationUnitLevel level, Collection<Period> periods )
+    {
+        return aggregatedDataValueStore.countDataValuesAtLevel( orgunit, level, periods );
+    }
+
     // -------------------------------------------------------------------------
     // AggregatedDataMapValue
     // -------------------------------------------------------------------------
@@ -131,7 +137,13 @@
     {
         return aggregatedDataValueStore.getAggregatedIndicatorValuesAtLevel( orgunit, level, periods );
     }
-    // -------------------------------------------------------------------------
+
+    @Override
+    public int countIndicatorValuesAtLevel( OrganisationUnit orgunit, OrganisationUnitLevel level, Collection<Period> periods )
+    {
+        return aggregatedDataValueStore.countIndicatorValuesAtLevel( orgunit, level, periods );
+    }
+// -------------------------------------------------------------------------
     // AggregatedIndicatorMapValue
     // -------------------------------------------------------------------------
     

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/aggregation/jdbc/JdbcAggregatedDataValueStore.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/aggregation/jdbc/JdbcAggregatedDataValueStore.java	2011-01-10 07:58:36 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/aggregation/jdbc/JdbcAggregatedDataValueStore.java	2011-01-19 11:57:37 +0000
@@ -190,10 +190,50 @@
         }
         finally
         {
+            // don't close holder or we lose resultset - iterator must close
             // holder.close();
         }
     }
 
+
+    @Override
+    public int countDataValuesAtLevel( OrganisationUnit rootOrgunit, OrganisationUnitLevel level, Collection<Period> periods )
+    {
+        final StatementHolder holder = statementManager.getHolder();
+
+        try
+        {
+            int rootlevel = rootOrgunit.getLevel();
+
+            String periodids = getCommaDelimitedString( getIdentifiers(Period.class, periods));
+
+            final String sql =
+                "SELECT count(*) as rowcount " +
+                "FROM aggregateddatavalue AS adv " +
+                "INNER JOIN _orgunitstructure AS ous on adv.organisationunitid=ous.organisationunitid " +
+                "WHERE adv.level = " + level.getLevel() +
+                " AND ous.idlevel" + rootlevel + "=" + rootOrgunit.getId() +
+                " AND adv.periodid IN (" + periodids + ") ";
+
+            Statement statement = holder.getStatement();
+
+            final ResultSet resultSet = statement.executeQuery( sql );
+
+            resultSet.next();
+
+            return resultSet.getInt("rowcount");
+
+        }
+        catch ( SQLException ex )
+        {
+            throw new RuntimeException( "Failed to get aggregated data values", ex );
+        }
+        finally
+        {
+            holder.close();
+        }
+    }
+
     public int deleteAggregatedDataValues( Collection<Integer> dataElementIds, Collection<Integer> periodIds, Collection<Integer> organisationUnitIds )
     {
         final String sql =
@@ -371,10 +411,47 @@
         }
         finally
         {
+            // don't close holder or we lose resultset - iterator must close
             // holder.close();
         }
     }
 
+    @Override
+    public int countIndicatorValuesAtLevel( OrganisationUnit rootOrgunit, OrganisationUnitLevel level, Collection<Period> periods )
+    {
+        final StatementHolder holder = statementManager.getHolder();
+
+        try
+        {
+            int rootlevel = rootOrgunit.getLevel();
+
+            String periodids = getCommaDelimitedString( getIdentifiers(Period.class, periods));
+
+            final String sql =
+                "SELECT count(*) as rowcount " +
+                "FROM aggregatedindicatorvalue AS aiv " +
+                "INNER JOIN _orgunitstructure AS ous on aiv.organisationunitid=ous.organisationunitid " +
+                "WHERE aiv.level = " + level.getLevel() +
+                " AND ous.idlevel" + rootlevel + "=" + rootOrgunit.getId() +
+                " AND aiv.periodid IN (" + periodids + ") ";
+
+            Statement statement = holder.getStatement();
+
+            final ResultSet resultSet = statement.executeQuery( sql );
+
+            resultSet.next();
+
+            return resultSet.getInt( "rowcount");
+        }
+        catch ( SQLException ex )
+        {
+            throw new RuntimeException( "Failed to get aggregated indicator values", ex );
+        }
+        finally
+        {
+            holder.close();
+        }
+    }
 
     // -------------------------------------------------------------------------
     // AggregatedIndicatorMapValue

=== modified file 'dhis-2/dhis-services/dhis-service-importexport/src/main/java/org/hisp/dhis/importexport/synchronous/ExportPivotViewService.java'
--- dhis-2/dhis-services/dhis-service-importexport/src/main/java/org/hisp/dhis/importexport/synchronous/ExportPivotViewService.java	2011-01-13 15:38:43 +0000
+++ dhis-2/dhis-services/dhis-service-importexport/src/main/java/org/hisp/dhis/importexport/synchronous/ExportPivotViewService.java	2011-01-19 11:57:37 +0000
@@ -47,6 +47,8 @@
 import org.hisp.dhis.period.MonthlyPeriodType;
 import org.hisp.dhis.period.Period;
 import org.hisp.dhis.period.PeriodService;
+import org.hisp.dhis.period.PeriodType;
+import org.hisp.dhis.period.YearlyPeriodType;
 import org.hisp.dhis.system.util.MathUtils;
 
 /**
@@ -56,12 +58,24 @@
  *
  * @author bobj
  */
-public class ExportPivotViewService {
+public class ExportPivotViewService
+{
 
     private static final Log log = LogFactory.getLog( ExportPivotViewService.class );
 
     // service can export either aggregated datavalues or aggregated indicator values
-    public enum RequestType { DATAVALUE, INDICATORVALUE };
+    public enum RequestType
+    {
+
+        DATAVALUE, INDICATORVALUE
+    };
+
+    // service can export either monthly or yearly periods
+    public enum RequestPeriodType
+    {
+
+        MONTHLY, YEARLY
+    };
 
     // precision to use when formatting double values
     public static int PRECISION = 5;
@@ -69,7 +83,6 @@
     // -------------------------------------------------------------------------
     // Dependencies
     // -------------------------------------------------------------------------
-
     private AggregatedDataValueService aggregatedDataValueService;
 
     public void setAggregatedDataValueService( AggregatedDataValueService aggregatedDataValueService )
@@ -77,7 +90,7 @@
         this.aggregatedDataValueService = aggregatedDataValueService;
     }
 
-    private  OrganisationUnitService organisationUnitService;
+    private OrganisationUnitService organisationUnitService;
 
     public void setOrganisationUnitService( OrganisationUnitService organisationUnitService )
     {
@@ -91,109 +104,167 @@
         this.periodService = periodService;
     }
 
-    public void execute (OutputStream out, RequestType requestType, Date startDate, Date endDate, int level, int root)
-        throws IOException
-    {
-        Writer writer = new BufferedWriter(new OutputStreamWriter(out));
-
-        Collection<Period> periods 
-            = periodService.getIntersectingPeriodsByPeriodType( new MonthlyPeriodType(), startDate, endDate );
-
-        if (periods.isEmpty())
-        {
-            log.info( "no periods to export");
-            return;
-        }
-
-        OrganisationUnit rootOrgUnit = organisationUnitService.getOrganisationUnit( root );
-
-        if (rootOrgUnit == null)
-        {
-            log.info( "no orgunit root to export with id = " + rootOrgUnit);
-            return;
-        }
-
-        rootOrgUnit.setLevel(organisationUnitService.getLevelOfOrganisationUnit( rootOrgUnit ));
-        
-        log.info("Orgunit: " + rootOrgUnit.getName());
-        log.info("Orgunit level: " + rootOrgUnit.getLevel());
-        
-        OrganisationUnitLevel orgUnitLevel = organisationUnitService.getOrganisationUnitLevelByLevel( level );
-
-        if (orgUnitLevel == null)
-        {
-            log.info( "no level with level id = " + orgUnitLevel);
-            return;
-        }
-
-        log.info( "Exporting for " + rootOrgUnit.getName() + " at level: " + orgUnitLevel.getName());
-
-        if (requestType == RequestType.DATAVALUE)
-        {
-            processDataValues(writer, rootOrgUnit , orgUnitLevel, periods );
-        }
-       else
-        {
-            processIndicatorValues(writer, rootOrgUnit , orgUnitLevel, periods );
-        }
-
-    }
-
-     void processDataValues(Writer writer, OrganisationUnit rootOrgUnit , OrganisationUnitLevel orgUnitLevel, Collection<Period> periods )
-         throws IOException
-     {
-        StoreIterator<AggregatedDataValue> Iterator
-            = aggregatedDataValueService.getAggregateDataValuesAtLevel( rootOrgUnit , orgUnitLevel, periods );
+    public void execute( OutputStream out, RequestType requestType, RequestPeriodType requestPeriodType,
+        Date startDate, Date endDate, int level, int root )
+        throws IOException
+    {
+        Writer writer = new BufferedWriter( new OutputStreamWriter( out ) );
+
+        Collection<Period> periods = getPeriods( requestPeriodType, startDate, endDate );
+
+        if ( periods.isEmpty() )
+        {
+            log.info( "no periods to export" );
+            return;
+        }
+
+        OrganisationUnit rootOrgUnit = organisationUnitService.getOrganisationUnit( root );
+
+        if ( rootOrgUnit == null )
+        {
+            log.info( "no orgunit root to export with id = " + rootOrgUnit );
+            return;
+        }
+
+        rootOrgUnit.setLevel( organisationUnitService.getLevelOfOrganisationUnit( rootOrgUnit ) );
+
+        OrganisationUnitLevel orgUnitLevel = organisationUnitService.getOrganisationUnitLevelByLevel( level );
+
+        if ( orgUnitLevel == null )
+        {
+            log.info( "no level with level id = " + orgUnitLevel );
+            return;
+        }
+
+        log.info( "Exporting for " + rootOrgUnit.getName() + " at level: " + orgUnitLevel.getName() );
+
+        if ( requestType == RequestType.DATAVALUE )
+        {
+            processDataValues( writer, rootOrgUnit, orgUnitLevel, periods );
+        } else
+        {
+            processIndicatorValues( writer, rootOrgUnit, orgUnitLevel, periods );
+        }
+
+    }
+
+    public int count( RequestType requestType, RequestPeriodType requestPeriodType,
+        Date startDate, Date endDate, int level, int root )
+    {
+        Collection<Period> periods = getPeriods( requestPeriodType, startDate, endDate );
+
+        if ( periods.isEmpty() )
+        {
+            return 0;
+        }
+
+        OrganisationUnit rootOrgUnit = organisationUnitService.getOrganisationUnit( root );
+
+        if ( rootOrgUnit == null )
+        {
+            return 0;
+        }
+
+        rootOrgUnit.setLevel( organisationUnitService.getLevelOfOrganisationUnit( rootOrgUnit ) );
+
+        OrganisationUnitLevel orgUnitLevel = organisationUnitService.getOrganisationUnitLevelByLevel( level );
+
+        if ( orgUnitLevel == null )
+        {
+            return 0;
+        }
+
+        log.debug( "Counting for " + rootOrgUnit.getName() + " at level: " + orgUnitLevel.getName() );
+
+        if ( requestType == RequestType.DATAVALUE )
+        {
+            return aggregatedDataValueService.countDataValuesAtLevel( rootOrgUnit, orgUnitLevel, periods );
+        } 
+        else
+        {
+            return aggregatedDataValueService.countIndicatorValuesAtLevel( rootOrgUnit, orgUnitLevel, periods );
+        }
+
+
+    }
+
+    private void processDataValues( Writer writer, OrganisationUnit rootOrgUnit, OrganisationUnitLevel orgUnitLevel, Collection<Period> periods )
+        throws IOException
+    {
+        StoreIterator<AggregatedDataValue> Iterator = aggregatedDataValueService.getAggregateDataValuesAtLevel( rootOrgUnit, orgUnitLevel, periods );
 
         AggregatedDataValue adv = Iterator.next();
 
-        writer.write("# period, orgunit, dataelement, catoptcombo, value\n");
-        while (adv != null)
+        writer.write( "# period, orgunit, dataelement, catoptcombo, value\n" );
+        while ( adv != null )
         {
             // process adv ..
             int periodId = adv.getPeriodId();
-            String period = periodService.getPeriod( periodId).getIsoDate();
+            String period = periodService.getPeriod( periodId ).getIsoDate();
 
-            writer.write( "'" + period + "',");
-            writer.write( adv.getOrganisationUnitId() + ",");
-            writer.write( adv.getDataElementId() + ",");
-            writer.write( adv.getCategoryOptionComboId() + ",");
-            writer.write( adv.getValue() + "\n");
+            writer.write( "'" + period + "'," );
+            writer.write( adv.getOrganisationUnitId() + "," );
+            writer.write( adv.getDataElementId() + "," );
+            writer.write( adv.getCategoryOptionComboId() + "," );
+            writer.write( adv.getValue() + "\n" );
 
             adv = Iterator.next();
         }
 
         writer.flush();
 
-     }
-
-
-     void processIndicatorValues(Writer writer, OrganisationUnit rootOrgUnit , OrganisationUnitLevel orgUnitLevel, Collection<Period> periods )
-         throws IOException
-     {
-        StoreIterator<AggregatedIndicatorValue> Iterator
-            = aggregatedDataValueService.getAggregateIndicatorValuesAtLevel( rootOrgUnit , orgUnitLevel, periods );
+    }
+
+    void processIndicatorValues( Writer writer, OrganisationUnit rootOrgUnit, OrganisationUnitLevel orgUnitLevel, Collection<Period> periods )
+        throws IOException
+    {
+        StoreIterator<AggregatedIndicatorValue> Iterator = aggregatedDataValueService.getAggregateIndicatorValuesAtLevel( rootOrgUnit, orgUnitLevel, periods );
 
         AggregatedIndicatorValue aiv = Iterator.next();
 
-        writer.write("# period, orgunit, indicator, factor, numerator, denominator\n");
-        while (aiv != null)
+        writer.write( "# period, orgunit, indicator, factor, numerator, denominator\n" );
+        while ( aiv != null )
         {
             // process adv ..
             int periodId = aiv.getPeriodId();
-            String period = periodService.getPeriod( periodId).getIsoDate();
+            String period = periodService.getPeriod( periodId ).getIsoDate();
 
-            writer.write( "'" + period + "',");
-            writer.write( aiv.getOrganisationUnitId() + ",");
-            writer.write( aiv.getIndicatorId() + ",");
-            writer.write( MathUtils.roundToString( aiv.getFactor(), PRECISION) + ",");
-            writer.write( MathUtils.roundToString(aiv.getNumeratorValue(), PRECISION) + ",");
-            writer.write( MathUtils.roundToString(aiv.getDenominatorValue(), PRECISION) + "\n");
+            writer.write( "'" + period + "'," );
+            writer.write( aiv.getOrganisationUnitId() + "," );
+            writer.write( aiv.getIndicatorId() + "," );
+            writer.write( MathUtils.roundToString( aiv.getFactor(), PRECISION ) + "," );
+            writer.write( MathUtils.roundToString( aiv.getNumeratorValue(), PRECISION ) + "," );
+            writer.write( MathUtils.roundToString( aiv.getDenominatorValue(), PRECISION ) + "\n" );
 
             aiv = Iterator.next();
         }
 
         writer.flush();
 
-     }
+    }
+
+    private Collection<Period> getPeriods( RequestPeriodType requestPeriodType, Date startDate, Date endDate )
+    {
+        Collection<Period> periods;
+        PeriodType periodType;
+
+        switch ( requestPeriodType )
+        {
+            case MONTHLY:
+                periodType = new MonthlyPeriodType();
+                break;
+            case YEARLY:
+                periodType = new YearlyPeriodType();
+                break;
+            default:
+                // shouldn't happen - log and quietly default to monthly
+                log.warn( "Unsupported period type: " + requestPeriodType );
+                periodType = new MonthlyPeriodType();
+        }
+
+        periods = periodService.getIntersectingPeriodsByPeriodType( periodType, startDate, endDate );
+
+        return periods;
+    }
+
 }

=== modified file 'dhis-2/dhis-web/dhis-web-importexport/src/main/java/org/hisp/dhis/importexport/action/exp/ExportDataMartAction.java'
--- dhis-2/dhis-web/dhis-web-importexport/src/main/java/org/hisp/dhis/importexport/action/exp/ExportDataMartAction.java	2011-01-14 16:18:27 +0000
+++ dhis-2/dhis-web/dhis-web-importexport/src/main/java/org/hisp/dhis/importexport/action/exp/ExportDataMartAction.java	2011-01-19 11:57:37 +0000
@@ -49,6 +49,7 @@
 import org.hisp.dhis.user.CurrentUserService;
 
 import com.opensymphony.xwork2.Action;
+import org.hisp.dhis.importexport.synchronous.ExportPivotViewService.RequestPeriodType;
 
 /**
  * @author Bob Jolliffe
@@ -144,6 +145,13 @@
         this.requestType = requestType;
     }
 
+    private RequestPeriodType periodType;
+
+    public void setPeriodType( RequestPeriodType requestType )
+    {
+        this.periodType = requestType;
+    }
+
     // -------------------------------------------------------------------------
     // Action implementation
     // -------------------------------------------------------------------------
@@ -223,15 +231,22 @@
         // prepare to write output
         OutputStream out = null;
 
+        // how many rows do we expect
+        int count = exportPivotViewService.count( requestType, periodType, start, end,
+                dataSourceLevel, dataSourceRoot);
+
         response.setContentType( "application/gzip");
         response.addHeader( "Content-Disposition", "attachment; filename=\""+fileName+"\"" );
         response.addHeader( "Cache-Control", "no-cache" );
         response.addHeader( "Expires", DateUtils.getExpiredHttpDateString() );
+        // write number of rows to custom header
+        response.addHeader( "X-Number-Of-Rows", String.valueOf( count ) );
 
         try
         {
             out = new GZIPOutputStream(response.getOutputStream(), GZIPBUFFER);
-            exportPivotViewService.execute(out, requestType, start, end, dataSourceLevel, dataSourceRoot);
+            exportPivotViewService.execute(out, requestType, periodType, start, end,
+                dataSourceLevel, dataSourceRoot);
         }
         finally
         {

=== modified file 'dhis-2/dhis-web/dhis-web-importexport/src/main/resources/struts.xml'
--- dhis-2/dhis-web/dhis-web-importexport/src/main/resources/struts.xml	2011-01-13 11:20:59 +0000
+++ dhis-2/dhis-web/dhis-web-importexport/src/main/resources/struts.xml	2011-01-19 11:57:37 +0000
@@ -212,7 +212,6 @@
       <result name="success" type="velocity-xml">/dhis-web-importexport/responseSuccess.vm</result>
       <result name="input" type="velocity-xml">/dhis-web-importexport/responseInput.vm</result>
     </action>
-    
   </package>
 
   <!-- Create a new namespace to map actions for exporting datamart -->
@@ -220,16 +219,32 @@
 
       <!-- route all export value requests through same action -->
 
-      <action name="dataValues" class="org.hisp.dhis.importexport.action.exp.ExportDataMartAction">
-        <result name="success" type="outputStreamResult" />
-        <result name="client-error" type="httpheader" />
-        <param name="requestType">DATAVALUE</param>
-      </action>
-
-      <action name="indicatorValues" class="org.hisp.dhis.importexport.action.exp.ExportDataMartAction">
-        <result name="success" type="outputStreamResult" />
-        <result name="client-error" type="httpheader" />
-        <param name="requestType">INDICATORVALUE</param>
+      <action name="monthlyDataValues" class="org.hisp.dhis.importexport.action.exp.ExportDataMartAction">
+        <result name="success" type="outputStreamResult" />
+        <result name="client-error" type="httpheader" />
+        <param name="requestType">DATAVALUE</param>
+        <param name="periodType">MONTHLY</param>
+      </action>
+
+      <action name="yearlyDataValues" class="org.hisp.dhis.importexport.action.exp.ExportDataMartAction">
+        <result name="success" type="outputStreamResult" />
+        <result name="client-error" type="httpheader" />
+        <param name="requestType">DATAVALUE</param>
+        <param name="periodType">YEARLY</param>
+      </action>
+
+      <action name="monthlyIndicatorValues" class="org.hisp.dhis.importexport.action.exp.ExportDataMartAction">
+        <result name="success" type="outputStreamResult" />
+        <result name="client-error" type="httpheader" />
+        <param name="requestType">INDICATORVALUE</param>
+        <param name="periodType">MONTHLY</param>
+      </action>
+
+      <action name="yearlyIndicatorValues" class="org.hisp.dhis.importexport.action.exp.ExportDataMartAction">
+        <result name="success" type="outputStreamResult" />
+        <result name="client-error" type="httpheader" />
+        <param name="requestType">INDICATORVALUE</param>
+        <param name="periodType">YEARLY</param>
       </action>
 
   </package>