← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 13994: Introduced CategoryOptionGroup and CategoryOptionGroupSet entities in the model. The purpose of t...

 

------------------------------------------------------------
revno: 13994
committer: Lars Helge Øverland <larshelge@xxxxxxxxx>
branch nick: dhis2
timestamp: Wed 2014-02-12 11:52:22 +0100
message:
  Introduced CategoryOptionGroup and CategoryOptionGroupSet entities in the model. The purpose of this is to enable further classifications of category options which can be made available in analysis. As an example, if category options represent funding mechanisms, each option can be further classified by agency and implementing partner.
added:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/CategoryOptionGroup.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/CategoryOptionGroupService.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/CategoryOptionGroupSet.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/CategoryOptionGroupSetService.java
  dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/dataelement/hibernate/CategoryOptionGroup.hbm.xml
  dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/dataelement/hibernate/CategoryOptionGroupSet.hbm.xml
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementCategoryService.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataelement/DefaultDataElementCategoryService.java
  dhis-2/dhis-services/dhis-service-core/src/main/resources/META-INF/dhis/beans.xml
  dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/dataelement/hibernate/DataElementGroupSet.hbm.xml
  dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/indicator/hibernate/IndicatorGroupSet.hbm.xml
  dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/organisationunit/hibernate/OrganisationUnitGroupSet.hbm.xml
  dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/dataelement/DataElementCategoryServiceTest.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
=== added file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/CategoryOptionGroup.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/CategoryOptionGroup.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/CategoryOptionGroup.java	2014-02-12 10:52:22 +0000
@@ -0,0 +1,88 @@
+package org.hisp.dhis.dataelement;
+
+/*
+ * Copyright (c) 2004-2013, 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.HashSet;
+import java.util.Set;
+
+import org.hisp.dhis.common.BaseNameableObject;
+import org.hisp.dhis.common.DxfNamespaces;
+import org.hisp.dhis.common.annotation.Scanned;
+
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+
+/**
+* @author Lars Helge Overland
+*/
+@JacksonXmlRootElement(localName = "categoryOptionGroup", namespace = DxfNamespaces.DXF_2_0)
+public class CategoryOptionGroup
+    extends BaseNameableObject
+{
+    @Scanned
+    private Set<DataElementCategoryOption> members = new HashSet<DataElementCategoryOption>();
+    
+    private CategoryOptionGroupSet groupSet;
+
+    // -------------------------------------------------------------------------
+    // Constructors
+    // -------------------------------------------------------------------------
+
+    public CategoryOptionGroup()
+    {
+    }
+
+    public CategoryOptionGroup( String name )
+    {
+        this.name = name;
+    }
+
+    // -------------------------------------------------------------------------
+    // Getters and setters
+    // -------------------------------------------------------------------------
+
+    public Set<DataElementCategoryOption> getMembers()
+    {
+        return members;
+    }
+
+    public void setMembers( Set<DataElementCategoryOption> members )
+    {
+        this.members = members;
+    }
+
+    public CategoryOptionGroupSet getGroupSet()
+    {
+        return groupSet;
+    }
+
+    public void setGroupSet( CategoryOptionGroupSet groupSet )
+    {
+        this.groupSet = groupSet;
+    }
+}

=== added file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/CategoryOptionGroupService.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/CategoryOptionGroupService.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/CategoryOptionGroupService.java	2014-02-12 10:52:22 +0000
@@ -0,0 +1,6 @@
+package org.hisp.dhis.dataelement;
+
+public interface CategoryOptionGroupService
+{
+
+}

=== added file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/CategoryOptionGroupSet.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/CategoryOptionGroupSet.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/CategoryOptionGroupSet.java	2014-02-12 10:52:22 +0000
@@ -0,0 +1,88 @@
+package org.hisp.dhis.dataelement;
+
+/*
+ * Copyright (c) 2004-2013, 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.BaseDimensionalObject;
+import org.hisp.dhis.common.DxfNamespaces;
+import org.hisp.dhis.common.annotation.Scanned;
+
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+
+/**
+* @author Lars Helge Overland
+*/
+@JacksonXmlRootElement(localName = "categoryOptionGroupSet", namespace = DxfNamespaces.DXF_2_0)
+public class CategoryOptionGroupSet
+    extends BaseDimensionalObject
+{
+    @Scanned
+    private List<CategoryOptionGroup> members = new ArrayList<CategoryOptionGroup>();
+    
+    private boolean dataDimension = true;
+
+    // -------------------------------------------------------------------------
+    // Constructors
+    // -------------------------------------------------------------------------
+
+    public CategoryOptionGroupSet()
+    {
+    }
+
+    public CategoryOptionGroupSet( String name )
+    {
+        this.name = name;
+    }
+
+    // -------------------------------------------------------------------------
+    // Getters and setters
+    // -------------------------------------------------------------------------
+
+    public List<CategoryOptionGroup> getMembers()
+    {
+        return members;
+    }
+
+    public void setMembers( List<CategoryOptionGroup> members )
+    {
+        this.members = members;
+    }
+
+    public boolean isDataDimension()
+    {
+        return dataDimension;
+    }
+
+    public void setDataDimension( boolean dataDimension )
+    {
+        this.dataDimension = dataDimension;
+    }
+}

=== added file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/CategoryOptionGroupSetService.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/CategoryOptionGroupSetService.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/CategoryOptionGroupSetService.java	2014-02-12 10:52:22 +0000
@@ -0,0 +1,6 @@
+package org.hisp.dhis.dataelement;
+
+public interface CategoryOptionGroupSetService
+{
+
+}

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementCategoryService.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementCategoryService.java	2014-01-07 19:29:07 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementCategoryService.java	2014-02-12 10:52:22 +0000
@@ -539,4 +539,40 @@
     Collection<DataElementCategoryCombo> getDataElementCategoryCombosBetween( int first, int max );
 
     Collection<DataElementCategoryCombo> getDataElementCategoryCombosBetweenByName( String name, int first, int max );
+
+    // -------------------------------------------------------------------------
+    // CategoryOptionGroup
+    // -------------------------------------------------------------------------
+
+    int saveCategoryOptionGroup( CategoryOptionGroup group );
+    
+    void updateCategoryOptionGroup( CategoryOptionGroup group );
+    
+    CategoryOptionGroup getCategoryOptionGroup( int id );
+    
+    CategoryOptionGroup getCategoryOptionGroup( String uid );
+    
+    void deleteCategoryOptionGroup( CategoryOptionGroup group );
+    
+    Collection<CategoryOptionGroup> getCategoryOptionGroupsBetween( int first, int max );
+    
+    Collection<CategoryOptionGroup> getCategoryOptionGroupsBetweenByName( int first, int max, String name );
+    
+    // -------------------------------------------------------------------------
+    // CategoryOptionGroup
+    // -------------------------------------------------------------------------
+
+    int saveCategoryOptionGroupSet( CategoryOptionGroupSet group );
+    
+    void updateCategoryOptionGroupSet( CategoryOptionGroupSet group );
+    
+    CategoryOptionGroupSet getCategoryOptionGroupSet( int id );
+    
+    CategoryOptionGroupSet getCategoryOptionGroupSet( String uid );
+    
+    void deleteCategoryOptionGroupSet( CategoryOptionGroupSet group );
+    
+    Collection<CategoryOptionGroupSet> getCategoryOptionGroupSetsBetween( int first, int max );
+    
+    Collection<CategoryOptionGroupSet> getCategoryOptionGroupSetsBetweenByName( int first, int max, String name );
 }

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataelement/DefaultDataElementCategoryService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataelement/DefaultDataElementCategoryService.java	2014-01-18 14:41:38 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataelement/DefaultDataElementCategoryService.java	2014-02-12 10:52:22 +0000
@@ -42,6 +42,7 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.hisp.dhis.common.GenericDimensionalObjectStore;
+import org.hisp.dhis.common.GenericIdentifiableObjectStore;
 import org.hisp.dhis.concept.Concept;
 import org.hisp.dhis.i18n.I18nService;
 import org.hisp.dhis.system.util.Filter;
@@ -89,6 +90,20 @@
         this.categoryOptionComboStore = categoryOptionComboStore;
     }
 
+    private GenericIdentifiableObjectStore<CategoryOptionGroup> categoryOptionGroupStore;
+
+    public void setCategoryOptionGroupStore( GenericIdentifiableObjectStore<CategoryOptionGroup> categoryOptionGroupStore )
+    {
+        this.categoryOptionGroupStore = categoryOptionGroupStore;
+    }
+
+    private GenericIdentifiableObjectStore<CategoryOptionGroupSet> categoryOptionGroupSetStore;
+
+    public void setCategoryOptionGroupSetStore( GenericIdentifiableObjectStore<CategoryOptionGroupSet> categoryOptionGroupSetStore )
+    {
+        this.categoryOptionGroupSetStore = categoryOptionGroupSetStore;
+    }
+
     private DataElementService dataElementService;
 
     public void setDataElementService( DataElementService dataElementService )
@@ -742,4 +757,82 @@
     {
         return categoryOptionComboStore.getCountLikeName( name );
     }
+
+    // -------------------------------------------------------------------------
+    // CategoryOptionGroup
+    // -------------------------------------------------------------------------
+
+    public int saveCategoryOptionGroup( CategoryOptionGroup group )
+    {
+        return categoryOptionGroupStore.save( group );
+    }
+    
+    public void updateCategoryOptionGroup( CategoryOptionGroup group )
+    {
+        categoryOptionGroupStore.update( group );
+    }
+    
+    public CategoryOptionGroup getCategoryOptionGroup( int id )
+    {
+        return categoryOptionGroupStore.get( id );
+    }
+    
+    public CategoryOptionGroup getCategoryOptionGroup( String uid )
+    {
+        return categoryOptionGroupStore.getByUid( uid );
+    }
+    
+    public void deleteCategoryOptionGroup( CategoryOptionGroup group )
+    {
+        categoryOptionGroupStore.delete( group );
+    }
+    
+    public Collection<CategoryOptionGroup> getCategoryOptionGroupsBetween( int first, int max )
+    {
+        return categoryOptionGroupStore.getAllOrderedName( first, max );
+    }
+
+    public Collection<CategoryOptionGroup> getCategoryOptionGroupsBetweenByName( int first, int max, String name )
+    {
+        return categoryOptionGroupStore.getAllLikeNameOrderedName( name, first, max );
+    }
+    
+    // -------------------------------------------------------------------------
+    // CategoryOptionGroupSet
+    // -------------------------------------------------------------------------
+
+    public int saveCategoryOptionGroupSet( CategoryOptionGroupSet group )
+    {
+        return categoryOptionGroupSetStore.save( group );
+    }
+    
+    public void updateCategoryOptionGroupSet( CategoryOptionGroupSet group )
+    {
+        categoryOptionGroupSetStore.update( group );
+    }
+    
+    public CategoryOptionGroupSet getCategoryOptionGroupSet( int id )
+    {
+        return categoryOptionGroupSetStore.get( id );
+    }
+    
+    public CategoryOptionGroupSet getCategoryOptionGroupSet( String uid )
+    {
+        return categoryOptionGroupSetStore.getByUid( uid );
+    }
+    
+    public void deleteCategoryOptionGroupSet( CategoryOptionGroupSet group )
+    {
+        categoryOptionGroupSetStore.delete( group );
+    }
+    
+    public Collection<CategoryOptionGroupSet> getCategoryOptionGroupSetsBetween( int first, int max )
+    {
+        return categoryOptionGroupSetStore.getAllOrderedName( first, max );
+    }
+
+    public Collection<CategoryOptionGroupSet> getCategoryOptionGroupSetsBetweenByName( int first, int max, String name )
+    {
+        return categoryOptionGroupSetStore.getAllLikeNameOrderedName( name, first, max );
+    }
 }

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/resources/META-INF/dhis/beans.xml'
--- dhis-2/dhis-services/dhis-service-core/src/main/resources/META-INF/dhis/beans.xml	2014-02-10 08:26:08 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/resources/META-INF/dhis/beans.xml	2014-02-12 10:52:22 +0000
@@ -62,7 +62,6 @@
     <property name="periodService" ref="org.hisp.dhis.period.PeriodService" />
   </bean>
 
-    <!--@author Ovidiu Rosu <rosu.ovi@xxxxxxxxx>-->
   <bean id="org.hisp.dhis.filter.MetaDataFilterStore" class="org.hisp.dhis.metadatafilter.hibernate.HibernateMetaDataFilterStore">
     <property name="clazz" value="org.hisp.dhis.filter.MetaDataFilter" />
     <property name="sessionFactory" ref="sessionFactory" />
@@ -171,6 +170,18 @@
     <property name="cacheable" value="true" />
   </bean>
 
+  <bean id="org.hisp.dhis.dataelement.CategoryOptionGroupStore" class="org.hisp.dhis.common.hibernate.HibernateIdentifiableObjectStore">
+    <property name="clazz" value="org.hisp.dhis.dataelement.CategoryOptionGroup" />
+    <property name="sessionFactory" ref="sessionFactory" />
+    <property name="cacheable" value="true" />
+  </bean>
+
+  <bean id="org.hisp.dhis.dataelement.CategoryOptionGroupSetStore" class="org.hisp.dhis.common.hibernate.HibernateIdentifiableObjectStore">
+    <property name="clazz" value="org.hisp.dhis.dataelement.CategoryOptionGroupSet" />
+    <property name="sessionFactory" ref="sessionFactory" />
+    <property name="cacheable" value="true" />
+  </bean>
+
   <bean id="org.hisp.dhis.dataset.SectionStore" class="org.hisp.dhis.dataset.hibernate.HibernateSectionStore">
     <property name="clazz" value="org.hisp.dhis.dataset.Section" />
     <property name="sessionFactory" ref="sessionFactory" />
@@ -466,17 +477,13 @@
     <property name="systemSettingManager" ref="org.hisp.dhis.setting.SystemSettingManager" />
   </bean>
   
-  <!-- <bean id="hibernateEntityInterceptorWiring" class="org.hisp.dhis.hibernate.HibernateEventListenerWiring" /> -->
-
-  <!-- Scheduled task for data monitoring -->
-  
-  <bean id="monitoringLastDayTask" class="org.hisp.dhis.validation.scheduling.MonitoringTask" />
-
   <bean id="org.hisp.dhis.dataelement.DataElementCategoryService" class="org.hisp.dhis.dataelement.DefaultDataElementCategoryService">
     <property name="categoryStore" ref="org.hisp.dhis.dataelement.CategoryStore" />
     <property name="categoryOptionStore" ref="org.hisp.dhis.dataelement.CategoryOptionStore" />
     <property name="categoryComboStore" ref="org.hisp.dhis.dataelement.CategoryComboStore" />
     <property name="categoryOptionComboStore" ref="org.hisp.dhis.dataelement.CategoryOptionComboStore" />
+    <property name="categoryOptionGroupStore" ref="org.hisp.dhis.dataelement.CategoryOptionGroupStore" />
+    <property name="categoryOptionGroupSetStore" ref="org.hisp.dhis.dataelement.CategoryOptionGroupSetStore" />
     <property name="dataElementService" ref="org.hisp.dhis.dataelement.DataElementService" />
     <property name="i18nService" ref="org.hisp.dhis.i18n.I18nService" />
   </bean>
@@ -851,6 +858,14 @@
     <property name="localeStore" ref="org.hisp.dhis.i18n.I18nLocaleStore" />
   </bean>
 
+  <!-- 
+  <bean id="hibernateEntityInterceptorWiring" class="org.hisp.dhis.hibernate.HibernateEventListenerWiring" /> 
+  -->
+
+  <!-- Scheduled task for data monitoring -->
+  
+  <bean id="monitoringLastDayTask" class="org.hisp.dhis.validation.scheduling.MonitoringTask" />
+
   <!-- Startup routine definitions -->
 
   <bean id="org.hisp.dhis.period.PeriodTypePopulator" class="org.hisp.dhis.period.PeriodTypePopulator">

=== added file 'dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/dataelement/hibernate/CategoryOptionGroup.hbm.xml'
--- dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/dataelement/hibernate/CategoryOptionGroup.hbm.xml	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/dataelement/hibernate/CategoryOptionGroup.hbm.xml	2014-02-12 10:52:22 +0000
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+  "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+  "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd";
+  [<!ENTITY identifiableProperties SYSTEM "classpath://org/hisp/dhis/common/identifiableProperties.hbm">]
+  >
+
+<hibernate-mapping>
+  <class name="org.hisp.dhis.dataelement.CategoryOptionGroup" table="categoryoptiongroup">
+
+    <cache usage="read-write" />
+
+    <id name="id" column="categoryoptiongroupid">
+      <generator class="native" />
+    </id>
+    &identifiableProperties;
+
+    <property name="name" column="name" not-null="true" unique="true" length="230" />
+
+    <property name="shortName" column="shortname" unique="true" length="50" />
+
+    <set name="members" table="categoryoptiongroupmembers">
+      <cache usage="read-write" />
+      <key column="categoryoptiongroupid" foreign-key="fk_categoryoptiongroupmembers_categoryoptionid" />
+      <many-to-many class="org.hisp.dhis.dataelement.DataElementCategoryOption" column="categoryoptionid"
+        foreign-key="fk_categoryoptiongroupmembers_categoryoptiongroupid" />
+    </set>
+
+    <!-- Access properties -->
+    <many-to-one name="user" class="org.hisp.dhis.user.User" column="userid" foreign-key="fk_categoryoptiongroup_userid" />
+
+    <property name="publicAccess" length="8" />
+
+    <set name="userGroupAccesses" table="categoryoptiongroupusergroupaccesses">
+      <cache usage="read-write" />
+      <key column="categoryoptiongroupid" />
+      <many-to-many class="org.hisp.dhis.user.UserGroupAccess" column="usergroupaccessid" unique="true" />
+    </set>
+
+    <join table="categoryoptiongroupsetmembers" inverse="true">
+      <key column="categoryoptiongroupid" />
+      <many-to-one column="categoryoptiongroupsetid" name="groupSet" />
+    </join>
+
+  </class>
+</hibernate-mapping>

=== added file 'dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/dataelement/hibernate/CategoryOptionGroupSet.hbm.xml'
--- dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/dataelement/hibernate/CategoryOptionGroupSet.hbm.xml	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/dataelement/hibernate/CategoryOptionGroupSet.hbm.xml	2014-02-12 10:52:22 +0000
@@ -0,0 +1,44 @@
+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+  "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+  "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd";
+  [<!ENTITY identifiableProperties SYSTEM "classpath://org/hisp/dhis/common/identifiableProperties.hbm">]
+  >
+
+<hibernate-mapping>
+  <class name="org.hisp.dhis.dataelement.CategoryOptionGroupSet" table="categoryoptiongroupset">
+
+    <cache usage="read-write" />
+
+    <id name="id" column="categoryoptiongroupsetid">
+      <generator class="native" />
+    </id>
+    &identifiableProperties;
+
+    <property name="name" column="name" not-null="true" unique="true" length="230" />
+
+    <property name="description" type="text" />
+
+    <property name="dataDimension" />
+
+    <list name="members" table="categoryoptiongroupsetmembers">
+      <cache usage="read-write" />
+      <key column="categoryoptiongroupsetid" foreign-key="fk_categoryoptiongroupsetmembers_categoryoptiongroupsetid" />
+      <list-index column="sort_order" base="1" />
+      <many-to-many class="org.hisp.dhis.dataelement.CategoryOptionGroup" column="categoryoptiongroupid" unique="true"
+        foreign-key="fk_categoryoptiongroupsetmembers_categoryoptiongroupid" />
+    </list>
+
+    <!-- Access properties -->
+    <many-to-one name="user" class="org.hisp.dhis.user.User" column="userid" foreign-key="fk_categoryoptiongroupset_userid" />
+
+    <property name="publicAccess" length="8" />
+
+    <set name="userGroupAccesses" table="categoryoptiongroupsetusergroupaccesses">
+      <cache usage="read-write" />
+      <key column="categoryoptiongroupsetid" />
+      <many-to-many class="org.hisp.dhis.user.UserGroupAccess" column="usergroupaccessid" unique="true" />
+    </set>
+
+  </class>
+</hibernate-mapping>

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/dataelement/hibernate/DataElementGroupSet.hbm.xml'
--- dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/dataelement/hibernate/DataElementGroupSet.hbm.xml	2013-12-30 09:28:55 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/dataelement/hibernate/DataElementGroupSet.hbm.xml	2014-02-12 10:52:22 +0000
@@ -17,7 +17,7 @@
 
     <property name="name" column="name" not-null="true" unique="true" length="230" />
 
-    <property name="description" />
+    <property name="description" type="text" />
 
     <property name="compulsory" />
 

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/indicator/hibernate/IndicatorGroupSet.hbm.xml'
--- dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/indicator/hibernate/IndicatorGroupSet.hbm.xml	2013-02-07 10:25:34 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/indicator/hibernate/IndicatorGroupSet.hbm.xml	2014-02-12 10:52:22 +0000
@@ -17,7 +17,7 @@
 
     <property name="name" column="name" not-null="true" unique="false" length="230" />
 
-    <property name="description" />
+    <property name="description" type="text" />
 
     <property name="compulsory" />
 

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/organisationunit/hibernate/OrganisationUnitGroupSet.hbm.xml'
--- dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/organisationunit/hibernate/OrganisationUnitGroupSet.hbm.xml	2014-01-19 05:14:19 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/organisationunit/hibernate/OrganisationUnitGroupSet.hbm.xml	2014-02-12 10:52:22 +0000
@@ -17,7 +17,7 @@
 
     <property name="name" column="name" not-null="true" unique="true" length="230" />
 
-    <property name="description" />
+    <property name="description" type="text" />
 
     <property name="compulsory" not-null="true" />
 

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/dataelement/DataElementCategoryServiceTest.java'
--- dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/dataelement/DataElementCategoryServiceTest.java	2013-08-23 16:05:01 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/dataelement/DataElementCategoryServiceTest.java	2014-02-12 10:52:22 +0000
@@ -42,7 +42,6 @@
 
 /**
  * @author Lars Helge Overland
- * @version $Id$
  */
 public class DataElementCategoryServiceTest
     extends DhisSpringTest
@@ -82,7 +81,7 @@
     }
 
     // -------------------------------------------------------------------------
-    // Tests
+    // Category
     // -------------------------------------------------------------------------
 
     @Test
@@ -151,4 +150,72 @@
         assertTrue( categories.contains( categoryB ) );
         assertTrue( categories.contains( categoryC ) );        
     }
+
+    // -------------------------------------------------------------------------
+    // CategoryOptionGroup
+    // -------------------------------------------------------------------------
+
+    @Test
+    public void testAddGetCategoryGroup()
+    {
+        CategoryOptionGroup groupA = new CategoryOptionGroup( "A" );
+        CategoryOptionGroup groupB = new CategoryOptionGroup( "B" );
+        CategoryOptionGroup groupC = new CategoryOptionGroup( "C" );
+        
+        groupA.getMembers().add( categoryOptionA );
+        groupA.getMembers().add( categoryOptionB );
+        groupB.getMembers().add( categoryOptionC );
+        
+        int idA = categoryService.saveCategoryOptionGroup( groupA );
+        int idB = categoryService.saveCategoryOptionGroup( groupB );
+        int idC = categoryService.saveCategoryOptionGroup( groupC );
+        
+        assertEquals( groupA, categoryService.getCategoryOptionGroup( idA ) );
+        assertEquals( groupB, categoryService.getCategoryOptionGroup( idB ) );
+        assertEquals( groupC, categoryService.getCategoryOptionGroup( idC ) );
+
+        assertEquals( 2, categoryService.getCategoryOptionGroup( idA ).getMembers().size() );
+        assertEquals( 1, categoryService.getCategoryOptionGroup( idB ).getMembers().size() );
+        assertEquals( 0, categoryService.getCategoryOptionGroup( idC ).getMembers().size() );
+    }
+    
+    // -------------------------------------------------------------------------
+    // CategoryOptionGroupSet
+    // -------------------------------------------------------------------------
+
+    @Test
+    public void testAddGetCategoryGroupSet()
+    {
+        CategoryOptionGroup groupA = new CategoryOptionGroup( "A" );
+        CategoryOptionGroup groupB = new CategoryOptionGroup( "B" );
+        CategoryOptionGroup groupC = new CategoryOptionGroup( "C" );
+        
+        groupA.getMembers().add( categoryOptionA );
+        groupA.getMembers().add( categoryOptionB );
+        groupB.getMembers().add( categoryOptionC );
+        
+        categoryService.saveCategoryOptionGroup( groupA );
+        categoryService.saveCategoryOptionGroup( groupB );
+        categoryService.saveCategoryOptionGroup( groupC );
+        
+        CategoryOptionGroupSet groupSetA = new CategoryOptionGroupSet( "A" );
+        CategoryOptionGroupSet groupSetB = new CategoryOptionGroupSet( "B" );
+        CategoryOptionGroupSet groupSetC = new CategoryOptionGroupSet( "C" );
+        
+        groupSetA.getMembers().add( groupA );
+        groupSetA.getMembers().add( groupB );
+        groupSetB.getMembers().add( groupC );
+        
+        int idA = categoryService.saveCategoryOptionGroupSet( groupSetA );
+        int idB = categoryService.saveCategoryOptionGroupSet( groupSetB );
+        int idC = categoryService.saveCategoryOptionGroupSet( groupSetC );
+        
+        assertEquals( groupSetA, categoryService.getCategoryOptionGroupSet( idA ) );
+        assertEquals( groupSetB, categoryService.getCategoryOptionGroupSet( idB ) );
+        assertEquals( groupSetC, categoryService.getCategoryOptionGroupSet( idC ) );
+
+        assertEquals( 2, categoryService.getCategoryOptionGroupSet( idA ).getMembers().size() );
+        assertEquals( 1, categoryService.getCategoryOptionGroupSet( idB ).getMembers().size() );
+        assertEquals( 0, categoryService.getCategoryOptionGroupSet( idC ).getMembers().size() );
+    }
 }