← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 5356: Extended OrganisationUnitHierarcy to also manage org unit groups

 

------------------------------------------------------------
revno: 5356
committer: Lars Helge Overland <larshelge@xxxxxxxxx>
branch nick: dhis2
timestamp: Sat 2011-12-10 17:56:25 +0100
message:
  Extended OrganisationUnitHierarcy to also manage org unit groups
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/BaseLinkableObject.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/BaseNameableObject.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementOperand.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataset/CompleteDataSetRegistrations.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataset/Section.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnitHierarchy.java
  dhis-2/dhis-api/src/test/java/org/hisp/dhis/organisationunit/OrganisationUnitHierarchyTest.java


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

Your team DHIS 2 developers is subscribed to branch lp:dhis2.
To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/BaseLinkableObject.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/BaseLinkableObject.java	2011-12-09 20:53:07 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/BaseLinkableObject.java	2011-12-10 16:56:25 +0000
@@ -27,10 +27,9 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+import javax.xml.bind.annotation.XmlAttribute;
+
 import org.codehaus.jackson.annotate.JsonProperty;
-import org.codehaus.jackson.map.annotate.JsonSerialize;
-
-import javax.xml.bind.annotation.XmlAttribute;
 
 /**
  * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/BaseNameableObject.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/BaseNameableObject.java	2011-12-09 20:53:07 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/BaseNameableObject.java	2011-12-10 16:56:25 +0000
@@ -27,10 +27,13 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
 import org.codehaus.jackson.annotate.JsonProperty;
-import org.codehaus.jackson.map.annotate.JsonSerialize;
-
-import javax.xml.bind.annotation.*;
 
 /**
  * @author Bob Jolliffe

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementOperand.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementOperand.java	2011-12-09 20:53:07 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementOperand.java	2011-12-10 16:56:25 +0000
@@ -27,25 +27,25 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+
 import org.apache.commons.lang.StringEscapeUtils;
 import org.codehaus.jackson.annotate.JsonProperty;
 import org.codehaus.jackson.map.annotate.JsonSerialize;
 import org.hisp.dhis.common.BaseIdentifiableObject;
 import org.hisp.dhis.common.Dxf2Namespace;
-import org.hisp.dhis.common.adapter.BaseIdentifiableObjectXmlAdapter;
 import org.hisp.dhis.common.adapter.CategoryOptionComboXmlAdapter;
 import org.hisp.dhis.common.adapter.DataElementXmlAdapter;
 
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
 /**
  * This object can act both as a hydrated persisted object and as a wrapper
  * object (but not both at the same time).

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataset/CompleteDataSetRegistrations.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataset/CompleteDataSetRegistrations.java	2011-12-09 20:53:07 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataset/CompleteDataSetRegistrations.java	2011-12-10 16:56:25 +0000
@@ -27,19 +27,17 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-import org.codehaus.jackson.annotate.JsonProperty;
-import org.codehaus.jackson.map.annotate.JsonSerialize;
-import org.hisp.dhis.common.BaseIdentifiableObject;
-import org.hisp.dhis.common.BaseLinkableObject;
-import org.hisp.dhis.common.Dxf2Namespace;
+import java.util.ArrayList;
+import java.util.List;
 
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
-import java.util.ArrayList;
-import java.util.List;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.hisp.dhis.common.BaseLinkableObject;
+import org.hisp.dhis.common.Dxf2Namespace;
 
 /**
  * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataset/Section.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataset/Section.java	2011-12-09 20:53:07 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataset/Section.java	2011-12-10 16:56:25 +0000
@@ -23,24 +23,29 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+
 import org.codehaus.jackson.annotate.JsonProperty;
 import org.codehaus.jackson.map.annotate.JsonSerialize;
 import org.hisp.dhis.common.BaseIdentifiableObject;
 import org.hisp.dhis.common.Dxf2Namespace;
-import org.hisp.dhis.common.adapter.BaseIdentifiableObjectXmlAdapter;
 import org.hisp.dhis.common.adapter.DataElementXmlAdapter;
 import org.hisp.dhis.dataelement.DataElement;
 import org.hisp.dhis.dataelement.DataElementCategoryCombo;
 import org.hisp.dhis.dataelement.DataElementOperand;
 
-import javax.xml.bind.annotation.*;
-import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
 @XmlRootElement( name = "section", namespace = Dxf2Namespace.NAMESPACE )
 @XmlAccessorType( value = XmlAccessType.NONE )
 public class Section

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnitHierarchy.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnitHierarchy.java	2011-12-05 18:54:20 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnitHierarchy.java	2011-12-10 16:56:25 +0000
@@ -36,14 +36,27 @@
 import java.util.Set;
 
 /**
+ * Class which encapsulates logic for the organisation unit hierarchy.
+ * 
+ * The key format for the organisation unit group variant is
+ * "<parent org unit id>:<group id>".
+ * 
  * @author Lars Helge Overland
  */
 public class OrganisationUnitHierarchy
 {
-    private Map<Integer, Set<Integer>> preparedRelationships = new HashMap<Integer, Set<Integer>>();
-    
     private Map<Integer, Set<Integer>> relationships = new HashMap<Integer, Set<Integer>>();
-    
+
+    private Map<Integer, Set<Integer>> subTrees = new HashMap<Integer, Set<Integer>>();
+    
+    // Key is on format "parent id:group id"
+    
+    private Map<String, Set<Integer>> groupSubTrees = new HashMap<String, Set<Integer>>();
+    
+    // -------------------------------------------------------------------------
+    // Constructors
+    // -------------------------------------------------------------------------
+
     public OrganisationUnitHierarchy( Map<Integer, Set<Integer>> relationships )
     {
         this.relationships = relationships;
@@ -64,7 +77,18 @@
             children.add( relation.getChildId() );
         }
     }
-    
+
+    // -------------------------------------------------------------------------
+    // Prepare
+    // -------------------------------------------------------------------------
+
+    public OrganisationUnitHierarchy prepareChildren( OrganisationUnit parent )
+    {
+        subTrees.put( parent.getId(), getChildren( parent.getId() ) );
+        
+        return this;
+    }
+
     public OrganisationUnitHierarchy prepareChildren( Collection<OrganisationUnit> parents )
     {
         for ( OrganisationUnit unit : parents )
@@ -74,19 +98,39 @@
         
         return this;
     }
-    
-    public OrganisationUnitHierarchy prepareChildren( OrganisationUnit unit )
-    {
-        preparedRelationships.put( unit.getId(), getChildren( unit.getId() ) );
-        
-        return this;
-    }
-    
+
+    // -------------------------------------------------------------------------
+    // Prepare for group
+    // -------------------------------------------------------------------------
+
+    public OrganisationUnitHierarchy prepareChildren( OrganisationUnit parent, OrganisationUnitGroup group )
+    {
+        groupSubTrees.put( getKey( parent.getId(), group ), getChildren( parent.getId(), group ) );
+        
+        return this;
+    }
+
+    public OrganisationUnitHierarchy prepareChildren( Collection<OrganisationUnit> parents, OrganisationUnitGroup group )
+    {
+        for ( OrganisationUnit unit : parents )
+        {
+            prepareChildren( unit, group );
+        }
+        
+        return this;
+    }
+    
+    // -------------------------------------------------------------------------
+    // Get children
+    // -------------------------------------------------------------------------
+
     public Set<Integer> getChildren( int parentId )
     {
-        if ( preparedRelationships.containsKey( parentId ) )
+        Set<Integer> preparedChildren = subTrees.get( parentId );
+        
+        if ( preparedChildren != null )
         {
-            return preparedRelationships.get( parentId );
+            return preparedChildren;
         }
         
         List<Integer> children = new ArrayList<Integer>();
@@ -121,5 +165,56 @@
         
         return children;
     }
+
+    // -------------------------------------------------------------------------
+    // Get children for group
+    // -------------------------------------------------------------------------
+
+    public Set<Integer> getChildren( int parentId, OrganisationUnitGroup group )
+    {
+        Set<Integer> children = groupSubTrees.get( getKey( parentId, group ) );
+        
+        if ( children != null )
+        {
+            return children;
+        }
+        
+        children = getChildren( parentId );
+        
+        Set<Integer> groupMembers = new HashSet<Integer>();
+        
+        for ( OrganisationUnit unit : group.getMembers() )
+        {
+            groupMembers.add( unit.getId() );
+        }
+        
+        children.retainAll( groupMembers );
+        
+        return children;
+    }
+    
+    public Set<Integer> getChildren( Collection<Integer> parentIds, Collection<OrganisationUnitGroup> groups )
+    {
+        Set<Integer> children = new HashSet<Integer>();
+        
+        for ( Integer id : parentIds )
+        {
+            for ( OrganisationUnitGroup group : groups )
+            {
+                children.addAll( getChildren( id, group ) );
+            }
+        }
+        
+        return children;
+    }
+    
+    // -------------------------------------------------------------------------
+    // Supportive methods
+    // -------------------------------------------------------------------------
+
+    private String getKey( int parentId, OrganisationUnitGroup group )
+    {
+        return parentId + ":" + group.getId();
+    }
 }
 

=== modified file 'dhis-2/dhis-api/src/test/java/org/hisp/dhis/organisationunit/OrganisationUnitHierarchyTest.java'
--- dhis-2/dhis-api/src/test/java/org/hisp/dhis/organisationunit/OrganisationUnitHierarchyTest.java	2011-07-26 07:39:20 +0000
+++ dhis-2/dhis-api/src/test/java/org/hisp/dhis/organisationunit/OrganisationUnitHierarchyTest.java	2011-12-10 16:56:25 +0000
@@ -46,6 +46,71 @@
 public class OrganisationUnitHierarchyTest
 {
     @Test
+    public void testGetGroupChildren()
+    {
+        OrganisationUnitGroup group = new OrganisationUnitGroup( "Group" );
+        
+        OrganisationUnit unit2 = new OrganisationUnit( "Unit2" );
+        OrganisationUnit unit4 = new OrganisationUnit( "Unit4" );
+        OrganisationUnit unit6 = new OrganisationUnit( "Unit6" );
+        OrganisationUnit unit8 = new OrganisationUnit( "Unit8" );
+        OrganisationUnit unit10 = new OrganisationUnit( "Unit10" );
+        OrganisationUnit unit12 = new OrganisationUnit( "Unit12" );
+        
+        unit2.setId( 2 );
+        unit4.setId( 4 );
+        unit6.setId( 6 );
+        unit8.setId( 8 );
+        unit10.setId( 10 );
+        unit12.setId( 12 );
+        
+        group.addOrganisationUnit( unit2 );
+        group.addOrganisationUnit( unit4 );
+        group.addOrganisationUnit( unit6 );
+        group.addOrganisationUnit( unit8 );
+        group.addOrganisationUnit( unit10 );
+        group.addOrganisationUnit( unit12 );
+                
+        List<OrganisationUnitRelationship> relationships = new ArrayList<OrganisationUnitRelationship>();
+        
+        relationships.add( new OrganisationUnitRelationship( 1, 2 ) );
+        relationships.add( new OrganisationUnitRelationship( 1, 3 ) );
+        relationships.add( new OrganisationUnitRelationship( 2, 4 ) );
+        relationships.add( new OrganisationUnitRelationship( 2, 5 ) );
+        relationships.add( new OrganisationUnitRelationship( 2, 6 ) );
+        relationships.add( new OrganisationUnitRelationship( 3, 7 ) );
+        relationships.add( new OrganisationUnitRelationship( 3, 8 ) );
+        relationships.add( new OrganisationUnitRelationship( 3, 9 ) );
+        relationships.add( new OrganisationUnitRelationship( 4, 10 ) );
+        relationships.add( new OrganisationUnitRelationship( 4, 11 ) );
+        relationships.add( new OrganisationUnitRelationship( 4, 12 ) );
+
+        OrganisationUnitHierarchy hierarchy = new OrganisationUnitHierarchy( relationships );
+        
+        assertEquals( 6, hierarchy.getChildren( 1, group ).size() );
+
+        assertEquals( 5, hierarchy.getChildren( 2, group ).size() );
+        assertTrue( hierarchy.getChildren( 2, group ).contains( 2 ) );
+        assertTrue( hierarchy.getChildren( 2, group ).contains( 4 ) );
+        assertTrue( hierarchy.getChildren( 2, group ).contains( 6 ) );
+        assertTrue( hierarchy.getChildren( 2, group ).contains( 10 ) );
+        assertTrue( hierarchy.getChildren( 2, group ).contains( 12 ) );
+
+        assertEquals( 1, hierarchy.getChildren( 3, group ).size() );
+        assertTrue( hierarchy.getChildren( 3, group ).contains( 8 ) );
+
+        assertEquals( 3, hierarchy.getChildren( 4, group ).size() );
+        assertTrue( hierarchy.getChildren( 4, group ).contains( 4 ) );
+        assertTrue( hierarchy.getChildren( 4, group ).contains( 10 ) );
+        assertTrue( hierarchy.getChildren( 4, group ).contains( 12 ) );        
+
+        assertEquals( 0, hierarchy.getChildren( 11, group ).size() );
+        
+        assertFalse( hierarchy.getChildren( 5, group ).contains( 10 ) );
+        assertFalse( hierarchy.getChildren( 3, group ).contains( 11 ) );
+    }
+    
+    @Test
     public void testGetChildrenA()
     {
         List<OrganisationUnitRelationship> relationships = new ArrayList<OrganisationUnitRelationship>();