← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 6551: Made the Notifier accept a task id which discriminates between tasks. Task is currently bound to ...

 

------------------------------------------------------------
revno: 6551
committer: Lars Helge Overland <larshelge@xxxxxxxxx>
branch nick: dhis2
timestamp: Thu 2012-04-12 14:39:47 +0200
message:
  Made the Notifier accept a task id which discriminates between tasks. Task is currently bound to current user + task category. Added unit tests.
removed:
  dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/notification/NotificationCategory.java
added:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/scheduling/
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/scheduling/TaskCategory.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/scheduling/TaskId.java
  dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/TaskLocalList.java
  dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/TaskLocalMap.java
  dhis-2/dhis-support/dhis-support-system/src/test/java/org/hisp/dhis/system/notification/
  dhis-2/dhis-support/dhis-support-system/src/test/java/org/hisp/dhis/system/notification/NotifierTest.java
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/datamart/DataMartEngine.java
  dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/datavalueset/DataValueSetService.java
  dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/datavalueset/DefaultDataValueSetService.java
  dhis-2/dhis-services/dhis-service-datamart-default/src/main/java/org/hisp/dhis/datamart/engine/DefaultDataMartEngine.java
  dhis-2/dhis-services/dhis-service-datamart-default/src/test/java/org/hisp/dhis/datamart/DataMartServiceMultiDimensionTest.java
  dhis-2/dhis-services/dhis-service-datamart-default/src/test/java/org/hisp/dhis/datamart/DataMartServiceOrgUnitTest.java
  dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/notification/InMemoryNotifier.java
  dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/notification/Notification.java
  dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/notification/Notifier.java
  dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/scheduling/DataMartTask.java
  dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/DataValueSetController.java
  dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/commons.js
  dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/commons/action/GetNotificationsAction.java
  dhis-2/dhis-web/dhis-web-commons/src/main/resources/META-INF/dhis/beans.xml
  dhis-2/dhis-web/dhis-web-importexport/src/main/java/org/hisp/dhis/importexport/action/GetImportSummaryAction.java
  dhis-2/dhis-web/dhis-web-importexport/src/main/java/org/hisp/dhis/importexport/action/datavalue/ImportDataValueAction.java
  dhis-2/dhis-web/dhis-web-importexport/src/main/java/org/hisp/dhis/importexport/action/util/ImportDataValueTask.java
  dhis-2/dhis-web/dhis-web-reporting/src/main/java/org/hisp/dhis/reporting/datamart/action/StartExportAction.java
  dhis-2/dhis-web/dhis-web-reporting/src/main/resources/META-INF/dhis/beans.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/datamart/DataMartEngine.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/datamart/DataMartEngine.java	2012-02-12 20:32:14 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/datamart/DataMartEngine.java	2012-04-12 12:39:47 +0000
@@ -32,6 +32,7 @@
 import java.util.Set;
 
 import org.hisp.dhis.organisationunit.OrganisationUnitGroup;
+import org.hisp.dhis.scheduling.TaskId;
 
 /**
  * @author Lars Helge Overland
@@ -65,8 +66,8 @@
      * @param periodIds the period identifiers.
      * @param organisationUnitIds the organisation unit identifiers.
      * @param organisationUnitGroupIds the organisation unit group identifiers.
-     * @param processState the state object.
+     * @param id the task identifier.
      */
     void export( Collection<Integer> dataElementIds, Collection<Integer> indicatorIds,
-        Collection<Integer> periodIds, Collection<Integer> organisationUnitIds, Collection<Integer> organisationUnitGroupIds );
+        Collection<Integer> periodIds, Collection<Integer> organisationUnitIds, Collection<Integer> organisationUnitGroupIds, TaskId id );
 }

=== added directory 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/scheduling'
=== added file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/scheduling/TaskCategory.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/scheduling/TaskCategory.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/scheduling/TaskCategory.java	2012-04-12 12:39:47 +0000
@@ -0,0 +1,38 @@
+package org.hisp.dhis.scheduling;
+
+/*
+ * 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.
+ */
+
+/**
+ * @author Lars Helge Overland
+ */
+public enum TaskCategory
+{
+    DATAMART,
+    DATAVALUE_IMPORT,
+    METADATA_IMPORT
+}

=== added file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/scheduling/TaskId.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/scheduling/TaskId.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/scheduling/TaskId.java	2012-04-12 12:39:47 +0000
@@ -0,0 +1,90 @@
+package org.hisp.dhis.scheduling;
+
+/*
+ * 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 org.hisp.dhis.user.User;
+
+/**
+ * @author Lars Helge Overland
+ */
+public class TaskId
+{
+    private static final String SEPARATOR = "-";
+    
+    private String id;
+    
+    public TaskId( String id )
+    {
+        this.id = id;
+    }
+    
+    public TaskId( TaskCategory category, User user )
+    {
+        this.id = category.toString() + SEPARATOR + user.getUserCredentials().getUsername();
+    }
+    
+    public String getId()
+    {
+        return id;
+    }
+    
+    @Override
+    public int hashCode()
+    {
+        return id.hashCode();
+    }
+
+    @Override
+    public boolean equals( Object obj )
+    {
+        if ( this == obj )
+        {
+            return true;
+        }
+        
+        if ( obj == null )
+        {
+            return false;
+        }
+        
+        if ( getClass() != obj.getClass() )
+        {
+            return false;
+        }
+        
+        TaskId other = (TaskId) obj;
+        
+        return id.equals( other.id );
+    }
+
+    @Override
+    public String toString()
+    {
+        return "[" + id + "]";
+    }
+}

=== modified file 'dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/datavalueset/DataValueSetService.java'
--- dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/datavalueset/DataValueSetService.java	2012-04-11 16:18:25 +0000
+++ dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/datavalueset/DataValueSetService.java	2012-04-12 12:39:47 +0000
@@ -32,6 +32,7 @@
 
 import org.hisp.dhis.dxf2.importsummary.ImportSummary;
 import org.hisp.dhis.dxf2.metadata.ImportOptions;
+import org.hisp.dhis.scheduling.TaskId;
 
 public interface DataValueSetService
 {
@@ -39,5 +40,5 @@
     
     ImportSummary saveDataValueSet( InputStream in );
     
-    ImportSummary saveDataValueSet( InputStream in, ImportOptions importOptions );
+    ImportSummary saveDataValueSet( InputStream in, ImportOptions importOptions, TaskId taskId );
 }

=== modified file 'dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/datavalueset/DefaultDataValueSetService.java'
--- dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/datavalueset/DefaultDataValueSetService.java	2012-04-11 20:16:18 +0000
+++ dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/datavalueset/DefaultDataValueSetService.java	2012-04-12 12:39:47 +0000
@@ -32,7 +32,7 @@
 import static org.hisp.dhis.importexport.ImportStrategy.UPDATES;
 import static org.hisp.dhis.system.util.ConversionUtils.wrap;
 import static org.hisp.dhis.system.util.DateUtils.getDefaultDate;
-import static org.hisp.dhis.system.notification.NotificationCategory.DATAVALUE_IMPORT;
+import static org.hisp.dhis.scheduling.TaskCategory.DATAVALUE_IMPORT;
 import static org.hisp.dhis.system.notification.NotificationLevel.INFO;
 
 import java.io.InputStream;
@@ -64,6 +64,7 @@
 import org.hisp.dhis.period.Period;
 import org.hisp.dhis.period.PeriodService;
 import org.hisp.dhis.period.PeriodType;
+import org.hisp.dhis.scheduling.TaskId;
 import org.hisp.dhis.system.notification.Notifier;
 import org.hisp.dhis.system.util.DateUtils;
 import org.hisp.dhis.user.CurrentUserService;
@@ -148,12 +149,12 @@
     
     public ImportSummary saveDataValueSet( InputStream in )
     {
-        return saveDataValueSet( in, ImportOptions.getDefaultImportOptions() );
+        return saveDataValueSet( in, ImportOptions.getDefaultImportOptions(), null );
     }
     
-    public ImportSummary saveDataValueSet( InputStream in, ImportOptions importOptions )
+    public ImportSummary saveDataValueSet( InputStream in, ImportOptions importOptions, TaskId id )
     {
-        notifier.clear( DATAVALUE_IMPORT ).notify( DATAVALUE_IMPORT, "Process started" );
+        notifier.clear( id, DATAVALUE_IMPORT ).notify( id, DATAVALUE_IMPORT, "Process started" );
         
         ImportSummary summary = new ImportSummary();
         
@@ -175,6 +176,7 @@
         
         if ( dataSet != null && completeDate != null )
         {
+            notifier.notify( id, DATAVALUE_IMPORT, "Completing data set" );
             handleComplete( dataSet, completeDate, orgUnit, period, summary );
         }
         else
@@ -190,7 +192,7 @@
         int updateCount = 0;
         int totalCount = 0;
         
-        notifier.notify( DATAVALUE_IMPORT, "Importing data values" );
+        notifier.notify( id, DATAVALUE_IMPORT, "Importing data values" );
         
         while ( dataValueSet.hasNextDataValue() )
         {
@@ -275,7 +277,7 @@
         
         batchHandler.flush();
         
-        notifier.notify( INFO, DATAVALUE_IMPORT, "Import done", true ).addTaskSummary( DATAVALUE_IMPORT, summary );
+        notifier.notify( id, DATAVALUE_IMPORT, INFO, "Import done", true ).addTaskSummary( id, DATAVALUE_IMPORT, summary );
         
         return summary;
     }
@@ -285,9 +287,7 @@
     //--------------------------------------------------------------------------
 
     private void handleComplete( DataSet dataSet, Date completeDate, OrganisationUnit orgUnit, Period period, ImportSummary summary )
-    {
-        notifier.notify( DATAVALUE_IMPORT, "Completing data set" );
-        
+    {        
         if ( orgUnit == null )
         {
             summary.getConflicts().add( new ImportConflict( OrganisationUnit.class.getSimpleName(), ERROR_OBJECT_NEEDED_TO_COMPLETE ) );

=== modified file 'dhis-2/dhis-services/dhis-service-datamart-default/src/main/java/org/hisp/dhis/datamart/engine/DefaultDataMartEngine.java'
--- dhis-2/dhis-services/dhis-service-datamart-default/src/main/java/org/hisp/dhis/datamart/engine/DefaultDataMartEngine.java	2012-04-10 19:37:24 +0000
+++ dhis-2/dhis-services/dhis-service-datamart-default/src/main/java/org/hisp/dhis/datamart/engine/DefaultDataMartEngine.java	2012-04-12 12:39:47 +0000
@@ -29,7 +29,7 @@
 
 import static org.hisp.dhis.setting.SystemSettingManager.DEFAULT_ORGUNITGROUPSET_AGG_LEVEL;
 import static org.hisp.dhis.setting.SystemSettingManager.KEY_ORGUNITGROUPSET_AGG_LEVEL;
-import static org.hisp.dhis.system.notification.NotificationCategory.DATAMART;
+import static org.hisp.dhis.scheduling.TaskCategory.DATAMART;
 import static org.hisp.dhis.system.notification.NotificationLevel.INFO;
 
 import java.util.ArrayList;
@@ -65,6 +65,7 @@
 import org.hisp.dhis.organisationunit.OrganisationUnitService;
 import org.hisp.dhis.period.Period;
 import org.hisp.dhis.period.PeriodService;
+import org.hisp.dhis.scheduling.TaskId;
 import org.hisp.dhis.setting.SystemSettingManager;
 import org.hisp.dhis.system.filter.AggregatableDataElementFilter;
 import org.hisp.dhis.system.filter.OrganisationUnitAboveOrEqualToLevelFilter;
@@ -194,17 +195,17 @@
     public void export( Collection<Integer> dataElementIds, Collection<Integer> indicatorIds,
         Collection<Integer> periodIds, Collection<Integer> organisationUnitIds )
     {
-        export( dataElementIds, indicatorIds, periodIds, organisationUnitIds, new HashSet<Integer>() );
+        export( dataElementIds, indicatorIds, periodIds, organisationUnitIds, new HashSet<Integer>(), null );
     }
     
     @Transactional
     public void export( Collection<Integer> dataElementIds, Collection<Integer> indicatorIds,
-        Collection<Integer> periodIds, Collection<Integer> organisationUnitIds, Collection<Integer> organisationUnitGroupIds )
+        Collection<Integer> periodIds, Collection<Integer> organisationUnitIds, Collection<Integer> organisationUnitGroupIds, TaskId id )
     {
         final int cpuCores = SystemUtils.getCpuCores();
         
         Clock clock = new Clock().startClock().logTime( "Data mart export process started, number of CPU cores: " + cpuCores + ", " + SystemUtils.getMemoryString() );
-        notifier.clear( DATAMART ).notify( DATAMART, "Process started" );
+        notifier.clear( id, DATAMART ).notify( id, DATAMART, "Process started" );
 
         // ---------------------------------------------------------------------
         // Replace null with empty collection
@@ -227,7 +228,7 @@
         final Collection<DataElement> dataElements = dataElementService.getDataElements( dataElementIds );
 
         clock.logTime( "Retrieved meta-data objects" );
-        notifier.notify( DATAMART, "Filtering meta-data" );
+        notifier.notify( id, DATAMART, "Filtering meta-data" );
 
         // ---------------------------------------------------------------------
         // Filter objects
@@ -239,7 +240,7 @@
         expressionService.filterInvalidIndicators( indicators );
 
         clock.logTime( "Filtered objects" );
-        notifier.notify( DATAMART, "Loading indicators" );
+        notifier.notify( id, DATAMART, "Loading indicators" );
 
         // ---------------------------------------------------------------------
         // Explode indicator expressions
@@ -252,7 +253,7 @@
         }
 
         clock.logTime( "Exploded indicator expressions" );
-        notifier.notify( DATAMART, "Loading data elements" );
+        notifier.notify( id, DATAMART, "Loading data elements" );
 
         // ---------------------------------------------------------------------
         // Get operands
@@ -266,7 +267,7 @@
         allOperands.addAll( indicatorOperands );
 
         clock.logTime( "Retrieved operands: " + allOperands.size() );
-        notifier.notify( DATAMART, "Loading periods" );
+        notifier.notify( id, DATAMART, "Loading periods" );
 
         // ---------------------------------------------------------------------
         // Filter out future periods
@@ -275,7 +276,7 @@
         FilterUtils.filter( periods, new PastAndCurrentPeriodFilter() );
         
         clock.logTime( "Number of periods: " + periods.size() );
-        notifier.notify( DATAMART, "Filtering data elements without data" );
+        notifier.notify( id, DATAMART, "Filtering data elements without data" );
         
         // ---------------------------------------------------------------------
         // Remove operands without data
@@ -286,7 +287,7 @@
         indicatorOperands.retainAll( allOperands );
         
         clock.logTime( "Number of operands with data: " + allOperands.size() + ", " + SystemUtils.getMemoryString() );
-        notifier.notify( DATAMART, "Populating crosstabulation table" );
+        notifier.notify( id, DATAMART, "Populating crosstabulation table" );
 
         // ---------------------------------------------------------------------
         // Create crosstabtable
@@ -319,7 +320,7 @@
         crossTabService.createAggregatedDataCache( indicatorOperands, key );
         
         clock.logTime( "Created aggregated data cache, number of indicator operands: " + indicatorOperands.size() + ", operands with data: " + allOperands.size() );
-        notifier.notify( DATAMART, "Dropping database indexes" );
+        notifier.notify( id, DATAMART, "Dropping database indexes" );
         
         // ---------------------------------------------------------------------
         // 2. Drop potential indexes
@@ -328,7 +329,7 @@
         aggregatedDataValueService.dropIndex( true, isIndicators );
         
         clock.logTime( "Dropped potential indexes" );
-        notifier.notify( DATAMART, "Deleting existing data element data" );
+        notifier.notify( id, DATAMART, "Deleting existing data element data" );
         
         // ---------------------------------------------------------------------
         // 3. Delete existing aggregated datavalues
@@ -337,7 +338,7 @@
         aggregatedDataValueService.deleteAggregatedDataValues( periodIds );
         
         clock.logTime( "Deleted existing aggregated datavalues" );
-        notifier.notify( DATAMART, "Exporting data for data elements" );
+        notifier.notify( id, DATAMART, "Exporting data for data elements" );
         
         // ---------------------------------------------------------------------
         // 4. Export data element values
@@ -361,7 +362,7 @@
         }
         
         clock.logTime( "Exported values for data element operands (" + allOperands.size() + "), pages: " + organisationUnitPages.size() + ", " + SystemUtils.getMemoryString() );
-        notifier.notify( DATAMART, "Deleting existing indicator data" );
+        notifier.notify( id, DATAMART, "Deleting existing indicator data" );
         
         // ---------------------------------------------------------------------
         // 5. Delete existing aggregated indicatorvalues
@@ -370,7 +371,7 @@
         aggregatedDataValueService.deleteAggregatedIndicatorValues( periodIds );
         
         clock.logTime( "Deleted existing aggregated indicatorvalues" );
-        notifier.notify( DATAMART, "Exporting data for indicators" );
+        notifier.notify( id, DATAMART, "Exporting data for indicators" );
         
         // ---------------------------------------------------------------------
         // 6. Export indicator values
@@ -390,7 +391,7 @@
         }
         
         clock.logTime( "Exported values for indicators (" + indicators.size() + "), pages: " + organisationUnitPages.size() + ", " + SystemUtils.getMemoryString() );
-        notifier.notify( DATAMART, "Creating database indexes" );
+        notifier.notify( id, DATAMART, "Creating database indexes" );
 
         // ---------------------------------------------------------------------
         // 7. Drop aggregated data cache
@@ -422,7 +423,7 @@
             crossTabService.createAggregatedOrgUnitDataCache( indicatorOperands, key );
             
             clock.logTime( "Created aggregated org unit data cache" );
-            notifier.notify( DATAMART, "Dropping database indexes" );
+            notifier.notify( id, DATAMART, "Dropping database indexes" );
             
             // -----------------------------------------------------------------
             // 2. Drop potential indexes
@@ -431,7 +432,7 @@
             aggregatedOrgUnitDataValueService.dropIndex( true, isIndicators );
 
             clock.logTime( "Dropped potential org unit indexes" );
-            notifier.notify( DATAMART, "Deleting existing data element data" );
+            notifier.notify( id, DATAMART, "Deleting existing data element data" );
 
             // ---------------------------------------------------------------------
             // 3. Delete existing aggregated datavalues
@@ -440,7 +441,7 @@
             aggregatedOrgUnitDataValueService.deleteAggregatedDataValues( periodIds );
             
             clock.logTime( "Deleted existing aggregated org unit datavalues" );
-            notifier.notify( DATAMART, "Exporting data for data elements" );
+            notifier.notify( id, DATAMART, "Exporting data for data elements" );
 
             // ---------------------------------------------------------------------
             // 4. Export data element values
@@ -468,7 +469,7 @@
             }
             
             clock.logTime( "Exported values for data element operands (" + allOperands.size() + "), pages: " + organisationUnitPages.size()  + ", " + SystemUtils.getMemoryString() );
-            notifier.notify( DATAMART, "Deleting existing indicator data" );
+            notifier.notify( id, DATAMART, "Deleting existing indicator data" );
             
             // ---------------------------------------------------------------------
             // 5. Delete existing aggregated indicatorvalues
@@ -477,7 +478,7 @@
             aggregatedOrgUnitDataValueService.deleteAggregatedIndicatorValues( periodIds );
             
             clock.logTime( "Deleted existing aggregated org unit indicatorvalues" );
-            notifier.notify( DATAMART, "Exporting data for indicators" );
+            notifier.notify( id, DATAMART, "Exporting data for indicators" );
 
             // ---------------------------------------------------------------------
             // 6. Export indicator values
@@ -497,7 +498,7 @@
             }
             
             clock.logTime( "Exported values for indicators (" + indicators.size() + "), pages: " + organisationUnitPages.size() + ", " + SystemUtils.getMemoryString() );
-            notifier.notify( DATAMART, "Creating database indexes" );
+            notifier.notify( id, DATAMART, "Creating database indexes" );
 
             // ---------------------------------------------------------------------
             // 7. Drop aggregated data cache
@@ -525,6 +526,6 @@
         
         clock.logTime( "Dropped crosstab table" );
         clock.logTime( "Data mart export process completed" );
-        notifier.notify( INFO, DATAMART, "Data mart process completed", true );
+        notifier.notify( id, DATAMART, INFO, "Data mart process completed", true );
     }
 }

=== modified file 'dhis-2/dhis-services/dhis-service-datamart-default/src/test/java/org/hisp/dhis/datamart/DataMartServiceMultiDimensionTest.java'
--- dhis-2/dhis-services/dhis-service-datamart-default/src/test/java/org/hisp/dhis/datamart/DataMartServiceMultiDimensionTest.java	2012-02-12 20:32:14 +0000
+++ dhis-2/dhis-services/dhis-service-datamart-default/src/test/java/org/hisp/dhis/datamart/DataMartServiceMultiDimensionTest.java	2012-04-12 12:39:47 +0000
@@ -262,7 +262,7 @@
         // Test
         // ---------------------------------------------------------------------
 
-        dataMartEngine.export( dataElementIds, indicatorIds, periodIds, organisationUnitIds, null );
+        dataMartEngine.export( dataElementIds, indicatorIds, periodIds, organisationUnitIds );
         
         assertEquals( 90.0, aggregatedDataValueService.getAggregatedValue( dataElementA, categoryOptionComboA, periodA, unitB ) );
         assertEquals( 70.0, aggregatedDataValueService.getAggregatedValue( dataElementA, categoryOptionComboA, periodB, unitB ) );
@@ -316,7 +316,7 @@
         // Test
         // ---------------------------------------------------------------------
 
-        dataMartEngine.export( dataElementIds, indicatorIds, periodIds, organisationUnitIds, null );
+        dataMartEngine.export( dataElementIds, indicatorIds, periodIds, organisationUnitIds );
 
         assertEquals( 90.0, aggregatedDataValueService.getAggregatedValue( dataElementA, categoryOptionComboA, periodA, unitB ) );
         assertEquals( 70.0, aggregatedDataValueService.getAggregatedValue( dataElementA, categoryOptionComboA, periodB, unitB ) );

=== modified file 'dhis-2/dhis-services/dhis-service-datamart-default/src/test/java/org/hisp/dhis/datamart/DataMartServiceOrgUnitTest.java'
--- dhis-2/dhis-services/dhis-service-datamart-default/src/test/java/org/hisp/dhis/datamart/DataMartServiceOrgUnitTest.java	2012-02-16 09:03:48 +0000
+++ dhis-2/dhis-services/dhis-service-datamart-default/src/test/java/org/hisp/dhis/datamart/DataMartServiceOrgUnitTest.java	2012-04-12 12:39:47 +0000
@@ -302,7 +302,7 @@
         
         dataElementService.updateDataElement( dataElementA );
         
-        dataMartEngine.export( dataElementIds, indicatorIds, periodIds, organisationUnitIds, organisationUnitGroupIds );
+        dataMartEngine.export( dataElementIds, indicatorIds, periodIds, organisationUnitIds, organisationUnitGroupIds, null );
         
         assertEquals( 145.0, aggregatedOrgUnitDataValueService.getAggregatedValue( dataElementA, categoryOptionCombo, periodA, unitA, groupA ) );
         assertEquals( 145.0, aggregatedOrgUnitDataValueService.getAggregatedValue( dataElementA, categoryOptionCombo, periodA, unitB, groupA ) );
@@ -336,7 +336,7 @@
         
         dataElementService.updateDataElement( dataElementA );
 
-        dataMartEngine.export( dataElementIds, indicatorIds, periodIds, organisationUnitIds, organisationUnitGroupIds );
+        dataMartEngine.export( dataElementIds, indicatorIds, periodIds, organisationUnitIds, organisationUnitGroupIds, null );
         
         assertEquals( 145.0, aggregatedOrgUnitDataValueService.getAggregatedValue( dataElementA, categoryOptionCombo, periodA, unitA, groupA ) );
         assertEquals( 145.0, aggregatedOrgUnitDataValueService.getAggregatedValue( dataElementA, categoryOptionCombo, periodA, unitB, groupA ) );
@@ -370,7 +370,7 @@
 
         dataElementService.updateDataElement( dataElementB );
 
-        dataMartEngine.export( dataElementIds, indicatorIds, periodIds, organisationUnitIds, organisationUnitGroupIds );
+        dataMartEngine.export( dataElementIds, indicatorIds, periodIds, organisationUnitIds, organisationUnitGroupIds, null );
         
         assertEquals( 1.0, aggregatedOrgUnitDataValueService.getAggregatedValue( dataElementB, categoryOptionCombo, periodA, unitA, groupA ) );
         assertEquals( 1.0, aggregatedOrgUnitDataValueService.getAggregatedValue( dataElementB, categoryOptionCombo, periodA, unitB, groupA ) );
@@ -404,7 +404,7 @@
         
         dataElementService.updateDataElement( dataElementB );
         
-        dataMartEngine.export( dataElementIds, indicatorIds, periodIds, organisationUnitIds, organisationUnitGroupIds );
+        dataMartEngine.export( dataElementIds, indicatorIds, periodIds, organisationUnitIds, organisationUnitGroupIds, null );
         
         assertEquals( 33.3, aggregatedOrgUnitDataValueService.getAggregatedValue( dataElementB, categoryOptionCombo, periodA, unitA, groupA ) );
         assertEquals( 33.3, aggregatedOrgUnitDataValueService.getAggregatedValue( dataElementB, categoryOptionCombo, periodA, unitB, groupA ) );
@@ -512,7 +512,7 @@
         
         indicatorIds.add( indicatorService.addIndicator( indicatorA ) );
 
-        dataMartEngine.export( dataElementIds, indicatorIds, periodIds, organisationUnitIds, organisationUnitGroupIds );
+        dataMartEngine.export( dataElementIds, indicatorIds, periodIds, organisationUnitIds, organisationUnitGroupIds, null );
         
         // ---------------------------------------------------------------------
         // Assert

=== modified file 'dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/notification/InMemoryNotifier.java'
--- dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/notification/InMemoryNotifier.java	2012-04-11 14:33:18 +0000
+++ dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/notification/InMemoryNotifier.java	2012-04-12 12:39:47 +0000
@@ -29,15 +29,17 @@
 
 import java.util.ArrayList;
 import java.util.Date;
-import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Map;
 
 import javax.annotation.PostConstruct;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.hisp.dhis.scheduling.TaskCategory;
+import org.hisp.dhis.scheduling.TaskId;
+import org.hisp.dhis.system.util.TaskLocalList;
+import org.hisp.dhis.system.util.TaskLocalMap;
 
 /**
  * @author Lars Helge Overland
@@ -47,17 +49,17 @@
 {
     private static final Log log = LogFactory.getLog( InMemoryNotifier.class );
     
-    private int MAX_SIZE = 1000;
-    
-    private List<Notification> notifications;
-    
-    private Map<NotificationCategory, Object> taskSummaries;
+    private int MAX_SIZE = 500;
+    
+    private TaskLocalList<Notification> notifications;
+    
+    private TaskLocalMap<TaskCategory, Object> taskSummaries;
     
     @PostConstruct
     public void init()
     {
-        notifications = new ArrayList<Notification>();
-        taskSummaries = new HashMap<NotificationCategory, Object>();
+        notifications = new TaskLocalList<Notification>();
+        taskSummaries = new TaskLocalMap<TaskCategory, Object>();
     }
 
     // -------------------------------------------------------------------------
@@ -65,60 +67,36 @@
     // -------------------------------------------------------------------------
 
     @Override
-    public Notifier notify( NotificationCategory category, String message )
+    public Notifier notify( TaskId id, TaskCategory category, String message )
     {
-        return notify( NotificationLevel.INFO, category, message, false );
+        return notify( id, category, NotificationLevel.INFO, message, false );
     }
     
     @Override
-    public Notifier notify( NotificationLevel level, NotificationCategory category, String message, boolean completed )
+    public Notifier notify( TaskId id, TaskCategory category, NotificationLevel level, String message, boolean completed )
     {
         Notification notification = new Notification( level, category, new Date(), message, completed );
         
-        notifications.add( 0, notification );
+        notifications.get( id ).add( 0, notification );
         
-        if ( notifications.size() > MAX_SIZE )
+        if ( notifications.get( id ).size() > MAX_SIZE )
         {
-            notifications.remove( MAX_SIZE );
+            notifications.get( id ).remove( MAX_SIZE );
         }
-        
+
         log.info( notification );
         
         return this;
     }
 
     @Override
-    public List<Notification> getNotifications( NotificationCategory category, int max )
-    {
-        List<Notification> list = new ArrayList<Notification>();
-        
-        if ( category != null )
-        {
-            for ( Notification notification : notifications )
-            {
-                if ( list.size() == max )
-                {
-                    break;
-                }
-                
-                if ( category.equals( notification.getCategory() ) )
-                {
-                    list.add( notification );
-                }
-            }
-        }
-        
-        return list;
-    }
-
-    @Override
-    public List<Notification> getNotifications( NotificationCategory category, String lastUid )
-    {
-        List<Notification> list = new ArrayList<Notification>();
-        
-        if ( category != null )
-        {
-            for ( Notification notification : notifications )
+    public List<Notification> getNotifications( TaskId id, TaskCategory category, String lastUid )
+    {
+        List<Notification> list = new ArrayList<Notification>();
+        
+        if ( category != null )
+        {
+            for ( Notification notification : notifications.get( id ) )
             {
                 if ( lastUid != null && lastUid.equals( notification.getUid() ) )
                 {
@@ -136,11 +114,11 @@
     }
     
     @Override
-    public Notifier clear( NotificationCategory category )
+    public Notifier clear( TaskId id, TaskCategory category )
     {
         if ( category != null )
         {
-            Iterator<Notification> iter = notifications.iterator();
+            Iterator<Notification> iter = notifications.get( id ).iterator();
             
             while ( iter.hasNext() )
             {
@@ -151,21 +129,21 @@
             }
         }
         
-        taskSummaries.remove( category );
+        taskSummaries.get( id ).remove( category );
         
         return this;
     }
 
     @Override
-    public Notifier addTaskSummary( NotificationCategory category, Object taskSummary )
+    public Notifier addTaskSummary( TaskId id, TaskCategory category, Object taskSummary )
     {
-        taskSummaries.put( category, taskSummary );
+        taskSummaries.get( id ).put( category, taskSummary );
         return this;
     }
 
     @Override
-    public Object getTaskSummary( NotificationCategory category )
+    public Object getTaskSummary( TaskId id, TaskCategory category )
     {
-        return taskSummaries.get( category );
+        return taskSummaries.get( id ).get( category );
     }
 }

=== modified file 'dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/notification/Notification.java'
--- dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/notification/Notification.java	2012-02-14 12:53:25 +0000
+++ dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/notification/Notification.java	2012-04-12 12:39:47 +0000
@@ -30,6 +30,7 @@
 import java.util.Date;
 
 import org.hisp.dhis.common.CodeGenerator;
+import org.hisp.dhis.scheduling.TaskCategory;
 
 /**
  * @author Lars Helge Overland
@@ -40,7 +41,7 @@
     
     private NotificationLevel level;
     
-    private NotificationCategory category;
+    private TaskCategory category;
     
     private Date time;
     
@@ -57,7 +58,7 @@
         this.uid = CodeGenerator.generateCode();
     }
 
-    public Notification( NotificationLevel level, NotificationCategory category, Date time, String message, boolean completed )
+    public Notification( NotificationLevel level, TaskCategory category, Date time, String message, boolean completed )
     {
         this.uid = CodeGenerator.generateCode();
         this.level = level;
@@ -91,12 +92,12 @@
         this.level = level;
     }
 
-    public NotificationCategory getCategory()
+    public TaskCategory getCategory()
     {
         return category;
     }
 
-    public void setCategory( NotificationCategory category )
+    public void setCategory( TaskCategory category )
     {
         this.category = category;
     }

=== removed file 'dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/notification/NotificationCategory.java'
--- dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/notification/NotificationCategory.java	2012-04-11 11:33:43 +0000
+++ dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/notification/NotificationCategory.java	1970-01-01 00:00:00 +0000
@@ -1,38 +0,0 @@
-package org.hisp.dhis.system.notification;
-
-/*
- * 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.
- */
-
-/**
- * @author Lars Helge Overland
- */
-public enum NotificationCategory
-{
-    DATAMART,
-    DATAVALUE_IMPORT,
-    METADATA_IMPORT
-}

=== modified file 'dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/notification/Notifier.java'
--- dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/notification/Notifier.java	2012-04-11 11:33:43 +0000
+++ dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/notification/Notifier.java	2012-04-12 12:39:47 +0000
@@ -29,23 +29,23 @@
 
 import java.util.List;
 
+import org.hisp.dhis.scheduling.TaskCategory;
+import org.hisp.dhis.scheduling.TaskId;
+
 /**
  * @author Lars Helge Overland
  */
 public interface Notifier
 {
-    Notifier notify( NotificationCategory category, String message );
-    
-    Notifier notify( NotificationLevel level, NotificationCategory category, String message, boolean completed );
-    
-    List<Notification> getNotifications( NotificationCategory category, int max );
-    
-    List<Notification> getNotifications( NotificationCategory category, String lastUid );
-    
-    Notifier clear( NotificationCategory category );
-    
-    Notifier addTaskSummary( NotificationCategory category, Object taskSummary );
-    
-    Object getTaskSummary( NotificationCategory category );
-    
+    Notifier notify( TaskId id, TaskCategory category, String message );
+    
+    Notifier notify( TaskId id, TaskCategory category, NotificationLevel level, String message, boolean completed );
+    
+    List<Notification> getNotifications( TaskId id, TaskCategory category, String lastUid );
+    
+    Notifier clear( TaskId id, TaskCategory category );
+    
+    Notifier addTaskSummary( TaskId id, TaskCategory category, Object taskSummary );
+    
+    Object getTaskSummary( TaskId id, TaskCategory category );
 }

=== modified file 'dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/scheduling/DataMartTask.java'
--- dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/scheduling/DataMartTask.java	2012-04-06 20:02:26 +0000
+++ dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/scheduling/DataMartTask.java	2012-04-12 12:39:47 +0000
@@ -55,6 +55,7 @@
 import org.hisp.dhis.period.PeriodService;
 import org.hisp.dhis.period.RelativePeriods;
 import org.hisp.dhis.period.YearlyPeriodType;
+import org.hisp.dhis.scheduling.TaskId;
 import org.hisp.dhis.setting.SystemSettingManager;
 import org.hisp.dhis.system.util.ConversionUtils;
 import org.hisp.dhis.system.util.Filter;
@@ -85,11 +86,18 @@
     private DataSetService dataSetService;
     
     private SystemSettingManager systemSettingManager;
-
+    
     // -------------------------------------------------------------------------
     // Params
     // -------------------------------------------------------------------------
 
+    private TaskId taskId;
+
+    public void setTaskId( TaskId taskId )
+    {
+        this.taskId = taskId;
+    }
+
     private List<Period> periods;
     
     public void setPeriods( List<Period> periods )
@@ -157,7 +165,7 @@
         
         Collection<Integer> periodIds = ConversionUtils.getIdentifiers( Period.class, periodService.reloadPeriods( periods ) );
         
-        dataMartEngine.export( dataElementIds, indicatorIds, periodIds, organisationUnitIds, organisationUnitGroupIds );
+        dataMartEngine.export( dataElementIds, indicatorIds, periodIds, organisationUnitIds, organisationUnitGroupIds, taskId );
         completenessEngine.exportDataSetCompleteness( dataSetIds, periodIds, organisationUnitIds ); 
     }
 

=== added file 'dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/TaskLocalList.java'
--- dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/TaskLocalList.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/TaskLocalList.java	2012-04-12 12:39:47 +0000
@@ -0,0 +1,66 @@
+package org.hisp.dhis.system.util;
+
+/*
+ * 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.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.hisp.dhis.scheduling.TaskId;
+
+/**
+ * @author Lars Helge Overland
+ */
+public class TaskLocalList<T>
+{
+    private Map<TaskId, List<T>> internalMap;
+    
+    public TaskLocalList()
+    {
+        this.internalMap = new HashMap<TaskId, List<T>>();
+    }
+    
+    public List<T> get( TaskId id )
+    {
+        List<T> list = internalMap.get( id );
+        
+        if ( list == null )
+        {
+            list = new ArrayList<T>();
+            internalMap.put( id, list );
+        }
+        
+        return list;
+    }
+    
+    public boolean clear( TaskId id )
+    {
+        return internalMap.remove( id ) != null;
+    }
+}

=== added file 'dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/TaskLocalMap.java'
--- dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/TaskLocalMap.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/TaskLocalMap.java	2012-04-12 12:39:47 +0000
@@ -0,0 +1,64 @@
+package org.hisp.dhis.system.util;
+
+/*
+ * 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.HashMap;
+import java.util.Map;
+
+import org.hisp.dhis.scheduling.TaskId;
+
+/**
+ * @author Lars Helge Overland
+ */
+public class TaskLocalMap<T, V>
+{
+    private Map<TaskId, Map<T, V>> internalMap;
+    
+    public TaskLocalMap()
+    {
+        this.internalMap = new HashMap<TaskId, Map<T, V>>();
+    }
+
+    public Map<T, V> get( TaskId id )
+    {
+        Map<T, V> map = internalMap.get( id );
+        
+        if ( map == null )
+        {
+            map = new HashMap<T, V>();
+            internalMap.put( id, map );
+        }
+        
+        return map;
+    }
+
+    public boolean clear( TaskId id )
+    {
+        return internalMap.remove( id ) != null;
+    }
+}

=== added directory 'dhis-2/dhis-support/dhis-support-system/src/test/java/org/hisp/dhis/system/notification'
=== added file 'dhis-2/dhis-support/dhis-support-system/src/test/java/org/hisp/dhis/system/notification/NotifierTest.java'
--- dhis-2/dhis-support/dhis-support-system/src/test/java/org/hisp/dhis/system/notification/NotifierTest.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-support/dhis-support-system/src/test/java/org/hisp/dhis/system/notification/NotifierTest.java	2012-04-12 12:39:47 +0000
@@ -0,0 +1,90 @@
+package org.hisp.dhis.system.notification;
+
+/*
+ * Copyright (c) 2011, 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 junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertNull;
+
+import java.util.List;
+
+import org.hisp.dhis.DhisSpringTest;
+import org.hisp.dhis.scheduling.TaskCategory;
+import org.hisp.dhis.scheduling.TaskId;
+import org.hisp.dhis.system.notification.Notification;
+import org.hisp.dhis.system.notification.Notifier;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * @author Lars Helge Overland
+ */
+public class NotifierTest
+    extends DhisSpringTest
+{
+    @Autowired
+    private Notifier notifier;
+
+    private TaskId id1 = new TaskId( "DATAVALUE_IMPORT-admin" );
+    private TaskId id2 = new TaskId( "DATAMART-admin" );
+    private TaskId id3 = new TaskId( "METADATA_IMPORT-admin" );
+    
+    @Test
+    public void testNotifiy()
+    {
+        notifier.notify( id1, TaskCategory.DATAVALUE_IMPORT, "Import started" );
+        notifier.notify( id1, TaskCategory.DATAVALUE_IMPORT, "Import working" );
+        notifier.notify( id1, TaskCategory.DATAVALUE_IMPORT, "Import done" );
+        notifier.notify( id2, TaskCategory.DATAMART, "Process started" );
+        notifier.notify( id2, TaskCategory.DATAMART, "Process done" );
+        
+        List<Notification> notifications = notifier.getNotifications( id1, TaskCategory.DATAVALUE_IMPORT, null );
+        
+        assertNotNull( notifications );
+        assertEquals( 3, notifications.size() );
+        
+        notifications = notifier.getNotifications( id2, TaskCategory.DATAMART, null );
+        
+        assertNotNull( notifications );
+        assertEquals( 2, notifications.size() );
+
+        notifications = notifier.getNotifications( id3, TaskCategory.METADATA_IMPORT, null );
+        
+        assertNotNull( notifications );
+        assertEquals( 0, notifications.size() );
+    }
+    
+    @Test
+    public void testTaskSummary()
+    {
+        notifier.addTaskSummary( id1, TaskCategory.DATAVALUE_IMPORT, new Object() );
+        
+        assertNotNull( notifier.getTaskSummary( id1, TaskCategory.DATAVALUE_IMPORT ) );
+        assertNull( notifier.getTaskSummary( id1, TaskCategory.DATAMART ) );
+    }
+}

=== modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/DataValueSetController.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/DataValueSetController.java	2012-04-11 16:18:25 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/DataValueSetController.java	2012-04-12 12:39:47 +0000
@@ -91,7 +91,7 @@
                                   InputStream in,
                                   Model model ) throws IOException
     {
-        ImportSummary summary = dataValueSetService.saveDataValueSet( in, importOptions );
+        ImportSummary summary = dataValueSetService.saveDataValueSet( in, importOptions, null );
 
         log.info( "Data values set saved " + importOptions );    
 

=== modified file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/commons.js'
--- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/commons.js	2012-04-11 20:40:12 +0000
+++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/commons.js	2012-04-12 12:39:47 +0000
@@ -1620,7 +1620,7 @@
 			}		
 			
 			html += '<tr><td>' + notification.time + '</td><td>' + notification.message + ' &nbsp;';
-			html += isComplete ?  '<img src="../images/completed.png">' : loaderHtml;
+			html += notification.completed == "true" ?  '<img src="../images/completed.png">' : loaderHtml;
 			html += '</td></tr>';
 		} );
 		

=== modified file 'dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/commons/action/GetNotificationsAction.java'
--- dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/commons/action/GetNotificationsAction.java	2012-04-10 20:15:18 +0000
+++ dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/commons/action/GetNotificationsAction.java	2012-04-12 12:39:47 +0000
@@ -30,9 +30,12 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import org.hisp.dhis.scheduling.TaskCategory;
+import org.hisp.dhis.scheduling.TaskId;
 import org.hisp.dhis.system.notification.Notification;
-import org.hisp.dhis.system.notification.NotificationCategory;
 import org.hisp.dhis.system.notification.Notifier;
+import org.hisp.dhis.user.CurrentUserService;
+import org.springframework.beans.factory.annotation.Autowired;
 
 import com.opensymphony.xwork2.Action;
 
@@ -41,18 +44,13 @@
  */
 public class GetNotificationsAction
     implements Action
-{
-    // -------------------------------------------------------------------------
-    // Dependencies
-    // -------------------------------------------------------------------------
-    
+{    
+    @Autowired
     private Notifier notifier;
 
-    public void setNotifier( Notifier notifier )
-    {
-        this.notifier = notifier;
-    }
-
+    @Autowired
+    private CurrentUserService currentUserService;
+    
     // -------------------------------------------------------------------------
     // Input
     // -------------------------------------------------------------------------
@@ -71,13 +69,6 @@
         this.lastUid = lastUid;
     }
 
-    private Integer max;
-
-    public void setMax( Integer max )
-    {
-        this.max = max;
-    }
-
     // -------------------------------------------------------------------------
     // Output
     // -------------------------------------------------------------------------
@@ -99,16 +90,11 @@
     {
         if ( category != null )
         {
-            NotificationCategory notificationCategory = NotificationCategory.valueOf( category.toUpperCase() );
+            TaskCategory taskCategory = TaskCategory.valueOf( category.toUpperCase() );
 
-            if ( max != null )
-            {
-                notifications = notifier.getNotifications( notificationCategory, max );
-            }
-            else
-            {
-                notifications = notifier.getNotifications( notificationCategory, lastUid );
-            }
+            TaskId taskId = new TaskId( taskCategory, currentUserService.getCurrentUser() );
+            
+            notifications = notifier.getNotifications( taskId, taskCategory, lastUid );
         }
         
         return SUCCESS;

=== modified file 'dhis-2/dhis-web/dhis-web-commons/src/main/resources/META-INF/dhis/beans.xml'
--- dhis-2/dhis-web/dhis-web-commons/src/main/resources/META-INF/dhis/beans.xml	2012-03-10 10:14:33 +0000
+++ dhis-2/dhis-web/dhis-web-commons/src/main/resources/META-INF/dhis/beans.xml	2012-04-12 12:39:47 +0000
@@ -317,9 +317,7 @@
 
   <!-- Common actions -->
 
-  <bean id="org.hisp.dhis.commons.action.GetNotificationsAction" class="org.hisp.dhis.commons.action.GetNotificationsAction" scope="prototype">
-	<property name="notifier" ref="notifier" />
-  </bean>
+  <bean id="org.hisp.dhis.commons.action.GetNotificationsAction" class="org.hisp.dhis.commons.action.GetNotificationsAction" scope="prototype"/>
 
   <bean id="org.hisp.dhis.commons.action.GetUserAction" class="org.hisp.dhis.commons.action.GetUserAction" scope="prototype">
     <property name="userService" ref="org.hisp.dhis.user.UserService" />

=== modified file 'dhis-2/dhis-web/dhis-web-importexport/src/main/java/org/hisp/dhis/importexport/action/GetImportSummaryAction.java'
--- dhis-2/dhis-web/dhis-web-importexport/src/main/java/org/hisp/dhis/importexport/action/GetImportSummaryAction.java	2012-04-11 20:16:18 +0000
+++ dhis-2/dhis-web/dhis-web-importexport/src/main/java/org/hisp/dhis/importexport/action/GetImportSummaryAction.java	2012-04-12 12:39:47 +0000
@@ -28,25 +28,41 @@
  */
 
 import org.hisp.dhis.dxf2.importsummary.ImportSummary;
-import org.hisp.dhis.system.notification.NotificationCategory;
+import org.hisp.dhis.scheduling.TaskCategory;
+import org.hisp.dhis.scheduling.TaskId;
 import org.hisp.dhis.system.notification.Notifier;
+import org.hisp.dhis.user.CurrentUserService;
 import org.springframework.beans.factory.annotation.Autowired;
 
 import com.opensymphony.xwork2.Action;
 
+/**
+ * @author Lars Helge Overland
+ */
 public class GetImportSummaryAction
     implements Action
 {
     @Autowired
     private Notifier notifier;
     
-    private NotificationCategory category;
-    
-    public void setCategory( NotificationCategory category )
+    @Autowired
+    private CurrentUserService currentUserService;
+
+    // -------------------------------------------------------------------------
+    // Input
+    // -------------------------------------------------------------------------
+    
+    private TaskCategory category;
+    
+    public void setCategory( TaskCategory category )
     {
         this.category = category;
     }
 
+    // -------------------------------------------------------------------------
+    // Output
+    // -------------------------------------------------------------------------
+    
     private ImportSummary summary;
     
     public ImportSummary getSummary()
@@ -54,9 +70,15 @@
         return summary;
     }
 
+    // -------------------------------------------------------------------------
+    // Action implementation
+    // -------------------------------------------------------------------------
+    
     public String execute()
     {
-        summary = (ImportSummary) notifier.getTaskSummary( category );
+        TaskId taskId = new TaskId( category, currentUserService.getCurrentUser() );        
+        
+        summary = (ImportSummary) notifier.getTaskSummary( taskId, category );
         
         return SUCCESS;
     }

=== modified file 'dhis-2/dhis-web/dhis-web-importexport/src/main/java/org/hisp/dhis/importexport/action/datavalue/ImportDataValueAction.java'
--- dhis-2/dhis-web/dhis-web-importexport/src/main/java/org/hisp/dhis/importexport/action/datavalue/ImportDataValueAction.java	2012-04-11 13:49:03 +0000
+++ dhis-2/dhis-web/dhis-web-importexport/src/main/java/org/hisp/dhis/importexport/action/datavalue/ImportDataValueAction.java	2012-04-12 12:39:47 +0000
@@ -35,20 +35,33 @@
 import org.hisp.dhis.dxf2.datavalueset.DataValueSetService;
 import org.hisp.dhis.importexport.ImportStrategy;
 import org.hisp.dhis.importexport.action.util.ImportDataValueTask;
+import org.hisp.dhis.scheduling.TaskCategory;
+import org.hisp.dhis.scheduling.TaskId;
 import org.hisp.dhis.system.scheduling.Scheduler;
+import org.hisp.dhis.user.CurrentUserService;
 import org.springframework.beans.factory.annotation.Autowired;
 
 import com.opensymphony.xwork2.Action;
 
+/**
+ * @author Lars Helge Overland
+ */
 public class ImportDataValueAction
     implements Action
 {
     @Autowired
     private DataValueSetService dataValueSetService;
+
+    @Autowired
+    private CurrentUserService currentUserService;
     
     @Autowired
     private Scheduler scheduler;
 
+    // -------------------------------------------------------------------------
+    // Input
+    // -------------------------------------------------------------------------
+    
     private File upload;
 
     public void setUpload( File upload )
@@ -70,12 +83,18 @@
         this.strategy = ImportStrategy.valueOf( stgy );
     }
 
+    // -------------------------------------------------------------------------
+    // Action implementation
+    // -------------------------------------------------------------------------
+    
     public String execute()
         throws Exception
     {
+        final TaskId taskId = new TaskId( TaskCategory.DATAVALUE_IMPORT, currentUserService.getCurrentUser() );
+        
         final InputStream in = new BufferedInputStream( new FileInputStream( upload ) ); 
 
-        scheduler.executeTask( new ImportDataValueTask( dataValueSetService, in, dryRun, strategy ) );
+        scheduler.executeTask( new ImportDataValueTask( dataValueSetService, in, dryRun, strategy, taskId ) );
         
         return SUCCESS;
     }

=== modified file 'dhis-2/dhis-web/dhis-web-importexport/src/main/java/org/hisp/dhis/importexport/action/util/ImportDataValueTask.java'
--- dhis-2/dhis-web/dhis-web-importexport/src/main/java/org/hisp/dhis/importexport/action/util/ImportDataValueTask.java	2012-04-11 19:17:22 +0000
+++ dhis-2/dhis-web/dhis-web-importexport/src/main/java/org/hisp/dhis/importexport/action/util/ImportDataValueTask.java	2012-04-12 12:39:47 +0000
@@ -33,7 +33,11 @@
 import org.hisp.dhis.dxf2.datavalueset.DataValueSetService;
 import org.hisp.dhis.dxf2.metadata.ImportOptions;
 import org.hisp.dhis.importexport.ImportStrategy;
+import org.hisp.dhis.scheduling.TaskId;
 
+/**
+ * @author Lars Helge Overland
+ */
 public class ImportDataValueTask
     implements Runnable
 {    
@@ -41,18 +45,20 @@
     private InputStream in;
     private boolean dryRun;
     private ImportStrategy strategy;
+    private TaskId taskId;
     
-    public ImportDataValueTask( DataValueSetService dataValueSetService, InputStream in, boolean dryRun, ImportStrategy strategy )
+    public ImportDataValueTask( DataValueSetService dataValueSetService, InputStream in, boolean dryRun, ImportStrategy strategy, TaskId taskId )
     {
         this.dataValueSetService = dataValueSetService;
         this.in = in;
         this.dryRun = dryRun;
         this.strategy = strategy;
+        this.taskId = taskId;
     }
     
     @Override
     public void run()
     {
-        dataValueSetService.saveDataValueSet( in, new ImportOptions( IdentifiableProperty.UID, IdentifiableProperty.UID, dryRun, strategy ) );
+        dataValueSetService.saveDataValueSet( in, new ImportOptions( IdentifiableProperty.UID, IdentifiableProperty.UID, dryRun, strategy ), taskId );
     }
 }

=== modified file 'dhis-2/dhis-web/dhis-web-reporting/src/main/java/org/hisp/dhis/reporting/datamart/action/StartExportAction.java'
--- dhis-2/dhis-web/dhis-web-reporting/src/main/java/org/hisp/dhis/reporting/datamart/action/StartExportAction.java	2012-02-12 20:32:14 +0000
+++ dhis-2/dhis-web/dhis-web-reporting/src/main/java/org/hisp/dhis/reporting/datamart/action/StartExportAction.java	2012-04-12 12:39:47 +0000
@@ -36,9 +36,12 @@
 import org.hisp.dhis.period.CalendarPeriodType;
 import org.hisp.dhis.period.Period;
 import org.hisp.dhis.period.PeriodType;
+import org.hisp.dhis.scheduling.TaskCategory;
+import org.hisp.dhis.scheduling.TaskId;
 import org.hisp.dhis.system.scheduling.DataMartTask;
 import org.hisp.dhis.system.scheduling.Scheduler;
 import org.hisp.dhis.system.util.DateUtils;
+import org.hisp.dhis.user.CurrentUserService;
 
 import com.opensymphony.xwork2.Action;
 
@@ -52,6 +55,13 @@
     // Dependencies
     // -------------------------------------------------------------------------
 
+    private CurrentUserService currentUserService;
+    
+    public void setCurrentUserService( CurrentUserService currentUserService )
+    {
+        this.currentUserService = currentUserService;
+    }
+
     private Scheduler scheduler;
     
     public void setScheduler( Scheduler scheduler )
@@ -110,10 +120,13 @@
             
             periods.addAll( periodType.generatePeriods( start, end ) );
         }
+
+        TaskId taskId = new TaskId( TaskCategory.DATAMART, currentUserService.getCurrentUser() );
         
         if ( periods.size() > 0 )
         {
             dataMartTask.setPeriods( periods );
+            dataMartTask.setTaskId( taskId );
         
             scheduler.executeTask( dataMartTask );
         }

=== modified file 'dhis-2/dhis-web/dhis-web-reporting/src/main/resources/META-INF/dhis/beans.xml'
--- dhis-2/dhis-web/dhis-web-reporting/src/main/resources/META-INF/dhis/beans.xml	2012-04-07 14:06:33 +0000
+++ dhis-2/dhis-web/dhis-web-reporting/src/main/resources/META-INF/dhis/beans.xml	2012-04-12 12:39:47 +0000
@@ -247,6 +247,7 @@
   
   <bean id="org.hisp.dhis.reporting.datamart.action.StartExportAction" class="org.hisp.dhis.reporting.datamart.action.StartExportAction"
 	scope="prototype">
+	<property name="currentUserService" ref="org.hisp.dhis.user.CurrentUserService"/>
 	<property name="scheduler" ref="scheduler"/>
 	<property name="dataMartTask" ref="dataMartLast12MonthsTask"/>
   </bean>