← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 9575: Analytics, improved modelling, introduced class Dimension and DimensionOption

 

Merge authors:
  Lars Helge Øverland (larshelge)
------------------------------------------------------------
revno: 9575 [merge]
committer: Lars Helge Øverland <larshelge@xxxxxxxxx>
branch nick: dhis2
timestamp: Tue 2013-01-22 13:03:58 +0100
message:
  Analytics, improved modelling, introduced class Dimension and DimensionOption
added:
  dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/Dimension.java
  dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/DimensionType.java
modified:
  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/data/JdbcAnalyticsManager.java
  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/QueryPlannerTest.java
  dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/AnalyticsController.java
  dhis-2/dhis-web/dhis-web-dashboard-integration/src/main/webapp/dhis-web-dashboard-integration/profile.vm


--
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-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	2013-01-18 14:18:49 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/DataQueryParams.java	2013-01-22 07:59:25 +0000
@@ -47,7 +47,6 @@
 import org.hisp.dhis.system.util.ListMap;
 import org.hisp.dhis.system.util.MapMap;
 
-import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
 
 @JacksonXmlRootElement( localName = "dxf2", namespace = Dxf2Namespace.NAMESPACE )
@@ -69,11 +68,11 @@
     private static final DimensionOption[] DIM_OPT_ARR = new DimensionOption[0];
     private static final DimensionOption[][] DIM_OPT_2D_ARR = new DimensionOption[0][];
     
-    private Map<String, List<IdentifiableObject>> dimensions = new HashMap<String, List<IdentifiableObject>>();
+    private List<Dimension> dimensions = new ArrayList<Dimension>();
     
     private boolean categories = false;
 
-    private Map<String, List<IdentifiableObject>> filters = new HashMap<String, List<IdentifiableObject>>();
+    private List<Dimension> filters = new ArrayList<Dimension>();
     
     // -------------------------------------------------------------------------
     // Transient properties
@@ -97,7 +96,7 @@
     {
     }
     
-    public DataQueryParams( Map<String, List<IdentifiableObject>> dimensions, boolean categories, Map<String, List<IdentifiableObject>> filters )
+    public DataQueryParams( List<Dimension> dimensions, boolean categories, List<Dimension> filters )
     {
         this.dimensions = dimensions;
         this.categories = categories;
@@ -106,9 +105,9 @@
     
     public DataQueryParams( DataQueryParams params )
     {
-        this.dimensions = new HashMap<String, List<IdentifiableObject>>( params.getDimensions() );
+        this.dimensions = new ArrayList<Dimension>( params.getDimensions() );
         this.categories = params.isCategories();
-        this.filters = new HashMap<String, List<IdentifiableObject>>( params.getFilters() );
+        this.filters = new ArrayList<Dimension>( params.getFilters() );
         
         this.tableName = params.getTableName();
         this.periodType = params.getPeriodType();
@@ -122,50 +121,30 @@
     // -------------------------------------------------------------------------
 
     /**
-     * Creates a list of the names of all dimensions for this query. If the period
-     * type property is set, the period dimension name will be replaced by the name
-     * of the period type, if present. If the organisation unit level property
-     * is set, the organisation unit dimension name will be replaced by the name
-     * of the organisation unit level column.
+     * Creates a list of the names of all dimensions for this query.
      */
-    public List<String> getSelectDimensionNames()
+    public List<Dimension> getSelectDimensions()
     {
-        List<String> list = getSelectDimensionNamesAsList();
-
-        if ( list.contains( PERIOD_DIM_ID ) && periodType != null )
-        {
-            list.set( list.indexOf( PERIOD_DIM_ID ), periodType );
-        }
-        
-        if ( list.contains( ORGUNIT_DIM_ID ) && organisationUnitLevel != 0 )
-        {
-            list.set( list.indexOf( ORGUNIT_DIM_ID ), LEVEL_PREFIX + organisationUnitLevel );
+        List<Dimension> list = new ArrayList<Dimension>( dimensions );
+        
+        list.remove( new Dimension( INDICATOR_DIM_ID ) );
+        
+        if ( categories )
+        {
+            list.add( new Dimension( CATEGORYOPTIONCOMBO_DIM_ID, DimensionType.CATEGORY_OPTION_COMBO, new ArrayList<IdentifiableObject>() ) );
         }
         
         return list;
     }
     
     /**
-     * Creates a list of the names of all dimensions for this query. If the period
-     * type property is set, the period dimension name will be replaced by the name
-     * of the period type, if present. If the organisation unit level property
-     * is set, the organisation unit dimension name will be replaced by the name
-     * of the organisation unit level column. Does not include the categories
-     * dimension, even if the categories property of this object is true.
+     * Creates a list of the names of all dimensions for this query. 
      */
-    public List<String> getQueryDimensionNames()
+    public List<Dimension> getQueryDimensions()
     {
-        List<String> list = getQueryDimensionNamesAsList();
-        
-        if ( list.contains( PERIOD_DIM_ID ) && periodType != null )
-        {
-            list.set( list.indexOf( PERIOD_DIM_ID ), periodType );
-        }
-        
-        if ( list.contains( ORGUNIT_DIM_ID ) && organisationUnitLevel != 0 )
-        {
-            list.set( list.indexOf( ORGUNIT_DIM_ID ), LEVEL_PREFIX + organisationUnitLevel );
-        }
+        List<Dimension> list = new ArrayList<Dimension>( dimensions );
+        
+        list.remove( new Dimension( INDICATOR_DIM_ID ) );
         
         return list;
     }
@@ -175,7 +154,7 @@
      */
     public void removeDimension( String dimension )
     {
-        this.dimensions.remove( dimension );
+        this.dimensions.remove( new Dimension( dimension ) );
     }
     
     /**
@@ -211,48 +190,47 @@
     {
         return getAllDimensionNamesAsList().indexOf( PERIOD_DIM_ID );
     }
-    
-    /**
-     * Returns a list of the names of all filters.
-     */
-    public List<String> getFilterNames()
-    {
-        return new ArrayList<String>( filters.keySet() );
-    }
-    
-    /**
-     * Returns a mapping between the dimension names and dimension values. Inserts
-     * keys and values for the current period type column name and organisation 
-     * unit level name, if the period type property and organisation unit level
-     * property are set.
-     */
-    public Map<String, List<IdentifiableObject>> getDimensionMap()
-    {
-        Map<String, List<IdentifiableObject>> map = new HashMap<String, List<IdentifiableObject>>();
+        
+    /**
+     * Populates the dimension name property on all dimensions. Will set the 
+     * name of the current period type for this query on the period dimension
+     * and the a prefixed organisation unit level on the organisation unit
+     * dimension.
+     */
+    public void populateDimensionNames()
+    {
+        for ( Dimension dimension : dimensions )
+        {
+            if ( periodType != null && PERIOD_DIM_ID.equals( dimension.getDimension() ) )
+            {
+                dimension.setDimensionName( periodType );
+            }
+            else if ( organisationUnitLevel != 0 && ORGUNIT_DIM_ID.equals( dimension.getDimension() ) )
+            {
+                dimension.setDimensionName( LEVEL_PREFIX + organisationUnitLevel );
+            }
+        }
 
-        map.putAll( dimensions );
-        map.remove( INDICATOR_DIM_ID );
-        
-        if ( periodType != null )
-        {
-            map.put( periodType, dimensions.get( PERIOD_DIM_ID ) );
-        }
-        
-        if ( organisationUnitLevel != 0 )
-        {
-            map.put( LEVEL_PREFIX + organisationUnitLevel, dimensions.get( ORGUNIT_DIM_ID ) );
-        }
-        
-        return map;
+        for ( Dimension filter : filters )
+        {
+            if ( periodType != null && PERIOD_DIM_ID.equals( filter.getDimension() ) )
+            {
+                filter.setDimensionName( periodType );
+            }
+            else if ( organisationUnitLevel != 0 && ORGUNIT_DIM_ID.equals( filter.getDimension() ) )
+            {
+                filter.setDimensionName( LEVEL_PREFIX + organisationUnitLevel );
+            }
+        }
     }
     
     /**
      * Returns the dimensions which are part of dimensions and filters. If any
      * such dimensions exist this object is in an illegal state.
      */
-    public Collection<String> dimensionsAsFilters()
+    public Collection<Dimension> dimensionsAsFilters()
     {
-        return CollectionUtils.intersection( dimensions.keySet(), filters.keySet() );
+        return CollectionUtils.intersection( dimensions, filters );
     }
     
     /**
@@ -261,7 +239,7 @@
      */
     public boolean hasPeriods()
     {
-        return dimensions.containsKey( PERIOD_DIM_ID ) || filters.containsKey( PERIOD_DIM_ID );
+        return getDimensionOptions( PERIOD_DIM_ID ) != null || getFilterOptions( PERIOD_DIM_ID ) != null;
     }
     
     /**
@@ -282,7 +260,7 @@
 
         if ( dataPeriodType != null )
         {
-            for ( IdentifiableObject aggregatePeriod : this.getPeriods() )
+            for ( IdentifiableObject aggregatePeriod : getPeriods() )
             {
                 Period dataPeriod = dataPeriodType.createPeriod( ((Period) aggregatePeriod).getStartDate() );
                 
@@ -316,17 +294,17 @@
     {
         Map<String, String> map = new HashMap<String, String>();
         
-        for ( String dimension : dimensions.keySet() )
+        for ( Dimension dimension : dimensions )
         {
-            for ( IdentifiableObject idObject : dimensions.get( dimension ) )
+            for ( IdentifiableObject idObject : dimension.getOptions() )
             {
                 map.put( idObject.getUid(), idObject.getDisplayName() );
             }
         }
         
-        for ( String filter : filters.keySet() )
+        for ( Dimension filter : filters )
         {
-            for ( IdentifiableObject idObject : filters.get( filter ) )
+            for ( IdentifiableObject idObject : filter.getOptions() )
             {
                 map.put( idObject.getUid(), idObject.getDisplayName() );
             }
@@ -337,6 +315,7 @@
     
     /**
      * Generates all permutations of the dimension and filter options for this query.
+     * Ignores the data element, category option combo and indicator dimensions.
      */
     public List<List<DimensionOption>> getDimensionOptionPermutations()
     {
@@ -344,15 +323,15 @@
         
         List<String> ignoreDims = Arrays.asList( DATAELEMENT_DIM_ID, CATEGORYOPTIONCOMBO_DIM_ID, INDICATOR_DIM_ID );
         
-        for ( String dimension : getInputDimensionNamesAsList() )
+        for ( Dimension dimension : dimensions )
         {
-            if ( !ignoreDims.contains( dimension ) )
+            if ( !ignoreDims.contains( dimension.getDimension() ) )
             {
                 List<DimensionOption> options = new ArrayList<DimensionOption>();
                 
-                for ( IdentifiableObject option : dimensions.get( dimension ) )
+                for ( IdentifiableObject option : dimension.getOptions() )
                 {
-                    options.add( new DimensionOption( dimension, option ) );
+                    options.add( new DimensionOption( dimension.getDimension(), option ) );
                 }
                 
                 dimensionOptions.add( options.toArray( DIM_OPT_ARR ) );
@@ -396,6 +375,48 @@
         
         return valueMap;
     }
+
+    public List<IdentifiableObject> getDimensionOptions( String dimension )
+    {
+        int index = dimensions.indexOf( new Dimension( dimension ) );
+        
+        return index != -1 ? dimensions.get( index ).getOptions() : null;
+    }
+
+    public void setDimensionOptions( String dimension, DimensionType type, List<IdentifiableObject> options )
+    {
+        int index = dimensions.indexOf( new Dimension( dimension ) );
+        
+        if ( index != -1 )
+        {
+            dimensions.set( index, new Dimension( dimension, type, options ) );
+        }
+        else
+        {
+            dimensions.add( new Dimension( dimension, type, options ) );
+        }
+    }
+    
+    public List<IdentifiableObject> getFilterOptions( String filter )
+    {
+        int index = filters.indexOf( new Dimension( filter ) );
+        
+        return index != -1 ? filters.get( index ).getOptions() : null;
+    }
+    
+    public void setFilterOptions( String filter, DimensionType type, List<IdentifiableObject> options )
+    {
+        int index = filters.indexOf( new Dimension( filter ) );
+        
+        if ( index != -1 )
+        {
+            filters.set( index, new Dimension( filter, type, options ) );
+        }
+        else
+        {
+            filters.add( new Dimension( filter, type, options ) );
+        }
+    }
     
     // -------------------------------------------------------------------------
     // Static methods
@@ -415,38 +436,22 @@
         
         return null;
     }
-
+    
     // -------------------------------------------------------------------------
     // Supportive methods
     // -------------------------------------------------------------------------
 
     private List<String> getInputDimensionNamesAsList()
     {
-        return new ArrayList<String>( dimensions.keySet() );
-    }
-    
-    private List<String> getSelectDimensionNamesAsList()
-    {
-        List<String> list = getInputDimensionNamesAsList();
+        List<String> list = new ArrayList<String>();
         
-        list.remove( INDICATOR_DIM_ID );
-
-        if ( categories )
+        for ( Dimension dimension : dimensions )
         {
-            list.add( CATEGORYOPTIONCOMBO_DIM_ID );
+            list.add( dimension.getDimension() );
         }
         
         return list;
     }
-
-    private List<String> getQueryDimensionNamesAsList()
-    {
-        List<String> list = getInputDimensionNamesAsList();
-        
-        list.remove( INDICATOR_DIM_ID );
-        
-        return list;
-    }
     
     private List<String> getAllDimensionNamesAsList()
     {
@@ -536,19 +541,17 @@
     // -------------------------------------------------------------------------
     // Get and set methods for serialize properties
     // -------------------------------------------------------------------------
-  
-    @JsonProperty( value = "dimensions" )
-    public Map<String, List<IdentifiableObject>> getDimensions()
+
+    public List<Dimension> getDimensions()
     {
         return dimensions;
     }
 
-    public void setDimensions( Map<String, List<IdentifiableObject>> dimensions )
+    public void setDimensions( List<Dimension> dimensions )
     {
         this.dimensions = dimensions;
     }
 
-    @JsonProperty( value = "categories" )
     public boolean isCategories()
     {
         return categories;
@@ -559,13 +562,12 @@
         this.categories = categories;
     }
 
-    @JsonProperty( value = "filters" )
-    public Map<String, List<IdentifiableObject>> getFilters()
+    public List<Dimension> getFilters()
     {
         return filters;
     }
 
-    public void setFilters( Map<String, List<IdentifiableObject>> filters )
+    public void setFilters( List<Dimension> filters )
     {
         this.filters = filters;
     }
@@ -573,7 +575,7 @@
     // -------------------------------------------------------------------------
     // Get and set methods for transient properties
     // -------------------------------------------------------------------------
-  
+
     public String getTableName()
     {
         return tableName;
@@ -610,18 +612,18 @@
   
     public List<IdentifiableObject> getDimensionOrFilter( String key )
     {
-        return dimensions.containsKey( key ) ? dimensions.get( key ) : filters.get( key );
+        return getDimensionOptions( key ) != null ? getDimensionOptions( key ) : getFilterOptions( key );
     }
     
-    public void resetDimensionOrFilter( String key, List<IdentifiableObject> values )
+    public void resetDimensionOrFilter( String key, List<IdentifiableObject> options )
     {
-        if ( dimensions.containsKey( key ) )
+        if ( getDimensionOptions( key ) != null )
         {
-            dimensions.put( key, values );
+            setDimensionOptions( key, null, options );
         }
-        else if ( filters.containsKey( key ) )
+        else if ( getFilterOptions( key ) != null )
         {
-            filters.put( key, values );
+            setFilterOptions( key, null, options );
         }
     }
     
@@ -631,52 +633,52 @@
   
     public List<IdentifiableObject> getIndicators()
     {
-        return dimensions.get( INDICATOR_DIM_ID );
+        return getDimensionOptions( INDICATOR_DIM_ID );
     }
     
     public void setIndicators( List<IdentifiableObject> indicators )
     {
-        dimensions.put( INDICATOR_DIM_ID, indicators );
+        setDimensionOptions( INDICATOR_DIM_ID, DimensionType.INDICATOR, indicators );
     }
     
     public List<IdentifiableObject> getDataElements()
     {
-        return dimensions.get( DATAELEMENT_DIM_ID );
+        return getDimensionOptions( DATAELEMENT_DIM_ID );
     }
     
     public void setDataElements( List<IdentifiableObject> dataElements )
     {
-        dimensions.put( DATAELEMENT_DIM_ID, dataElements );
+        setDimensionOptions( DATAELEMENT_DIM_ID, DimensionType.DATAELEMENT, dataElements );
     }
     
     public List<IdentifiableObject> getDataSets()
     {
-        return dimensions.get( DATASET_DIM_ID );
+        return getDimensionOptions( DATASET_DIM_ID );
     }
     
     public void setDataSets( List<IdentifiableObject> dataSets )
     {
-        dimensions.get( DATASET_DIM_ID );
+        setDimensionOptions( DATASET_DIM_ID, DimensionType.DATASET, dataSets );
     }
     
     public List<IdentifiableObject> getPeriods()
     {
-        return dimensions.get( PERIOD_DIM_ID );
+        return getDimensionOptions( PERIOD_DIM_ID );
     }
     
     public void setPeriods( List<IdentifiableObject> periods )
     {
-        dimensions.put( PERIOD_DIM_ID, periods );
+        setDimensionOptions( PERIOD_DIM_ID, DimensionType.PERIOD, periods );
     }
 
     public List<IdentifiableObject> getOrganisationUnits()
     {
-        return dimensions.get( ORGUNIT_DIM_ID );
+        return getDimensionOptions( ORGUNIT_DIM_ID );
     }
     
     public void setOrganisationUnits( List<IdentifiableObject> organisationUnits )
     {
-        dimensions.put( ORGUNIT_DIM_ID, organisationUnits );
+        setDimensionOptions( ORGUNIT_DIM_ID, DimensionType.ORGANISATIONUNIT, organisationUnits );
     }
     
     // -------------------------------------------------------------------------
@@ -685,34 +687,38 @@
 
     public List<IdentifiableObject> getFilterDatElements()
     {
-        return filters.get( DATAELEMENT_DIM_ID );
+        return getFilterOptions( DATAELEMENT_DIM_ID );
     }
     
     public void setFilterDataElements( List<IdentifiableObject> dataElements )
     {
-        filters.put( DATAELEMENT_DIM_ID, dataElements );
+        setFilterOptions( DATAELEMENT_DIM_ID, DimensionType.DATAELEMENT, dataElements );
     }
     
     public List<IdentifiableObject> getFilterPeriods()
     {
-        return filters.get( PERIOD_DIM_ID );
+        return getFilterOptions( PERIOD_DIM_ID );
     }
     
     public void setFilterPeriods( List<IdentifiableObject> periods )
     {
-        filters.put( PERIOD_DIM_ID, periods );
+        setFilterOptions( PERIOD_DIM_ID, DimensionType.PERIOD, periods );
     }
     
     public List<IdentifiableObject> getFilterOrganisationUnits()
     {
-        return filters.get( ORGUNIT_DIM_ID );
+        return getFilterOptions( ORGUNIT_DIM_ID );
     }
     
     public void setFilterOrganisationUnits( List<IdentifiableObject> organisationUnits )
     {
-        filters.put( ORGUNIT_DIM_ID, organisationUnits );
+        setFilterOptions( ORGUNIT_DIM_ID, DimensionType.ORGANISATIONUNIT, organisationUnits );
     }
 
+    // -------------------------------------------------------------------------
+    // Get and set methods for transient properties
+    // -------------------------------------------------------------------------
+
     public AggregationType getAggregationType()
     {
         return aggregationType;

=== added file 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/Dimension.java'
--- dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/Dimension.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/Dimension.java	2013-01-22 07:59:25 +0000
@@ -0,0 +1,131 @@
+package org.hisp.dhis.analytics;
+
+/*
+ * 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.List;
+
+import org.hisp.dhis.common.IdentifiableObject;
+
+public class Dimension
+{
+    private String dimension;
+    
+    private DimensionType type;
+
+    private String dimensionName;
+
+    private List<IdentifiableObject> options = new ArrayList<IdentifiableObject>();
+    
+    public Dimension( String dimension )
+    {
+        this.dimension = dimension;
+    }
+
+    public Dimension( String dimension, DimensionType type, List<IdentifiableObject> options )
+    {
+        this.dimension = dimension;
+        this.type = type;
+        this.options = options;
+    }
+    
+    public String getDimension()
+    {
+        return dimension;
+    }
+
+    public void setDimension( String dimension )
+    {
+        this.dimension = dimension;
+    }
+
+    public DimensionType getType()
+    {
+        return type;
+    }
+
+    public void setType( DimensionType type )
+    {
+        this.type = type;
+    }
+
+    public String getDimensionName()
+    {
+        return dimensionName != null ? dimensionName : dimension;
+    }
+
+    public void setDimensionName( String dimensionName )
+    {
+        this.dimensionName = dimensionName;
+    }
+
+    public List<IdentifiableObject> getOptions()
+    {
+        return options;
+    }
+
+    public void setOptions( List<IdentifiableObject> options )
+    {
+        this.options = options;
+    }
+
+    @Override
+    public int hashCode()
+    {
+        return dimension.hashCode();
+    }
+
+    @Override
+    public boolean equals( Object object )
+    {
+        if ( this == object )
+        {
+            return true;
+        }
+        
+        if ( object == null )
+        {
+            return false;
+        }
+        
+        if ( getClass() != object.getClass() )
+        {
+            return false;
+        }
+        
+        Dimension other = (Dimension) object;
+        
+        return dimension.equals( other.dimension );
+    }
+    
+    @Override
+    public String toString()
+    {
+        return "[Dimension: " + dimension + ", type: " + type + ", name: " + dimensionName + ", options: " + options + "]";
+    }
+}

=== added file 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/DimensionType.java'
--- dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/DimensionType.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/DimensionType.java	2013-01-22 07:59:25 +0000
@@ -0,0 +1,13 @@
+package org.hisp.dhis.analytics;
+
+public enum DimensionType
+{
+    INDICATOR,
+    DATAELEMENT,
+    DATASET,
+    CATEGORY_OPTION_COMBO,
+    PERIOD,
+    ORGANISATIONUNIT,
+    DATAELEMENT_GROUPSET,
+    ORGANISATIONUNIT_GROUPSET
+}

=== 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	2013-01-18 16:00:12 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultAnalyticsService.java	2013-01-22 07:59:25 +0000
@@ -51,7 +51,9 @@
 import org.hisp.dhis.analytics.AnalyticsManager;
 import org.hisp.dhis.analytics.AnalyticsService;
 import org.hisp.dhis.analytics.DataQueryParams;
+import org.hisp.dhis.analytics.Dimension;
 import org.hisp.dhis.analytics.DimensionOption;
+import org.hisp.dhis.analytics.DimensionType;
 import org.hisp.dhis.analytics.QueryPlanner;
 import org.hisp.dhis.common.Grid;
 import org.hisp.dhis.common.GridHeader;
@@ -127,9 +129,9 @@
 
         grid.setMetaData( params.getUidNameMap() );
         
-        for ( String col : params.getSelectDimensionNames() )
+        for ( Dimension col : params.getSelectDimensions() )
         {
-            grid.addHeader( new GridHeader( col, col, String.class.getName(), false, true ) );
+            grid.addHeader( new GridHeader( col.getDimensionName(), col.getDimension(), String.class.getName(), false, true ) );
         }
         
         grid.addHeader( new GridHeader( DataQueryParams.VALUE_ID, VALUE_HEADER_NAME, Double.class.getName(), false, false ) );
@@ -279,9 +281,7 @@
                 
                 if ( dimension != null && options != null )
                 {
-                    List<IdentifiableObject> dimensionOptions = getDimensionOptions( dimension, options, format );
-                    
-                    params.getDimensions().put( dimension, dimensionOptions );
+                    params.getDimensions().add( getDimension( dimension, options, format ) );
                 }
             }
         }
@@ -295,9 +295,7 @@
                 
                 if ( dimension != null && options != null )
                 {
-                    List<IdentifiableObject> dimensionOptions = getDimensionOptions( dimension, options, format );
-                    
-                    params.getFilters().put( dimension, dimensionOptions );
+                    params.getFilters().add( getDimension( dimension, options, format ) );
                 }
             }
         }
@@ -309,23 +307,23 @@
     // Supportive methods
     // -------------------------------------------------------------------------
     
-    private List<IdentifiableObject> getDimensionOptions( String dimension, List<String> options, I18nFormat format )
+    private Dimension getDimension( String dimension, List<String> options, I18nFormat format )
     {
         if ( INDICATOR_DIM_ID.equals( dimension ) )
         {
-            return asList( indicatorService.getIndicatorsByUid( options ) );
+            return new Dimension( dimension, DimensionType.INDICATOR, asList( indicatorService.getIndicatorsByUid( options ) ) );
         }
         else if ( DATAELEMENT_DIM_ID.equals( dimension ) )
         {
-            return asList( dataElementService.getDataElementsByUid( options ) );
+            return new Dimension( dimension, DimensionType.DATAELEMENT, asList( dataElementService.getDataElementsByUid( options ) ) );
         }
         else if ( DATASET_DIM_ID.equals( dimension ) )
         {
-            return asList( dataSetService.getDataSetsByUid( options ) );
+            return new Dimension( dimension, DimensionType.DATASET, asList( dataSetService.getDataSetsByUid( options ) ) );
         }
         else if ( ORGUNIT_DIM_ID.equals( dimension ) )
         {
-            return asList( organisationUnitService.getOrganisationUnitsByUid( options ) );
+            return new Dimension( dimension, DimensionType.ORGANISATIONUNIT, asList( organisationUnitService.getOrganisationUnitsByUid( options ) ) );
         }
         else if ( PERIOD_DIM_ID.equals( dimension ) )
         {
@@ -350,21 +348,21 @@
                 }
             }
             
-            return list;
+            return new Dimension( dimension, DimensionType.PERIOD, list );
         }
         
         OrganisationUnitGroupSet orgUnitGroupSet = organisationUnitGroupService.getOrganisationUnitGroupSet( dimension );
             
         if ( orgUnitGroupSet != null )
         {
-            return asList( organisationUnitGroupService.getOrganisationUnitGroupsByUid( options ) );
+            return new Dimension( dimension, DimensionType.ORGANISATIONUNIT_GROUPSET, asList( organisationUnitGroupService.getOrganisationUnitGroupsByUid( options ) ) );
         }
         
         DataElementGroupSet dataElementGroupSet = dataElementService.getDataElementGroupSet( dimension );
         
         if ( dataElementGroupSet != null )
         {
-            return asList( dataElementService.getDataElementGroupsByUid( options ) );
+            return new Dimension( dimension, DimensionType.DATAELEMENT_GROUPSET, asList( dataElementService.getDataElementGroupsByUid( options ) ) );
         }
         
         return null;

=== 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	2013-01-17 17:49:13 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultQueryPlanner.java	2013-01-22 07:59:25 +0000
@@ -30,6 +30,7 @@
 import static org.hisp.dhis.analytics.AggregationType.AVERAGE_DISAGGREGATION;
 import static org.hisp.dhis.dataelement.DataElement.AGGREGATION_OPERATOR_AVERAGE;
 import static org.hisp.dhis.dataelement.DataElement.AGGREGATION_OPERATOR_SUM;
+import static org.hisp.dhis.analytics.DataQueryParams.*;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -37,6 +38,8 @@
 
 import org.hisp.dhis.analytics.AggregationType;
 import org.hisp.dhis.analytics.DataQueryParams;
+import org.hisp.dhis.analytics.Dimension;
+import org.hisp.dhis.analytics.DimensionType;
 import org.hisp.dhis.analytics.QueryPlanner;
 import org.hisp.dhis.analytics.table.PartitionUtils;
 import org.hisp.dhis.common.IdentifiableObject;
@@ -55,6 +58,7 @@
     implements QueryPlanner
 {
     //TODO call getLevelOrgUnitMap once
+    //TODO shortcut group by methods when only 1 option
     
     @Autowired
     private OrganisationUnitService organisationUnitService;
@@ -190,7 +194,7 @@
 
         return subQueries;
     }
-        
+    
     /**
      * Groups the given query into sub queries based on its periods and which 
      * partition it should be executed against. Sets the partition table name on
@@ -249,7 +253,7 @@
             DataQueryParams query = new DataQueryParams( params );
             query.setPeriods( periodTypePeriodMap.get( periodType ) );
             query.setPeriodType( periodType );
-            queries.add( query );            
+            queries.add( query );
         }
         
         return queries;        
@@ -354,8 +358,15 @@
         {
             if ( params.getFilterPeriods() != null && !params.getFilterPeriods().isEmpty() )
             {
-                params.getFilters().putAll( getPeriodTypePeriodMap( params.getFilterPeriods() ) );
-                params.getFilters().remove( DataQueryParams.PERIOD_DIM_ID );
+                ListMap<String, IdentifiableObject> map = getPeriodTypePeriodMap( params.getFilterPeriods() );
+
+                params.getFilters().remove( new Dimension( PERIOD_DIM_ID ) );
+                
+                for ( String periodType : map.keySet() )
+                {
+                    params.getFilters().add( new Dimension( PERIOD_DIM_ID, DimensionType.PERIOD, map.get( periodType ) ) );
+                    params.setPeriodType( periodType );
+                }                
             }
         }
         
@@ -372,8 +383,15 @@
         {
             if ( params.getFilterOrganisationUnits() != null && !params.getFilterOrganisationUnits().isEmpty() )
             {
-                params.getFilters().putAll( getLevelColumnOrgUnitMap( params.getFilterOrganisationUnits() ) );
-                params.getFilters().remove( DataQueryParams.ORGUNIT_DIM_ID );
+                ListMap<Integer, IdentifiableObject> map = getLevelColumnOrgUnitMap( params.getFilterOrganisationUnits() );
+                
+                params.getFilters().remove( new Dimension( ORGUNIT_DIM_ID ) );
+                
+                for ( Integer level : map.keySet() )
+                {
+                    params.getFilters().add( new Dimension( ORGUNIT_DIM_ID, DimensionType.ORGANISATIONUNIT, map.get( level ) ) );
+                    params.setOrganisationUnitLevel( level );
+                }
             }
         }
         
@@ -419,15 +437,15 @@
      * Creates a mapping between the level column and organisation unit for the 
      * given organisation units.
      */
-    private ListMap<String, IdentifiableObject> getLevelColumnOrgUnitMap( Collection<IdentifiableObject> orgUnits )
+    private ListMap<Integer, IdentifiableObject> getLevelColumnOrgUnitMap( Collection<IdentifiableObject> orgUnits )
     {
-        ListMap<String, IdentifiableObject> map = new ListMap<String, IdentifiableObject>();
+        ListMap<Integer, IdentifiableObject> map = new ListMap<Integer, IdentifiableObject>();
         
         for ( IdentifiableObject orgUnit : orgUnits )
         {
             int level = organisationUnitService.getLevelOfOrganisationUnit( ((OrganisationUnit) orgUnit).getUid() );
             
-            map.putValue( DataQueryParams.LEVEL_PREFIX + level, orgUnit );
+            map.putValue( level, orgUnit );
         }
         
         return map;

=== modified file 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/JdbcAnalyticsManager.java'
--- dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/JdbcAnalyticsManager.java	2013-01-18 14:18:49 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/JdbcAnalyticsManager.java	2013-01-22 07:59:25 +0000
@@ -30,11 +30,12 @@
 import static org.hisp.dhis.analytics.AggregationType.AVERAGE_AGGREGATION;
 import static org.hisp.dhis.analytics.AggregationType.AVERAGE_DISAGGREGATION;
 import static org.hisp.dhis.analytics.AggregationType.COUNT_AGGREGATION;
-import static org.hisp.dhis.analytics.DataQueryParams.*;
-import static org.hisp.dhis.system.util.TextUtils.getCommaDelimitedString;
+import static org.hisp.dhis.analytics.DataQueryParams.DIMENSION_SEP;
+import static org.hisp.dhis.analytics.DataQueryParams.VALUE_ID;
+import static org.hisp.dhis.common.IdentifiableObjectUtils.getUids;
 import static org.hisp.dhis.system.util.TextUtils.getQuotedCommaDelimitedString;
-import static org.hisp.dhis.common.IdentifiableObjectUtils.*;
 
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -46,6 +47,7 @@
 import org.apache.commons.logging.LogFactory;
 import org.hisp.dhis.analytics.AnalyticsManager;
 import org.hisp.dhis.analytics.DataQueryParams;
+import org.hisp.dhis.analytics.Dimension;
 import org.hisp.dhis.common.IdentifiableObject;
 import org.hisp.dhis.period.Period;
 import org.hisp.dhis.period.PeriodType;
@@ -85,14 +87,15 @@
     {
         ListMap<IdentifiableObject, IdentifiableObject> dataPeriodAggregationPeriodMap = params.getDataPeriodAggregationPeriodMap();
         params.replaceAggregationPeriodsWithDataPeriods( dataPeriodAggregationPeriodMap );
+
+        params.populateDimensionNames();
         
-        List<String> selectDimensions = params.getSelectDimensionNames();
-        List<String> queryDimensions = params.getQueryDimensionNames();
-        Map<String, List<IdentifiableObject>> dimensionMap = params.getDimensionMap();
+        List<Dimension> selectDimensions = params.getSelectDimensions();
+        List<Dimension> queryDimensions = params.getQueryDimensions();
         
         SqlHelper sqlHelper = new SqlHelper();
         
-        String sql = "select " + getCommaDelimitedString( selectDimensions ) + ", ";
+        String sql = "select " + getCommaDelimitedString( selectDimensions ) + ", "; //TODO
         
         int days = PeriodType.getPeriodTypeByName( params.getPeriodType() ).getFrequencyOrder();
         
@@ -111,14 +114,14 @@
         
         sql += " as value from " + params.getTableName() + " ";
         
-        for ( String dim : queryDimensions )
+        for ( Dimension dim : queryDimensions )
         {
-            sql += sqlHelper.whereAnd() + " " + dim + " in (" + getQuotedCommaDelimitedString( getUids( dimensionMap.get( dim ) ) ) + " ) ";
+            sql += sqlHelper.whereAnd() + " " + dim.getDimensionName() + " in (" + getQuotedCommaDelimitedString( getUids( dim.getOptions() ) ) + " ) ";
         }
 
-        for ( String filter : params.getFilterNames() )
+        for ( Dimension filter : params.getFilters() )
         {
-            sql += sqlHelper.whereAnd() + " " + filter + " in (" + getQuotedCommaDelimitedString( getUids( params.getFilters().get( filter ) ) ) + " ) ";
+            sql += sqlHelper.whereAnd() + " " + filter.getDimensionName() + " in (" + getQuotedCommaDelimitedString( getUids( filter.getOptions() ) ) + " ) ";
         }
         
         sql += "group by " + getCommaDelimitedString( selectDimensions );
@@ -133,9 +136,9 @@
         {
             StringBuilder key = new StringBuilder();
             
-            for ( String dim : selectDimensions )
+            for ( Dimension dim : selectDimensions )
             {
-                key.append( rowSet.getString( dim ) + DIMENSION_SEP );
+                key.append( rowSet.getString( dim.getDimensionName() ) + DIMENSION_SEP );
             }
             
             key.deleteCharAt( key.length() - 1 );
@@ -181,4 +184,21 @@
             }
         }
     }
+    
+    private static String getCommaDelimitedString( Collection<Dimension> dimensions )
+    {
+        final StringBuilder builder = new StringBuilder();
+        
+        if ( dimensions != null && !dimensions.isEmpty() )
+        {
+            for ( Dimension dimension : dimensions )
+            {
+                builder.append( dimension.getDimensionName() ).append( "," );
+            }
+            
+            return builder.substring( 0, builder.length() - 1 );
+        }
+        
+        return builder.toString();
+    }
 }

=== 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	2013-01-13 13:49:33 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/test/java/org/hisp/dhis/analytics/data/AnalyticsServiceTest.java	2013-01-22 07:59:25 +0000
@@ -136,7 +136,7 @@
         assertEquals( 3, params.getPeriods().size() );
         assertEquals( 5, params.getFilterOrganisationUnits().size() );
         
-        assertEquals( 4, params.getDimensionMap().get( DataQueryParams.DATAELEMENT_DIM_ID ).size() );
-        assertEquals( 3, params.getDimensionMap().get( ouGroupSetA.getUid() ).size() );
+        assertEquals( 4, params.getDataElements().size() );
+        assertEquals( 3, params.getDimensionOptions( ouGroupSetA.getUid() ).size() );
     }
 }

=== modified file 'dhis-2/dhis-services/dhis-service-analytics/src/test/java/org/hisp/dhis/analytics/data/QueryPlannerTest.java'
--- dhis-2/dhis-services/dhis-service-analytics/src/test/java/org/hisp/dhis/analytics/data/QueryPlannerTest.java	2013-01-17 17:49:13 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/test/java/org/hisp/dhis/analytics/data/QueryPlannerTest.java	2013-01-22 07:59:25 +0000
@@ -44,6 +44,7 @@
 
 import org.hisp.dhis.DhisSpringTest;
 import org.hisp.dhis.analytics.DataQueryParams;
+import org.hisp.dhis.analytics.Dimension;
 import org.hisp.dhis.analytics.DimensionOption;
 import org.hisp.dhis.analytics.QueryPlanner;
 import org.hisp.dhis.common.IdentifiableObject;
@@ -126,6 +127,33 @@
     // -------------------------------------------------------------------------
     // Tests
     // -------------------------------------------------------------------------
+
+    @Test
+    public void testSetGetCopy()
+    {
+        List<IdentifiableObject> desA = getList( deA, deB );
+        List<IdentifiableObject> ousA = getList( ouA, ouB );
+        List<IdentifiableObject> ousB = getList( ouC, ouD );
+        List<IdentifiableObject> pesA = getList( createPeriod( "2000Q1" ), createPeriod( "2000Q2" ) );
+        List<IdentifiableObject> pesB = getList( createPeriod( "200001" ), createPeriod( "200002" ) );
+        
+        DataQueryParams paramsA = new DataQueryParams();
+        paramsA.setDataElements( desA );
+        paramsA.setOrganisationUnits( ousA );
+        paramsA.setPeriods( pesA );
+        
+        DataQueryParams paramsB = new DataQueryParams( paramsA );
+        paramsB.setOrganisationUnits( ousB );
+        paramsB.setPeriods( pesB );
+        
+        assertEquals( desA, paramsA.getDataElements() );
+        assertEquals( ousA, paramsA.getOrganisationUnits() );
+        assertEquals( pesA, paramsA.getPeriods() );
+        
+        assertEquals( desA, paramsB.getDataElements() );
+        assertEquals( ousB, paramsB.getOrganisationUnits() );
+        assertEquals( pesB, paramsB.getPeriods() );
+    }
     
     @Test
     public void testGetPermutationOperandValueMap()
@@ -211,8 +239,8 @@
         {
             assertNotNull( permutation );
             assertEquals( 2, permutation.size() );
-            assertEquals( PERIOD_DIM_ID, permutation.get( 0 ).getDimension() );
-            assertEquals( ORGUNIT_DIM_ID, permutation.get( 1 ).getDimension() );
+            assertEquals( ORGUNIT_DIM_ID, permutation.get( 0 ).getDimension() );
+            assertEquals( PERIOD_DIM_ID, permutation.get( 1 ).getDimension() );
         }
     }
     
@@ -266,6 +294,7 @@
         {
             assertTrue( samePeriodType( query.getPeriods() ) );
             assertTrue( samePartition( query.getPeriods() ) );
+            assertDimensionNameNotNull( query );
         }
     }
     
@@ -290,6 +319,7 @@
         {
             assertTrue( samePeriodType( query.getPeriods() ) );
             assertTrue( samePartition( query.getPeriods() ) );
+            assertDimensionNameNotNull( query );
         }
     }
     
@@ -328,6 +358,7 @@
         {
             assertTrue( samePeriodType( query.getPeriods() ) );
             assertTrue( samePartition( query.getPeriods() ) );
+            assertDimensionNameNotNull( query );
         }
     }
     
@@ -351,6 +382,7 @@
         {
             assertTrue( samePeriodType( query.getPeriods() ) );
             assertTrue( samePartition( query.getPeriods() ) );
+            assertDimensionNameNotNull( query );
         }
     }
     
@@ -373,6 +405,7 @@
         {
             assertTrue( samePeriodType( query.getPeriods() ) );
             assertTrue( samePartition( query.getPeriods() ) );
+            assertDimensionNameNotNull( query );
         }
     }
 
@@ -395,6 +428,7 @@
         {
             assertTrue( samePeriodType( query.getPeriods() ) );
             assertTrue( samePartition( query.getPeriods() ) );
+            assertDimensionNameNotNull( query );
         }
     }
     
@@ -427,6 +461,13 @@
         List<DataQueryParams> queries = queryPlanner.planQuery( params, 4, ANALYTICS_TABLE_NAME );
         
         assertEquals( 4, queries.size() );
+
+        for ( DataQueryParams query : queries )
+        {
+            assertTrue( samePeriodType( query.getFilterPeriods() ) );
+            assertTrue( samePartition( query.getFilterPeriods() ) );
+            assertDimensionNameNotNull( query );
+        }
     }
 
     /**
@@ -445,6 +486,13 @@
         List<DataQueryParams> queries = queryPlanner.planQuery( params, 4, ANALYTICS_TABLE_NAME );
         
         assertEquals( 6, queries.size() );
+
+        for ( DataQueryParams query : queries )
+        {
+            assertTrue( samePeriodType( query.getPeriods() ) );
+            assertTrue( samePartition( query.getPeriods() ) );
+            assertDimensionNameNotNull( query );
+        }
     }
     
     // -------------------------------------------------------------------------
@@ -488,4 +536,17 @@
         
         return true;
     }
+    
+    private static void assertDimensionNameNotNull( DataQueryParams params )
+    {
+        for ( Dimension dim : params.getDimensions() )
+        {
+            assertNotNull( dim.getDimensionName() );
+        }
+        
+        for ( Dimension filter : params.getFilters() )
+        {
+            assertNotNull( filter.getDimensionName() );
+        }
+    }
 }

=== modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/AnalyticsController.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/AnalyticsController.java	2013-01-17 14:26:35 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/AnalyticsController.java	2013-01-22 07:59:25 +0000
@@ -33,6 +33,7 @@
 
 import org.hisp.dhis.analytics.AnalyticsService;
 import org.hisp.dhis.analytics.DataQueryParams;
+import org.hisp.dhis.analytics.Dimension;
 import org.hisp.dhis.api.utils.ContextUtils;
 import org.hisp.dhis.api.utils.ContextUtils.CacheStrategy;
 import org.hisp.dhis.common.Grid;
@@ -45,6 +46,8 @@
 import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.RequestParam;
 
+import static org.hisp.dhis.analytics.DataQueryParams.*;
+
 @Controller
 public class AnalyticsController
 {
@@ -171,7 +174,7 @@
             return false;
         }
         
-        if ( params.getFilterNames() != null && params.getFilterNames().contains( DataQueryParams.INDICATOR_DIM_ID ) )
+        if ( params.getFilters() != null && params.getFilters().contains( new Dimension( INDICATOR_DIM_ID ) ) )
         {
             ContextUtils.conflictResponse( response, "Indicators cannot be specified as filter" );
             return false;

=== modified file 'dhis-2/dhis-web/dhis-web-dashboard-integration/src/main/webapp/dhis-web-dashboard-integration/profile.vm'
--- dhis-2/dhis-web/dhis-web-dashboard-integration/src/main/webapp/dhis-web-dashboard-integration/profile.vm	2013-01-09 06:50:45 +0000
+++ dhis-2/dhis-web/dhis-web-dashboard-integration/src/main/webapp/dhis-web-dashboard-integration/profile.vm	2013-01-22 11:51:56 +0000
@@ -42,7 +42,7 @@
 	<span class="bold">$i18n.getString( "latest_interpretations" )</span> |
     <span>$i18n.getString( "share_your_own_interpretations_from" ) 
     <a href="../dhis-web-visualizer/app/index.html">$i18n.getString( "data_visualizer" )</a>,
-    <a href="../dhis-web-mapping/app/index.html">$i18n.getString( "gis" )</a>&nsbp;$i18n.getString( "or" )&nsbp;
+    <a href="../dhis-web-mapping/app/index.html">$i18n.getString( "gis" )</a>&nbsp;$i18n.getString( "or" )&nbsp;
     <a href="../dhis-web-reporting/displayManageTableForm.action">$i18n.getString( "report_table" )</a></span>
 </div>
 <div id="profileInterpretationFeed"></div>
\ No newline at end of file