← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 19433: Analytics, added support for aggregated program attribute values.

 

------------------------------------------------------------
revno: 19433
committer: Lars Helge Overland <larshelge@xxxxxxxxx>
branch nick: dhis2
timestamp: Wed 2015-06-17 16:52:34 +0200
message:
  Analytics, added support for aggregated program attribute values.
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/DimensionType.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/DimensionalObject.java
  dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/DataQueryParams.java
  dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultAnalyticsService.java
  dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultQueryPlanner.java
  dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/EventQueryParams.java
  dhis-2/dhis-services/dhis-service-analytics/src/test/java/org/hisp/dhis/analytics/data/AnalyticsServiceTest.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/setting/DefaultSystemSettingManager.java
  dhis-2/dhis-support/dhis-support-commons/src/main/java/org/hisp/dhis/commons/collection/ListUtils.java


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

Your team DHIS 2 developers is subscribed to branch lp:dhis2.
To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/DimensionType.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/DimensionType.java	2015-06-14 11:58:26 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/DimensionType.java	2015-06-17 14:52:34 +0000
@@ -38,6 +38,7 @@
     DATASET,
     DATAELEMENT_OPERAND,
     PROGRAM_DATAELEMENT,
+    PROGRAM_ATTRIBUTE,
     DATA_X,
     DATA_COLLAPSED,
     CATEGORY_OPTION_COMBO,

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/DimensionalObject.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/DimensionalObject.java	2015-06-14 11:58:26 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/DimensionalObject.java	2015-06-17 14:52:34 +0000
@@ -54,6 +54,7 @@
     final String DATASET_DIM_ID = "ds";
     final String DATAELEMENT_OPERAND_ID = "dc";
     final String PROGRAM_DATAELEMENT_DIM_ID = "pd";
+    final String PROGRAM_ATTRIBUTE_DIM_ID = "pa";
     final String CATEGORYOPTIONCOMBO_DIM_ID = "co";
     final String PERIOD_DIM_ID = "pe";
     final String ORGUNIT_DIM_ID = "ou";
@@ -71,8 +72,10 @@
     final String LONGITUDE_DIM_ID = "longitude";
     final String LATITUDE_DIM_ID = "latitude";
 
-    final List<String> DATA_X_DIMS = Arrays.asList( INDICATOR_DIM_ID, DATAELEMENT_DIM_ID, DATASET_DIM_ID, DATAELEMENT_OPERAND_ID, PROGRAM_DATAELEMENT_DIM_ID );    
-    final List<String> STATIC_DIMS = Arrays.asList( LONGITUDE_DIM_ID, LATITUDE_DIM_ID );
+    final List<String> DATA_X_DIMS = Arrays.asList( 
+        INDICATOR_DIM_ID, DATAELEMENT_DIM_ID, DATASET_DIM_ID, DATAELEMENT_OPERAND_ID, PROGRAM_DATAELEMENT_DIM_ID, PROGRAM_ATTRIBUTE_DIM_ID );    
+    final List<String> STATIC_DIMS = Arrays.asList( 
+        LONGITUDE_DIM_ID, LATITUDE_DIM_ID );
     
     final Map<String, String> PRETTY_NAMES = DimensionalObjectUtils.asMap( 
         DATA_X_DIM_ID, "Data",

=== modified file 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/DataQueryParams.java'
--- dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/DataQueryParams.java	2015-06-16 17:25:14 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/DataQueryParams.java	2015-06-17 14:52:34 +0000
@@ -45,6 +45,7 @@
 import static org.hisp.dhis.common.DimensionalObject.ORGUNIT_DIM_ID;
 import static org.hisp.dhis.common.DimensionalObject.PERIOD_DIM_ID;
 import static org.hisp.dhis.common.DimensionalObject.PROGRAM_DATAELEMENT_DIM_ID;
+import static org.hisp.dhis.common.DimensionalObject.PROGRAM_ATTRIBUTE_DIM_ID;
 import static org.hisp.dhis.common.NameableObjectUtils.asList;
 import static org.hisp.dhis.common.NameableObjectUtils.getList;
 
@@ -86,6 +87,8 @@
 import org.hisp.dhis.commons.collection.CollectionUtils;
 import org.hisp.dhis.commons.collection.ListUtils;
 
+import com.google.common.collect.Lists;
+
 /**
  * @author Lars Helge Overland
  */
@@ -107,11 +110,11 @@
     public static final int CO_IN_INDEX = 1;
     
     public static final List<String> DATA_DIMS = Arrays.asList( 
-        INDICATOR_DIM_ID, DATAELEMENT_DIM_ID, DATAELEMENT_OPERAND_ID, DATASET_DIM_ID, PROGRAM_DATAELEMENT_DIM_ID );
+        INDICATOR_DIM_ID, DATAELEMENT_DIM_ID, DATAELEMENT_OPERAND_ID, DATASET_DIM_ID, PROGRAM_DATAELEMENT_DIM_ID, PROGRAM_ATTRIBUTE_DIM_ID );
     public static final List<String> FIXED_DIMS = Arrays.asList( 
-        DATA_X_DIM_ID, INDICATOR_DIM_ID, DATAELEMENT_DIM_ID, DATASET_DIM_ID, PROGRAM_DATAELEMENT_DIM_ID, PERIOD_DIM_ID, ORGUNIT_DIM_ID );
+        DATA_X_DIM_ID, INDICATOR_DIM_ID, DATAELEMENT_DIM_ID, DATASET_DIM_ID, PROGRAM_DATAELEMENT_DIM_ID, PROGRAM_ATTRIBUTE_DIM_ID, PERIOD_DIM_ID, ORGUNIT_DIM_ID );
     private static final List<String> DIMENSION_PERMUTATION_IGNORE_DIMS = Arrays.asList( 
-        INDICATOR_DIM_ID, DATAELEMENT_DIM_ID, CATEGORYOPTIONCOMBO_DIM_ID, DATASET_DIM_ID, PROGRAM_DATAELEMENT_DIM_ID );    
+        INDICATOR_DIM_ID, DATAELEMENT_DIM_ID, CATEGORYOPTIONCOMBO_DIM_ID, DATASET_DIM_ID, PROGRAM_DATAELEMENT_DIM_ID, PROGRAM_ATTRIBUTE_DIM_ID );    
     public static final List<DimensionType> COMPLETENESS_DIMENSION_TYPES = Arrays.asList( 
         DATASET, PERIOD, ORGANISATIONUNIT, ORGANISATIONUNIT_GROUPSET, CATEGORYOPTION_GROUPSET );
     private static final List<DimensionType> COMPLETENESS_TARGET_DIMENSION_TYPES = Arrays.asList( 
@@ -282,7 +285,8 @@
         if ( !dimensions.contains( new BaseDimensionalObject( DATAELEMENT_DIM_ID ) ) ||
             dimensions.contains( new BaseDimensionalObject( INDICATOR_DIM_ID ) ) ||
             dimensions.contains( new BaseDimensionalObject( DATASET_DIM_ID ) ) ||
-            dimensions.contains( new BaseDimensionalObject( PROGRAM_DATAELEMENT_DIM_ID ) ) )
+            dimensions.contains( new BaseDimensionalObject( PROGRAM_DATAELEMENT_DIM_ID ) ) ||
+            dimensions.contains( new BaseDimensionalObject( PROGRAM_ATTRIBUTE_DIM_ID ) ) )
         {
             removeDimension( CATEGORYOPTIONCOMBO_DIM_ID );
         }
@@ -351,10 +355,12 @@
             }
         }
         
-        list.remove( new BaseDimensionalObject( INDICATOR_DIM_ID ) );
-        list.remove( new BaseDimensionalObject( DATAELEMENT_DIM_ID ) );
-        list.remove( new BaseDimensionalObject( DATASET_DIM_ID ) );
-        list.remove( new BaseDimensionalObject( PROGRAM_DATAELEMENT_DIM_ID ) );
+        list.removeAll( Lists.newArrayList( 
+            new BaseDimensionalObject( INDICATOR_DIM_ID ),
+            new BaseDimensionalObject( DATAELEMENT_DIM_ID ),
+            new BaseDimensionalObject( DATASET_DIM_ID ),
+            new BaseDimensionalObject( PROGRAM_DATAELEMENT_DIM_ID ),
+            new BaseDimensionalObject( PROGRAM_ATTRIBUTE_DIM_ID ) ) );
         
         return list;
     }
@@ -1605,9 +1611,19 @@
         return getDimensionOptions( PROGRAM_DATAELEMENT_DIM_ID );
     }
     
-    public void setProgramDataElements( List<? extends NameableObject> trackerDataElements )
-    {
-        setDimensionOptions( PROGRAM_DATAELEMENT_DIM_ID, DimensionType.PROGRAM_DATAELEMENT, null, asList( trackerDataElements ) );
+    public void setProgramDataElements( List<? extends NameableObject> programDataElements )
+    {
+        setDimensionOptions( PROGRAM_DATAELEMENT_DIM_ID, DimensionType.PROGRAM_DATAELEMENT, null, asList( programDataElements ) );
+    }
+    
+    public List<NameableObject> getProgramAttributes()
+    {
+        return getDimensionOptions( PROGRAM_ATTRIBUTE_DIM_ID );
+    }
+    
+    public void setProgramAttributes( List<? extends NameableObject> programAttributes )
+    {
+        setDimensionOptions( PROGRAM_ATTRIBUTE_DIM_ID, DimensionType.PROGRAM_ATTRIBUTE, null, asList( programAttributes ) );
     }
     
     public List<DimensionalObject> getDataElementGroupSets()
@@ -1702,6 +1718,11 @@
         return getFilterOptions( PROGRAM_DATAELEMENT_DIM_ID );
     }
     
+    public List<NameableObject> getFilterProgramAttributes()
+    {
+        return getFilterOptions( PROGRAM_ATTRIBUTE_DIM_ID );
+    }
+    
     public void setFilter( String filter, DimensionType type, NameableObject item )
     {
         setFilterOptions( filter, type, null, getList( item ) );

=== modified file 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultAnalyticsService.java'
--- dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultAnalyticsService.java	2015-06-16 17:25:14 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultAnalyticsService.java	2015-06-17 14:52:34 +0000
@@ -53,6 +53,7 @@
 import static org.hisp.dhis.common.DimensionalObject.PERIOD_DIM_ID;
 import static org.hisp.dhis.common.DimensionalObject.PROGRAM_INDICATOR_DIM_ID;
 import static org.hisp.dhis.common.DimensionalObject.PROGRAM_DATAELEMENT_DIM_ID;
+import static org.hisp.dhis.common.DimensionalObject.PROGRAM_ATTRIBUTE_DIM_ID;
 import static org.hisp.dhis.common.DimensionalObjectUtils.toDimension;
 import static org.hisp.dhis.common.IdentifiableObjectUtils.getLocalPeriodIdentifier;
 import static org.hisp.dhis.common.IdentifiableObjectUtils.getLocalPeriodIdentifiers;
@@ -151,6 +152,7 @@
 import org.hisp.dhis.commons.util.DebugUtils;
 import org.hisp.dhis.commons.collection.ListUtils;
 import org.hisp.dhis.system.util.SystemUtils;
+import org.hisp.dhis.trackedentity.TrackedEntityAttribute;
 import org.hisp.dhis.util.Timer;
 import org.hisp.dhis.commons.collection.UniqueArrayList;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -255,7 +257,7 @@
 
         addDataSetValues( params, grid );
         
-        addProgramDataElementValues( params, grid );
+        addProgramValues( params, grid );
 
         addDynamicDimensionValues( params, grid );
 
@@ -371,6 +373,7 @@
             dataSourceParams.removeDimension( INDICATOR_DIM_ID );
             dataSourceParams.removeDimension( DATASET_DIM_ID );
             dataSourceParams.removeDimension( PROGRAM_DATAELEMENT_DIM_ID );
+            dataSourceParams.removeDimension( PROGRAM_ATTRIBUTE_DIM_ID );
 
             Map<String, Object> aggregatedDataMap = getAggregatedDataValueMapObjectTyped( dataSourceParams );
 
@@ -390,9 +393,9 @@
      * @param params the data query parameters.
      * @param grid the grid.
      */
-    private void addProgramDataElementValues( DataQueryParams params, Grid grid )
+    private void addProgramValues( DataQueryParams params, Grid grid )
     {
-        if ( !params.getProgramDataElements().isEmpty() )
+        if ( !params.getProgramDataElements().isEmpty() || !params.getProgramAttributes().isEmpty() )
         {
             DataQueryParams dataSourceParams = params.instance();
             dataSourceParams.removeDimension( INDICATOR_DIM_ID );
@@ -427,6 +430,7 @@
             dataSourceParams.removeDimension( INDICATOR_DIM_ID );
             dataSourceParams.removeDimension( DATAELEMENT_DIM_ID );
             dataSourceParams.removeDimension( PROGRAM_DATAELEMENT_DIM_ID );
+            dataSourceParams.removeDimension( PROGRAM_ATTRIBUTE_DIM_ID );
             dataSourceParams.setAggregationType( AggregationType.COUNT );
 
             if ( !COMPLETENESS_DIMENSION_TYPES.containsAll( dataSourceParams.getDimensionTypes() ) )
@@ -979,6 +983,7 @@
             List<NameableObject> dataSets = new ArrayList<>();
             List<NameableObject> operandDataElements = new ArrayList<>();
             List<NameableObject> programDataElements = new ArrayList<>();
+            List<NameableObject> programAttributes = new ArrayList<>();
 
             itemLoop:
             for ( String uid : items )
@@ -1033,6 +1038,14 @@
                     operandDataElements.add( dc.getDataElement() );
                     continue itemLoop;
                 }
+                
+                TrackedEntityAttribute pa = idObjectManager.get( TrackedEntityAttribute.class, uid );
+                
+                if ( pa != null )
+                {
+                    programAttributes.add( pa );
+                    continue itemLoop;
+                }
 
                 throw new IllegalQueryException( "Data dimension option identifier does not reference any option: " + uid );
             }
@@ -1071,7 +1084,12 @@
                 dataDimensions.add( new BaseDimensionalObject( PROGRAM_DATAELEMENT_DIM_ID, DimensionType.PROGRAM_DATAELEMENT, programDataElements ) );
             }
 
-            if ( indicators.isEmpty() && dataElements.isEmpty() && dataSets.isEmpty() && operandDataElements.isEmpty() && programDataElements.isEmpty() )
+            if ( !programAttributes.isEmpty() )
+            {
+                dataDimensions.add( new BaseDimensionalObject( PROGRAM_ATTRIBUTE_DIM_ID, DimensionType.PROGRAM_ATTRIBUTE, programAttributes ) );
+            }
+            
+            if ( indicators.isEmpty() && dataElements.isEmpty() && dataSets.isEmpty() && operandDataElements.isEmpty() && programDataElements.isEmpty() && programAttributes.isEmpty() )
             {
                 throw new IllegalQueryException( "Dimension dx is present in query without any valid dimension options" );
             }
@@ -1332,7 +1350,8 @@
 
         if ( !dataElements.isEmpty() )
         {
-            DataQueryParams dataSourceParams = params.instance().removeDimensions( INDICATOR_DIM_ID, DATAELEMENT_DIM_ID, DATASET_DIM_ID, PROGRAM_DATAELEMENT_DIM_ID );
+            DataQueryParams dataSourceParams = params.instance().removeDimensions( 
+                INDICATOR_DIM_ID, DATAELEMENT_DIM_ID, DATASET_DIM_ID, PROGRAM_DATAELEMENT_DIM_ID, PROGRAM_ATTRIBUTE_DIM_ID );
             
             dataSourceParams.getDimensions().add( DataQueryParams.DE_IN_INDEX, new BaseDimensionalObject( 
                 DATAELEMENT_DIM_ID, DimensionType.DATAELEMENT, dataElements ) );
@@ -1358,7 +1377,8 @@
 
         if ( !dataElements.isEmpty() )
         {
-            DataQueryParams dataSourceParams = params.instance().removeDimensions( INDICATOR_DIM_ID, DATAELEMENT_DIM_ID, DATASET_DIM_ID, PROGRAM_DATAELEMENT_DIM_ID );
+            DataQueryParams dataSourceParams = params.instance().removeDimensions( 
+                INDICATOR_DIM_ID, DATAELEMENT_DIM_ID, DATASET_DIM_ID, PROGRAM_DATAELEMENT_DIM_ID, PROGRAM_ATTRIBUTE_DIM_ID );
             
             dataSourceParams.getDimensions().add( DataQueryParams.DE_IN_INDEX, new BaseDimensionalObject( 
                 DATAELEMENT_DIM_ID, DimensionType.DATAELEMENT, dataElements ) );

=== modified file 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultQueryPlanner.java'
--- dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultQueryPlanner.java	2015-06-15 13:44:20 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultQueryPlanner.java	2015-06-17 14:52:34 +0000
@@ -37,6 +37,7 @@
 import static org.hisp.dhis.common.DimensionalObject.ORGUNIT_DIM_ID;
 import static org.hisp.dhis.common.DimensionalObject.PERIOD_DIM_ID;
 import static org.hisp.dhis.common.DimensionalObject.PROGRAM_DATAELEMENT_DIM_ID;
+import static org.hisp.dhis.common.DimensionalObject.PROGRAM_ATTRIBUTE_DIM_ID;
 import static org.hisp.dhis.dataelement.DataElement.AGGREGATION_OPERATOR_AVERAGE;
 import static org.hisp.dhis.dataelement.DataElement.AGGREGATION_OPERATOR_AVERAGE_SUM;
 import static org.hisp.dhis.dataelement.DataElement.VALUE_TYPE_BOOL;
@@ -160,6 +161,11 @@
         {
             violation = "Program must be specified when tracker data elements are specified";
         }
+
+        if ( params.hasDimensionOrFilter( PROGRAM_ATTRIBUTE_DIM_ID ) && !params.hasProgram() )
+        {
+            violation = "Program must be specified when program attributes are specified";
+        }
         
         if ( violation != null )
         {

=== modified file 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/EventQueryParams.java'
--- dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/EventQueryParams.java	2015-06-15 13:44:20 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/EventQueryParams.java	2015-06-17 14:52:34 +0000
@@ -31,6 +31,7 @@
 import static org.hisp.dhis.common.DimensionalObject.PERIOD_DIM_ID;
 import static org.hisp.dhis.common.DimensionalObject.PROGRAM_INDICATOR_DIM_ID;
 import static org.hisp.dhis.common.DimensionalObject.PROGRAM_DATAELEMENT_DIM_ID;
+import static org.hisp.dhis.common.DimensionalObject.PROGRAM_ATTRIBUTE_DIM_ID;
 
 import java.util.ArrayList;
 import java.util.Date;
@@ -51,6 +52,7 @@
 import org.hisp.dhis.option.OptionSet;
 import org.hisp.dhis.organisationunit.OrganisationUnit;
 import org.hisp.dhis.period.Period;
+import org.hisp.dhis.trackedentity.TrackedEntityAttribute;
 import org.hisp.dhis.commons.collection.ListUtils;
 
 /**
@@ -143,22 +145,37 @@
         
         dataQueryParams.copyTo( params );
         
-        for ( NameableObject object : ListUtils.emptyIfNull( dataQueryParams.getProgramDataElements() ) )
+        for ( NameableObject object : dataQueryParams.getProgramDataElements() )
         {
             DataElement element = (DataElement) object;            
             QueryItem item = new QueryItem( element, element.getLegendSet(), element.getType(), element.getOptionSet() );
             params.getItems().add( item );
         }
 
-        for ( NameableObject object : ListUtils.emptyIfNull( dataQueryParams.getFilterProgramDataElements() ) )
+        for ( NameableObject object : dataQueryParams.getProgramAttributes() )
+        {
+            TrackedEntityAttribute element = (TrackedEntityAttribute) object;            
+            QueryItem item = new QueryItem( element, element.getLegendSet(), element.getValueType(), element.getOptionSet() );
+            params.getItems().add( item );
+        }
+
+        for ( NameableObject object : dataQueryParams.getFilterProgramDataElements() )
         {
             DataElement element = (DataElement) object;            
             QueryItem item = new QueryItem( element, element.getLegendSet(), element.getType(), element.getOptionSet() );            
             params.getItemFilters().add( item );
         }
 
+        for ( NameableObject object : dataQueryParams.getFilterProgramAttributes() )
+        {
+            TrackedEntityAttribute element = (TrackedEntityAttribute) object;            
+            QueryItem item = new QueryItem( element, element.getLegendSet(), element.getValueType(), element.getOptionSet() );            
+            params.getItemFilters().add( item );
+        }
+
         params.setAggregateData( true );
         params.removeDimensionOrFilter( PROGRAM_DATAELEMENT_DIM_ID );
+        params.removeDimensionOrFilter( PROGRAM_ATTRIBUTE_DIM_ID );
         
         return params;
     }

=== modified file 'dhis-2/dhis-services/dhis-service-analytics/src/test/java/org/hisp/dhis/analytics/data/AnalyticsServiceTest.java'
--- dhis-2/dhis-services/dhis-service-analytics/src/test/java/org/hisp/dhis/analytics/data/AnalyticsServiceTest.java	2015-06-14 16:02:38 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/test/java/org/hisp/dhis/analytics/data/AnalyticsServiceTest.java	2015-06-17 14:52:34 +0000
@@ -50,6 +50,8 @@
 import org.hisp.dhis.organisationunit.OrganisationUnitGroupSet;
 import org.hisp.dhis.organisationunit.OrganisationUnitService;
 import org.hisp.dhis.period.PeriodType;
+import org.hisp.dhis.trackedentity.TrackedEntityAttribute;
+import org.hisp.dhis.trackedentity.TrackedEntityAttributeService;
 import org.hisp.dhis.user.CurrentUserService;
 import org.hisp.dhis.user.User;
 import org.junit.Test;
@@ -68,6 +70,9 @@
     private DataElement deE;
     private DataElement deF;
     
+    private TrackedEntityAttribute paA;
+    private TrackedEntityAttribute paB;
+    
     private OrganisationUnit ouA;
     private OrganisationUnit ouB;
     private OrganisationUnit ouC;
@@ -91,6 +96,9 @@
     
     @Autowired
     private OrganisationUnitGroupService organisationUnitGroupService;
+
+    @Autowired
+    private TrackedEntityAttributeService attributeService;
     
     @Override
     public void setUpTest()
@@ -111,6 +119,12 @@
         dataElementService.addDataElement( deD );
         dataElementService.addDataElement( deE );
         dataElementService.addDataElement( deF );
+
+        paA = createTrackedEntityAttribute( 'A' );
+        paB = createTrackedEntityAttribute( 'B' );
+        
+        attributeService.addTrackedEntityAttribute( paA );
+        attributeService.addTrackedEntityAttribute( paB );
         
         ouA = createOrganisationUnit( 'A' );
         ouB = createOrganisationUnit( 'B' );
@@ -221,6 +235,23 @@
     }
 
     @Test
+    public void testGetFromUrlD()
+    {
+        Set<String> dimensionParams = new HashSet<>();
+        dimensionParams.add( "dx:" + deA.getUid() + ";" + deB.getUid() + ";" + paA.getUid() + ";" + paB.getUid() );
+
+        Set<String> filterParams = new HashSet<>();
+        filterParams.add( "ou:" + ouA.getUid() );
+        
+        DataQueryParams params = analyticsService.getFromUrl( dimensionParams, filterParams, null, null, 
+            false, false, false, false, false, false, null, null, null, null, null, null );
+        
+        assertEquals( 2, params.getDataElements().size() );
+        assertEquals( 2, params.getProgramAttributes().size() );
+        assertEquals( 1, params.getFilterOrganisationUnits().size() );
+    }
+
+    @Test
     public void testGetFromUrlOrgUnitGroupSetAllItems()
     {
         Set<String> dimensionParams = new HashSet<>();

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/setting/DefaultSystemSettingManager.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/setting/DefaultSystemSettingManager.java	2015-06-16 05:11:29 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/setting/DefaultSystemSettingManager.java	2015-06-17 14:52:34 +0000
@@ -187,12 +187,6 @@
     }
 
     @Override
-    public boolean accountInviteEnabled()
-    {
-        return (Boolean) getSystemSetting( KEY_ACCOUNT_INVITE, false );
-    }
-
-    @Override
     public boolean selfRegistrationNoRecaptcha()
     {
         return (Boolean) getSystemSetting( KEY_SELF_REGISTRATION_NO_RECAPTCHA, false );

=== modified file 'dhis-2/dhis-support/dhis-support-commons/src/main/java/org/hisp/dhis/commons/collection/ListUtils.java'
--- dhis-2/dhis-support/dhis-support-commons/src/main/java/org/hisp/dhis/commons/collection/ListUtils.java	2015-06-16 17:57:23 +0000
+++ dhis-2/dhis-support/dhis-support-commons/src/main/java/org/hisp/dhis/commons/collection/ListUtils.java	2015-06-17 14:52:34 +0000
@@ -280,16 +280,4 @@
         
         return list;
     }
-    
-    /**
-     * Returns an empty list if the given list is null, otherwise returns the list
-     * as is.
-     * 
-     * @param list the list.
-     * @return a list.
-     */
-    public static <T> List<T> emptyIfNull( List<T> list )
-    {
-        return list != null ? list : new ArrayList<T>();
-    }
 }