← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 897: Added objects DataElementGroupSet and IndicatorGroupSet. Added methods List<? extends DimensionOp...

 

------------------------------------------------------------
revno: 897
committer: Lars Helge Oeverland larshelge@xxxxxxxxx
branch nick: trunk
timestamp: Wed 2009-10-21 20:41:33 +0200
message:
  Added objects DataElementGroupSet and IndicatorGroupSet. Added methods List<? extends DimensionOption> getDimensionOptions() and DimensionOption getDimensionOption( Object ) to interface Dimension. Implemented those methods in DataElement, Period, Source, DataElementGroupSet and IndicatorGroupSet. Implemented method getDimensions( DataElement ) in DataValue. Made the association between CategoryOption and CategoryOptionCombo bi-directional.
added:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementGroupSet.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/indicator/IndicatorGroupSet.java
  dhis-2/dhis-api/src/test/java/org/hisp/dhis/dataelement/DimensionTest.java
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/Dimension.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/DimensionOption.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElement.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementCategory.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementCategoryOption.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/datavalue/DataValue.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/indicator/Indicator.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/period/Period.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/source/Source.java
  dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/dataelement/hibernate/DataElementCategoryOption.hbm.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/common/Dimension.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/Dimension.java	2009-10-16 15:31:26 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/Dimension.java	2009-10-21 18:41:33 +0000
@@ -27,7 +27,16 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+import java.util.List;
+
+/**
+ * @author Lars Helge Overland
+ */
 public interface Dimension
 {
     String getName();
+    
+    List<? extends DimensionOption> getDimensionOptions();
+    
+    DimensionOption getDimensionOption( Object object );
 }

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/DimensionOption.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/DimensionOption.java	2009-10-16 15:31:26 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/DimensionOption.java	2009-10-21 18:41:33 +0000
@@ -27,6 +27,9 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+/**
+ * @author Lars Helge Overland
+ */
 public interface DimensionOption
 {
     String getName();

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElement.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElement.java	2009-10-16 15:31:26 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElement.java	2009-10-21 18:41:33 +0000
@@ -123,6 +123,11 @@
      */
     private List<Integer> aggregationLevels = new ArrayList<Integer>();
     
+    /**
+     * A Set of DataElementGroupSets.
+     */
+    private Set<DataElementGroupSet> groupSets = new HashSet<DataElementGroupSet>();
+    
     // -------------------------------------------------------------------------
     // Constructors
     // -------------------------------------------------------------------------
@@ -131,17 +136,72 @@
     {
     }
     
+    public DataElement( String name )
+    {
+        this.name = name;
+    }
+    
     // -------------------------------------------------------------------------
     // Dimension
     // -------------------------------------------------------------------------
 
-    public static final Dimension DIMENSION = new Dimension()
+    public static Dimension DIMENSION = new DataElementDimension();
+    
+    public static class DataElementDimension
+        implements Dimension
     {
+        private static final String NAME = "DataElement";
+        
         public String getName()
         {
-            return "DataElement";
-        }
-    };
+            return NAME;
+        }
+        
+        public List<? extends DimensionOption> getDimensionOptions()
+        {
+            return null;
+        }
+
+        public DimensionOption getDimensionOption( Object object )
+        {
+            return null;
+        }
+        
+        @Override
+        public boolean equals( Object o )
+        {
+            if ( this == o )
+            {
+                return true;
+            }
+            
+            if ( o == null )
+            {
+                return false;
+            }
+            
+            if ( !( o instanceof DataElementDimension ) )
+            {
+                return false;
+            }
+            
+            final DataElementDimension other = (DataElementDimension) o;
+            
+            return NAME.equals( other.getName() );
+        }
+        
+        @Override
+        public int hashCode()
+        {
+            return NAME.hashCode();
+        }
+
+        @Override
+        public String toString()
+        {
+            return "[" + NAME + "]";
+        }
+    }
     
     // -------------------------------------------------------------------------
     // hashCode, equals and toString
@@ -364,4 +424,14 @@
     {
         this.aggregationLevels = aggregationLevels;
     }
+
+    public Set<DataElementGroupSet> getGroupSets()
+    {
+        return groupSets;
+    }
+
+    public void setGroupSets( Set<DataElementGroupSet> groupSets )
+    {
+        this.groupSets = groupSets;
+    }
 }

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementCategory.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementCategory.java	2009-10-16 15:31:26 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementCategory.java	2009-10-21 18:41:33 +0000
@@ -31,6 +31,7 @@
 import java.util.List;
 
 import org.hisp.dhis.common.Dimension;
+import org.hisp.dhis.common.DimensionOption;
 import org.hisp.dhis.common.IdentifiableObject;
 
 
@@ -47,8 +48,7 @@
     extends IdentifiableObject implements Dimension
 {
     public static final String DEFAULT_NAME = "default";
-    
-    
+        
     private List<DataElementCategoryOption> categoryOptions = new ArrayList<DataElementCategoryOption>();
 
     // -------------------------------------------------------------------------
@@ -69,6 +69,28 @@
         this.name = name;
         this.categoryOptions = categoryOptions;
     }
+
+    // -------------------------------------------------------------------------
+    // Dimension
+    // -------------------------------------------------------------------------
+    
+    public List<DataElementCategoryOption> getDimensionOptions()
+    {
+        return categoryOptions;
+    }
+    
+    public DimensionOption getDimensionOption( Object object )
+    {
+        for ( DataElementCategoryOption categoryOption : categoryOptions )
+        {
+            if ( categoryOption.getCategoryOptionCombos().contains( object ) )
+            {
+                return categoryOption;
+            }
+        }
+        
+        return null;
+    }
     
     // -------------------------------------------------------------------------
     // hashCode, equals and toString

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementCategoryOption.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementCategoryOption.java	2009-10-16 15:31:26 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementCategoryOption.java	2009-10-21 18:41:33 +0000
@@ -27,6 +27,9 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+import java.util.ArrayList;
+import java.util.List;
+
 import org.hisp.dhis.common.DimensionOption;
 import org.hisp.dhis.common.IdentifiableObject;
 
@@ -41,6 +44,8 @@
     
     private DataElementCategory category;
     
+    private List<DataElementCategoryOptionCombo> categoryOptionCombos = new ArrayList<DataElementCategoryOptionCombo>();
+    
     // -------------------------------------------------------------------------
     // Constructors
     // -------------------------------------------------------------------------
@@ -115,4 +120,14 @@
     {
         this.category = category;
     }
+
+    public List<DataElementCategoryOptionCombo> getCategoryOptionCombos()
+    {
+        return categoryOptionCombos;
+    }
+
+    public void setCategoryOptionCombos( List<DataElementCategoryOptionCombo> categoryOptionCombos )
+    {
+        this.categoryOptionCombos = categoryOptionCombos;
+    }
 }

=== added file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementGroupSet.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementGroupSet.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementGroupSet.java	2009-10-21 18:41:33 +0000
@@ -0,0 +1,138 @@
+package org.hisp.dhis.dataelement;
+
+/*
+ * Copyright (c) 2004-2007, 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.Dimension;
+import org.hisp.dhis.common.DimensionOption;
+import org.hisp.dhis.common.IdentifiableObject;
+
+/**
+ * DataElementGroupSet is a set of DataElementGroups. It is by default exclusive,
+ * in the sense that a DataElement can only be a member of one or zero of the 
+ * DataElementGroups in a DataElementGroupSet.
+ * 
+ * @author Lars Helge Overland
+ */
+public class DataElementGroupSet
+    extends IdentifiableObject
+    implements Dimension
+{
+    private List<DataElementGroup> members = new ArrayList<DataElementGroup>();
+
+    // -------------------------------------------------------------------------
+    // Constructors
+    // -------------------------------------------------------------------------
+
+    public DataElementGroupSet()
+    {   
+    }
+    
+    public DataElementGroupSet( String name )
+    {
+        this.name = name;
+    }
+
+    // -------------------------------------------------------------------------
+    // Dimension
+    // -------------------------------------------------------------------------
+
+    public List<? extends DimensionOption> getDimensionOptions()
+    {
+        return members;
+    }
+    
+    public DimensionOption getDimensionOption( Object object )
+    {
+        for ( DataElementGroup group : members )
+        {
+            System.out.println( "group: " + group + " object " + object );
+            if ( group.getMembers().contains( object ) )
+            {
+                return group;
+            }
+        }
+        
+        return null;
+    }
+    
+    // -------------------------------------------------------------------------
+    // equals and hashCode
+    // -------------------------------------------------------------------------
+
+    @Override
+    public int hashCode()
+    {
+        return name.hashCode();
+    }
+
+    @Override
+    public boolean equals( Object o )
+    {
+        if ( this == o )
+        {
+            return true;
+        }
+
+        if ( o == null )
+        {
+            return false;
+        }
+
+        if ( !( o instanceof DataElementGroupSet ) )
+        {
+            return false;
+        }
+
+        final DataElementGroupSet other = (DataElementGroupSet) o;
+
+        return name.equals( other.getName() );
+    }
+
+    @Override
+    public String toString()
+    {
+        return "[" + name + "]";
+    }
+
+    // -------------------------------------------------------------------------
+    // Getters and setters
+    // -------------------------------------------------------------------------
+
+    public List<DataElementGroup> getMembers()
+    {
+        return members;
+    }
+
+    public void setMembers( List<DataElementGroup> members )
+    {
+        this.members = members;
+    }    
+}

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/datavalue/DataValue.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/datavalue/DataValue.java	2009-10-16 19:36:39 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/datavalue/DataValue.java	2009-10-21 18:41:33 +0000
@@ -37,6 +37,7 @@
 import org.hisp.dhis.dataelement.DataElementCategoryOption;
 import org.hisp.dhis.dataelement.DataElementCategoryOptionCombo;
 import org.hisp.dhis.dataelement.DataElement;
+import org.hisp.dhis.dataelement.DataElementGroupSet;
 import org.hisp.dhis.period.Period;
 import org.hisp.dhis.source.Source;
 
@@ -141,7 +142,7 @@
     }
 
     // -------------------------------------------------------------------------
-    // Logic
+    // Dimension
     // -------------------------------------------------------------------------
 
     public Map<Dimension, DimensionOption> getDimensions()
@@ -152,7 +153,7 @@
         dimensions.put( Period.DIMENSION, period );
         dimensions.put( Source.DIMENSION, source );
         
-        if ( !optionCombo.isDefault() )
+        if ( optionCombo != null && !optionCombo.isDefault() )
         {
             for ( DataElementCategoryOption categoryOption : optionCombo.getCategoryOptions() )
             {
@@ -163,6 +164,18 @@
         return dimensions;
     }
     
+    public Map<Dimension, DimensionOption> getDimensions( DataElement dataElement )
+    {
+        Map<Dimension, DimensionOption> dimensions = getDimensions();
+                
+        for ( DataElementGroupSet groupSet : dataElement.getGroupSets() )
+        {
+            dimensions.put( groupSet, groupSet.getDimensionOption( this.dataElement ) );
+        }
+        
+        return dimensions;
+    }
+    
     // -------------------------------------------------------------------------
     // hashCode and equals
     // -------------------------------------------------------------------------

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/indicator/Indicator.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/indicator/Indicator.java	2009-10-15 17:28:51 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/indicator/Indicator.java	2009-10-21 18:41:33 +0000
@@ -27,6 +27,9 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+import java.util.HashSet;
+import java.util.Set;
+
 import org.hisp.dhis.common.IdentifiableObject;
 import org.hisp.dhis.datadictionary.ExtendedDataElement;
 
@@ -59,6 +62,8 @@
 
     private String url;
         
+    private Set<IndicatorGroupSet> groupSets = new HashSet<IndicatorGroupSet>();
+    
     // -------------------------------------------------------------------------
     // Constructors
     // -------------------------------------------------------------------------
@@ -239,4 +244,14 @@
     {
         this.url = url;
     }
+
+    public Set<IndicatorGroupSet> getGroupSets()
+    {
+        return groupSets;
+    }
+
+    public void setGroupSets( Set<IndicatorGroupSet> groupSets )
+    {
+        this.groupSets = groupSets;
+    }
 }

=== added file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/indicator/IndicatorGroupSet.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/indicator/IndicatorGroupSet.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/indicator/IndicatorGroupSet.java	2009-10-21 18:41:33 +0000
@@ -0,0 +1,137 @@
+package org.hisp.dhis.indicator;
+
+/*
+ * Copyright (c) 2004-2007, 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.Dimension;
+import org.hisp.dhis.common.DimensionOption;
+import org.hisp.dhis.common.IdentifiableObject;
+
+/**
+ * An IndicatorGroupSet is a set of IndicatorGroups. It is by default exclusive,
+ * in the sense that an Indicator can only be a member of one or zero of the
+ * IndicatorGroups in a IndicatorGroupSet. 
+ * 
+ * @author Lars Helge Overland
+ */
+public class IndicatorGroupSet
+    extends IdentifiableObject
+    implements Dimension
+{
+    private List<IndicatorGroup> members = new ArrayList<IndicatorGroup>();
+
+    // -------------------------------------------------------------------------
+    // Constructors
+    // -------------------------------------------------------------------------
+
+    public IndicatorGroupSet()
+    {   
+    }
+
+    public IndicatorGroupSet( String name )
+    {
+        this.name = name;
+    }
+
+    // -------------------------------------------------------------------------
+    // equals and hashCode
+    // -------------------------------------------------------------------------
+
+    @Override
+    public int hashCode()
+    {
+        return name.hashCode();
+    }
+
+    @Override
+    public boolean equals( Object o )
+    {
+        if ( this == o )
+        {
+            return true;
+        }
+
+        if ( o == null )
+        {
+            return false;
+        }
+
+        if ( !( o instanceof IndicatorGroupSet ) )
+        {
+            return false;
+        }
+
+        final IndicatorGroupSet other = (IndicatorGroupSet) o;
+
+        return name.equals( other.getName() );
+    }
+
+    @Override
+    public String toString()
+    {
+        return "[" + name + "]";
+    }
+
+    // -------------------------------------------------------------------------
+    // Dimension
+    // -------------------------------------------------------------------------
+
+    public List<? extends DimensionOption> getDimensionOptions()
+    {
+        return members;
+    }
+    
+    public DimensionOption getDimensionOption( Object object )
+    {        
+        for ( IndicatorGroup group : members )
+        {
+            if ( group.getMembers().contains( object ) )
+            {
+                return group;
+            }
+        }
+        
+        return null;
+    }
+    
+    // -------------------------------------------------------------------------
+    // Getters and setters
+    // -------------------------------------------------------------------------
+
+    public List<IndicatorGroup> getMembers()
+    {
+        return members;
+    }
+
+    public void setMembers( List<IndicatorGroup> members )
+    {
+        this.members = members;
+    }    
+}

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/period/Period.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/period/Period.java	2009-10-16 15:31:26 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/period/Period.java	2009-10-21 18:41:33 +0000
@@ -29,6 +29,7 @@
 
 import java.io.Serializable;
 import java.util.Date;
+import java.util.List;
 
 import org.hisp.dhis.common.Dimension;
 import org.hisp.dhis.common.DimensionOption;
@@ -81,13 +82,63 @@
     // Dimension
     // -------------------------------------------------------------------------
 
-    public static final Dimension DIMENSION = new Dimension()
+    public static Dimension DIMENSION = new PeriodDimension();
+    
+    public static class PeriodDimension
+        implements Dimension
     {
+        private static final String NAME = "Period";
+        
         public String getName()
         {
-            return "Period";
-        }
-    };
+            return NAME;
+        }
+        
+        public List<? extends DimensionOption> getDimensionOptions()
+        {
+            return null;
+        }
+        
+        public DimensionOption getDimensionOption( Object object )
+        {
+            return null;
+        }
+        
+        @Override
+        public boolean equals( Object o )
+        {
+            if ( this == o )
+            {
+                return true;
+            }
+            
+            if ( o == null )
+            {
+                return false;
+            }
+            
+            if ( !( o instanceof PeriodDimension ) )
+            {
+                return false;
+            }
+            
+            final PeriodDimension other = (PeriodDimension) o;
+            
+            return NAME.equals( other.getName() );
+        }
+        
+        @Override
+        public int hashCode()
+        {
+            return NAME.hashCode();
+        }
+
+        @Override
+        public String toString()
+        {
+            return "[" + NAME + "]";
+        }
+    }
     
     // -------------------------------------------------------------------------
     // hashCode, equals and toString

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/source/Source.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/source/Source.java	2009-10-16 15:31:26 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/source/Source.java	2009-10-21 18:41:33 +0000
@@ -28,6 +28,7 @@
  */
 
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 
 import org.hisp.dhis.common.Dimension;
@@ -48,13 +49,63 @@
     // Dimension
     // -------------------------------------------------------------------------
 
-    public static final Dimension DIMENSION = new Dimension()
+    public static Dimension DIMENSION = new SourceDimension();
+    
+    public static class SourceDimension
+        implements Dimension
     {
+        private static final String NAME = "Source";
+        
         public String getName()
         {
-            return "Source";
-        }
-    };
+            return NAME;
+        }
+        
+        public List<? extends DimensionOption> getDimensionOptions()
+        {
+            return null;
+        }
+
+        public DimensionOption getDimensionOption( Object object )
+        {
+            return null;
+        }
+        
+        @Override
+        public boolean equals( Object o )
+        {
+            if ( this == o )
+            {
+                return true;
+            }
+            
+            if ( o == null )
+            {
+                return false;
+            }
+            
+            if ( !( o instanceof SourceDimension ) )
+            {
+                return false;
+            }
+            
+            final SourceDimension other = (SourceDimension) o;
+            
+            return NAME.equals( other.getName() );
+        }
+        
+        @Override
+        public int hashCode()
+        {
+            return NAME.hashCode();
+        }
+
+        @Override
+        public String toString()
+        {
+            return "[" + NAME + "]";
+        }
+    }
     
     // -------------------------------------------------------------------------
     // hashCode, equals and toString

=== added file 'dhis-2/dhis-api/src/test/java/org/hisp/dhis/dataelement/DimensionTest.java'
--- dhis-2/dhis-api/src/test/java/org/hisp/dhis/dataelement/DimensionTest.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-api/src/test/java/org/hisp/dhis/dataelement/DimensionTest.java	2009-10-21 18:41:33 +0000
@@ -0,0 +1,109 @@
+package org.hisp.dhis.dataelement;
+
+/*
+ * Copyright (c) 2004-2007, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this
+ *   list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of the HISP project nor the names of its contributors may
+ *   be used to endorse or promote products derived from this software without
+ *   specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.util.Map;
+
+import org.hisp.dhis.common.Dimension;
+import org.hisp.dhis.common.DimensionOption;
+import org.hisp.dhis.datavalue.DataValue;
+import org.hisp.dhis.organisationunit.OrganisationUnit;
+import org.hisp.dhis.period.MonthlyPeriodType;
+import org.hisp.dhis.period.Period;
+import org.hisp.dhis.source.Source;
+import org.junit.Test;
+
+import static junit.framework.Assert.*;
+
+/**
+ * @author Lars Helge Overland
+ */
+public class DimensionTest
+{
+    @Test
+    public void testGroupSetDimensions()
+    {
+        OrganisationUnit source = new OrganisationUnit( "Bobs Clinic" );
+        Period period = new MonthlyPeriodType().createPeriod();
+        
+        DataElement hivAids = new DataElement( "HivAids" );
+        DataElement malaria = new DataElement( "Malaria" );
+        DataElement diabetes = new DataElement( "Diabetes" );
+        DataElement cancer = new DataElement( "Cancer" );
+        
+        DataElementGroup communicable = new DataElementGroup( "Communicable" );
+        DataElementGroup nonCommunicable = new DataElementGroup( "NonCommunicable" );
+        
+        DataElementGroupSet diseaseType = new DataElementGroupSet( "DiseaseType" );
+        
+        DataElement diseaseByType = new DataElement( "DiseaseByType" ); // Uber data element
+        
+        communicable.getMembers().add( hivAids );
+        communicable.getMembers().add( malaria );
+        
+        nonCommunicable.getMembers().add( diabetes );
+        nonCommunicable.getMembers().add( cancer );
+        
+        diseaseType.getMembers().add( communicable );
+        diseaseType.getMembers().add( nonCommunicable );
+        
+        diseaseByType.getGroupSets().add( diseaseType );
+        
+        DataValue dataValue = new DataValue( hivAids, period, source );
+        
+        Map<Dimension, DimensionOption> dimensions = dataValue.getDimensions( diseaseByType );
+        
+        assertEquals( 4, dimensions.size() );
+        
+        assertTrue( dimensions.keySet().contains( diseaseType ) );
+        assertTrue( dimensions.keySet().contains( DataElement.DIMENSION ) );
+        assertTrue( dimensions.keySet().contains( Period.DIMENSION ) );
+        assertTrue( dimensions.keySet().contains( Source.DIMENSION ) );
+        
+        assertTrue( dimensions.values().contains( communicable ) );
+        assertTrue( dimensions.values().contains( hivAids ) );
+        assertTrue( dimensions.values().contains( period ) );
+        assertTrue( dimensions.values().contains( source ) );
+
+        dataValue = new DataValue( diabetes, period, source );
+        
+        dimensions = dataValue.getDimensions( diseaseByType );
+        
+        assertEquals( 4, dimensions.size() );
+        
+        assertTrue( dimensions.keySet().contains( diseaseType ) );
+        assertTrue( dimensions.keySet().contains( DataElement.DIMENSION ) );
+        assertTrue( dimensions.keySet().contains( Period.DIMENSION ) );
+        assertTrue( dimensions.keySet().contains( Source.DIMENSION ) );
+        
+        assertTrue( dimensions.values().contains( nonCommunicable ) );
+        assertTrue( dimensions.values().contains( diabetes ) );
+        assertTrue( dimensions.values().contains( period ) );
+        assertTrue( dimensions.values().contains( source ) );
+    }
+}

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/dataelement/hibernate/DataElementCategoryOption.hbm.xml'
--- dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/dataelement/hibernate/DataElementCategoryOption.hbm.xml	2009-10-16 13:09:18 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/dataelement/hibernate/DataElementCategoryOption.hbm.xml	2009-10-21 18:41:33 +0000
@@ -9,12 +9,19 @@
     <id name="id" column="categoryoptionid">
       <generator class="native"/>
     </id>
-        	
+        	
+    <property name="uuid" length="40"/>
+    
     <property name="name">
       <column name="name" not-null="true" length="160"/>
     </property>
     
-    <property name="uuid" length="40"/>
+    <list name="categoryOptionCombos" table="categoryoptioncombos_categoryoptions" inverse="true">
+	  <key column="categoryoptionid"/>
+      <list-index column="sort_order" base="1"/>
+	  <many-to-many class="org.hisp.dhis.dataelement.DataElementCategoryOptionCombo"
+		column="categoryoptioncomboid" foreign-key="fk_categoryoption_categoryoptioncomboid"/>
+	</list> 
     
     <join table="categories_categoryoptions" inverse="true">
       <key column="categoryoptionid"/>