← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 17162: SecurityService. Using queries to speed upretrieval of readable category options

 

------------------------------------------------------------
revno: 17162
committer: Lars Helge Overland <larshelge@xxxxxxxxx>
branch nick: dhis2
timestamp: Fri 2014-10-17 22:57:35 +0200
message:
  SecurityService. Using queries to speed upretrieval of readable category options
added:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/CategoryOptionStore.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataelement/hibernate/HibernateCategoryOptionStore.java
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/java/org/hisp/dhis/user/DefaultUserService.java
  dhis-2/dhis-services/dhis-service-core/src/main/resources/META-INF/dhis/beans.xml
  dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/dataelement/DataElementCategoryOptionServiceTest.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/CategoryOptionStore.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/CategoryOptionStore.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/CategoryOptionStore.java	2014-10-17 20:57:35 +0000
@@ -0,0 +1,42 @@
+package org.hisp.dhis.dataelement;
+
+/*
+ * Copyright (c) 2004-2014, 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.List;
+
+import org.hisp.dhis.common.GenericIdentifiableObjectStore;
+
+/**
+ * @author Lars Helge Overland
+ */
+public interface CategoryOptionStore
+    extends GenericIdentifiableObjectStore<DataElementCategoryOption>
+{
+    List<DataElementCategoryOption> getCategoryOptions( DataElementCategory category );
+}

=== 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-10-17 18:44:58 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementCategoryService.java	2014-10-17 20:57:35 +0000
@@ -244,14 +244,14 @@
     Collection<DataElementCategoryOption> getAllDataElementCategoryOptions();
 
     /**
-     * Returns all DataElementCategoryOptions for a given concept
+     * Returns all DataElementCategoryOptions for the given DataElementCategory.
      * 
-     * @param concept the Concept
+     * @param category the DataElementCategory.
      * @return a collection of all DataElementCategoryOptions, or an empty
      *         collection if there are no DataElementCategoryOptions.
      */
-    Collection<DataElementCategoryOption> getDataElementCategoryOptionsByConcept( Concept concept );
-
+    Collection<DataElementCategoryOption> getDataElementCategoryOptions( DataElementCategory category );
+    
     // -------------------------------------------------------------------------
     // CategoryCombo
     // -------------------------------------------------------------------------

=== 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-10-17 18:44:58 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataelement/DefaultDataElementCategoryService.java	2014-10-17 20:57:35 +0000
@@ -41,7 +41,6 @@
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.hisp.dhis.common.GenericDimensionalObjectStore;
 import org.hisp.dhis.common.GenericNameableObjectStore;
 import org.hisp.dhis.concept.Concept;
 import org.hisp.dhis.i18n.I18nService;
@@ -69,9 +68,9 @@
         this.categoryStore = categoryStore;
     }
 
-    private GenericDimensionalObjectStore<DataElementCategoryOption> categoryOptionStore;
+    private CategoryOptionStore categoryOptionStore;
 
-    public void setCategoryOptionStore( GenericDimensionalObjectStore<DataElementCategoryOption> categoryOptionStore )
+    public void setCategoryOptionStore( CategoryOptionStore categoryOptionStore )
     {
         this.categoryOptionStore = categoryOptionStore;
     }
@@ -376,6 +375,12 @@
     }
 
     @Override
+    public Collection<DataElementCategoryOption> getDataElementCategoryOptions( DataElementCategory category )
+    {
+        return i18n( i18nService, categoryOptionStore.getCategoryOptions( category ) );
+    }
+
+    @Override
     public Collection<DataElementCategoryOption> getDataElementCategoryOptionsBetween( int first, int max )
     {
         return i18n( i18nService, categoryOptionStore.getAllOrderedName( first, max ) );
@@ -389,12 +394,6 @@
     }
 
     @Override
-    public Collection<DataElementCategoryOption> getDataElementCategoryOptionsByConcept( Concept concept )
-    {
-        return categoryOptionStore.getByConcept( concept );
-    }
-
-    @Override
     public int getDataElementCategoryOptionCount()
     {
         return categoryOptionStore.getCount();

=== added file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataelement/hibernate/HibernateCategoryOptionStore.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataelement/hibernate/HibernateCategoryOptionStore.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataelement/hibernate/HibernateCategoryOptionStore.java	2014-10-17 20:57:35 +0000
@@ -0,0 +1,53 @@
+package org.hisp.dhis.dataelement.hibernate;
+
+/*
+ * Copyright (c) 2004-2014, 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.List;
+
+import org.hibernate.criterion.Restrictions;
+import org.hisp.dhis.common.hibernate.HibernateIdentifiableObjectStore;
+import org.hisp.dhis.dataelement.CategoryOptionStore;
+import org.hisp.dhis.dataelement.DataElementCategory;
+import org.hisp.dhis.dataelement.DataElementCategoryOption;
+
+/**
+ * @author Lars Helge Overland
+ */
+public class HibernateCategoryOptionStore
+    extends HibernateIdentifiableObjectStore<DataElementCategoryOption>
+    implements CategoryOptionStore
+{
+    @SuppressWarnings("unchecked")
+    public List<DataElementCategoryOption> getCategoryOptions( DataElementCategory category )
+    {
+        return getSharingCriteria().
+            createAlias( "categories", "category" ).
+            add( Restrictions.eq( "category.id", category.getId() ) ).list();
+    }
+}

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/user/DefaultUserService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/user/DefaultUserService.java	2014-10-17 18:44:58 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/user/DefaultUserService.java	2014-10-17 20:57:35 +0000
@@ -390,15 +390,9 @@
         {
             options = new HashSet<>();
 
-            for ( DataElementCategory cat : catConstraints )
+            for ( DataElementCategory category : catConstraints )
             {
-                for ( DataElementCategoryOption o : cat.getCategoryOptions() )
-                {
-                    if ( securityService.canRead( o ) )
-                    {
-                        options.add( o );
-                    }
-                }
+                options.addAll( categoryService.getDataElementCategoryOptions( category ) );
             }
         }
 

=== 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-10-17 18:44:58 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/resources/META-INF/dhis/beans.xml	2014-10-17 20:57:35 +0000
@@ -170,8 +170,7 @@
     <property name="cacheable" value="true" />
   </bean>
 
-  <bean id="org.hisp.dhis.dataelement.CategoryOptionStore"
-    class="org.hisp.dhis.common.hibernate.HibernateDimensionalObjectStore">
+  <bean id="org.hisp.dhis.dataelement.CategoryOptionStore" class="org.hisp.dhis.dataelement.hibernate.HibernateCategoryOptionStore">
     <property name="clazz" value="org.hisp.dhis.dataelement.DataElementCategoryOption" />
     <property name="sessionFactory" ref="sessionFactory" />
     <property name="cacheable" value="true" />

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/dataelement/DataElementCategoryOptionServiceTest.java'
--- dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/dataelement/DataElementCategoryOptionServiceTest.java	2014-10-07 13:46:29 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/dataelement/DataElementCategoryOptionServiceTest.java	2014-10-17 20:57:35 +0000
@@ -33,7 +33,11 @@
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
 
 import org.hisp.dhis.DhisSpringTest;
 import org.junit.Test;
@@ -52,7 +56,11 @@
     private DataElementCategoryOption categoryOptionA;
     private DataElementCategoryOption categoryOptionB;
     private DataElementCategoryOption categoryOptionC;
-  
+    
+    private DataElementCategory categoryA;
+    private DataElementCategory categoryB;
+    private DataElementCategory categoryC;
+    
     // -------------------------------------------------------------------------
     // Tests
     // -------------------------------------------------------------------------
@@ -119,4 +127,53 @@
         assertTrue( categoryOptions.contains( categoryOptionB ) );
         assertTrue( categoryOptions.contains( categoryOptionC ) );        
     }
+
+    @Test
+    public void testGetByCategory()
+    {
+        categoryOptionA = new DataElementCategoryOption( "CategoryOptionA" );
+        categoryOptionB = new DataElementCategoryOption( "CategoryOptionB" );
+        categoryOptionC = new DataElementCategoryOption( "CategoryOptionC" );
+
+        categoryService.addDataElementCategoryOption( categoryOptionA );
+        categoryService.addDataElementCategoryOption( categoryOptionB );
+        categoryService.addDataElementCategoryOption( categoryOptionC );
+        
+        List<DataElementCategoryOption> optionsA = new ArrayList<>();
+        List<DataElementCategoryOption> optionsB = new ArrayList<>();
+           
+        optionsA.add( categoryOptionA );
+        optionsA.add( categoryOptionB );
+        optionsB.add( categoryOptionC );
+        
+        categoryA = new DataElementCategory( "CategoryA", optionsA );
+        categoryB = new DataElementCategory( "CategoryB", optionsB );
+        categoryC = new DataElementCategory( "CategoryC" );
+        
+        Set<DataElementCategory> categoriesA = new HashSet<>();
+        Set<DataElementCategory> categoriesB = new HashSet<>();
+        
+        categoriesA.add( categoryA );
+        categoriesB.add( categoryB );
+        
+        categoryOptionA.setCategories( categoriesA );
+        categoryOptionB.setCategories( categoriesA );
+        categoryOptionC.setCategories( categoriesB );
+        
+        categoryService.addDataElementCategory( categoryA );
+        categoryService.addDataElementCategory( categoryB );
+        categoryService.addDataElementCategory( categoryC );
+        
+        Collection<DataElementCategoryOption> categoryOptions = categoryService.getDataElementCategoryOptions( categoryA );
+
+        assertEquals( 2, categoryOptions.size() );
+        
+        categoryOptions = categoryService.getDataElementCategoryOptions( categoryB );
+
+        assertEquals( 1, categoryOptions.size() );
+        
+        categoryOptions = categoryService.getDataElementCategoryOptions( categoryC );
+
+        assertEquals( 0, categoryOptions.size() );        
+    }
 }