=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementCategoryCombo.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementCategoryCombo.java 2011-05-05 21:14:56 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementCategoryCombo.java 2011-09-26 15:17:15 +0000 @@ -118,6 +118,21 @@ return categories != null && categories.size() > 1; } + public DataElementCategoryOption[][] getCategoryOptionsAsArray() + { + DataElementCategoryOption[][] arrays = new DataElementCategoryOption[categories.size()][]; + + int i = 0; + + for ( DataElementCategory category : categories ) + { + arrays[i++] = new ArrayList( + category.getCategoryOptions() ).toArray( new DataElementCategoryOption[0] ); + } + + return arrays; + } + // ------------------------------------------------------------------------- // hashCode, equals and toString // ------------------------------------------------------------------------- === 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 2011-08-17 09:25:09 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataelement/DefaultDataElementCategoryService.java 2011-09-26 15:17:15 +0000 @@ -37,6 +37,7 @@ import java.util.Set; import org.apache.commons.collections.CollectionUtils; +import org.hisp.dhis.common.CombinationGenerator; import org.hisp.dhis.common.GenericIdentifiableObjectStore; import org.hisp.dhis.system.util.Filter; import org.hisp.dhis.system.util.FilterUtils; @@ -467,79 +468,27 @@ } public void generateOptionCombos( DataElementCategoryCombo categoryCombo ) - { - int totalOptionCombos = 1; - - for ( DataElementCategory category : categoryCombo.getCategories() ) - { - totalOptionCombos = totalOptionCombos * category.getCategoryOptions().size(); - } - - /* - * Iterate through the collection of optionsMap every time picking one - * option from each collection. Because we have put enough number of - * options in each collection, better to remove the picked options so - * that we don't get confused how many times to pick an option - pick an - * option only once! - */ - Map> optionsMap = prepareOptionsForCombination( categoryCombo ); - - Set optionCombos = new HashSet( - totalOptionCombos ); - - for ( int i = 0; i < totalOptionCombos; i++ ) - { - List options = new ArrayList( categoryCombo - .getCategories().size() ); - - /* - * We are going to iterate the list of categories a number of times. - * better to create a copy and iterate through the copy. we can stop - * iterating when we have create the required option combinations. - */ - Collection copyOfCategories = categoryCombo.getCategories(); - - Iterator categoryIterator = copyOfCategories.iterator(); - - while ( categoryIterator.hasNext() ) - { - DataElementCategory cat = categoryIterator.next(); - - /* - * From each category pick one option - */ - Iterator optionIterator = optionsMap.get( cat.getId() ).iterator(); - - DataElementCategoryOption option = optionIterator.next(); - - options.add( option ); - - /* - * Once we used the option, better to remove it. because we have - * enough number of options - */ - optionIterator.remove(); - } - + { + CombinationGenerator generator = + new CombinationGenerator( categoryCombo.getCategoryOptionsAsArray() ); + + Set optionCombos = new HashSet(); + + while ( generator.hasNext() ) + { DataElementCategoryOptionCombo optionCombo = new DataElementCategoryOptionCombo(); - + optionCombo.setCategoryOptions( generator.getNext() ); optionCombo.setCategoryCombo( categoryCombo ); - - optionCombo.setCategoryOptions( options ); - + optionCombos.add( optionCombo ); addDataElementCategoryOptionCombo( optionCombo ); - - optionCombos.add( optionCombo ); } - + + categoryCombo.setOptionCombos( optionCombos ); + updateDataElementCategoryCombo( categoryCombo ); + //TODO update category option -> category option combo association - //TODO re-implement using CombinationGenerator - - categoryCombo.setOptionCombos( optionCombos ); - - updateDataElementCategoryCombo( categoryCombo ); } - + public List sortOptionCombos( DataElementCategoryCombo categoryCombo ) { List optionCombos = new ArrayList( === modified file 'dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/dataelement/DataElementCategoryComboServiceTest.java' --- dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/dataelement/DataElementCategoryComboServiceTest.java 2010-04-12 21:23:33 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/dataelement/DataElementCategoryComboServiceTest.java 2011-09-26 15:17:15 +0000 @@ -27,15 +27,19 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertNotNull; +import static junit.framework.Assert.assertNull; +import static junit.framework.Assert.assertTrue; + import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Set; import org.hisp.dhis.DhisSpringTest; import org.junit.Test; -import static junit.framework.Assert.*; - /** * @author Lars Helge Overland * @version $Id$ @@ -43,14 +47,21 @@ public class DataElementCategoryComboServiceTest extends DhisSpringTest { + private DataElementCategoryOption categoryOptionA; + private DataElementCategoryOption categoryOptionB; + private DataElementCategoryOption categoryOptionC; + private DataElementCategoryOption categoryOptionD; + private DataElementCategoryOption categoryOptionE; + private DataElementCategoryOption categoryOptionF; + + private DataElementCategory categoryA; + private DataElementCategory categoryB; + private DataElementCategory categoryC; + private DataElementCategoryCombo categoryComboA; private DataElementCategoryCombo categoryComboB; private DataElementCategoryCombo categoryComboC; - private DataElementCategory categoryA; - private DataElementCategory categoryB; - private DataElementCategory categoryC; - private List categories; // ------------------------------------------------------------------------- @@ -64,10 +75,38 @@ categories = new ArrayList(); + categoryOptionA = new DataElementCategoryOption( "OptionA" ); + categoryOptionB = new DataElementCategoryOption( "OptionB" ); + categoryOptionC = new DataElementCategoryOption( "OptionC" ); + categoryOptionD = new DataElementCategoryOption( "OptionD" ); + categoryOptionE = new DataElementCategoryOption( "OptionE" ); + categoryOptionF = new DataElementCategoryOption( "OptionF" ); + + categoryService.addDataElementCategoryOption( categoryOptionA ); + categoryService.addDataElementCategoryOption( categoryOptionB ); + categoryService.addDataElementCategoryOption( categoryOptionC ); + categoryService.addDataElementCategoryOption( categoryOptionD ); + categoryService.addDataElementCategoryOption( categoryOptionE ); + categoryService.addDataElementCategoryOption( categoryOptionF ); + categoryA = new DataElementCategory( "CategoryA" ); categoryB = new DataElementCategory( "CategoryB" ); categoryC = new DataElementCategory( "CategoryC" ); + categoryA.getCategoryOptions().add( categoryOptionA ); + categoryA.getCategoryOptions().add( categoryOptionB ); + categoryB.getCategoryOptions().add( categoryOptionC ); + categoryB.getCategoryOptions().add( categoryOptionD ); + categoryC.getCategoryOptions().add( categoryOptionE ); + categoryC.getCategoryOptions().add( categoryOptionF ); + + categoryOptionA.setCategory( categoryA ); + categoryOptionB.setCategory( categoryA ); + categoryOptionC.setCategory( categoryB ); + categoryOptionD.setCategory( categoryB ); + categoryOptionE.setCategory( categoryC ); + categoryOptionF.setCategory( categoryC ); + categoryService.addDataElementCategory( categoryA ); categoryService.addDataElementCategory( categoryB ); categoryService.addDataElementCategory( categoryC ); @@ -147,4 +186,26 @@ assertTrue( categoryCombos.contains( categoryComboB ) ); assertTrue( categoryCombos.contains( categoryComboC ) ); } + + @Test + public void testGenerateCategoryOptionCombos() + { + categoryComboA = new DataElementCategoryCombo( "CategoryComboA", categories ); + categoryService.addDataElementCategoryCombo( categoryComboA ); + + categoryService.generateOptionCombos( categoryComboA ); + + Set optionCombos = categoryComboA.getOptionCombos(); + + assertEquals( 8, optionCombos.size() ); + + assertTrue( optionCombos.contains( createCategoryOptionCombo( categoryComboA, categoryOptionA, categoryOptionC, categoryOptionE ) ) ); + assertTrue( optionCombos.contains( createCategoryOptionCombo( categoryComboA, categoryOptionA, categoryOptionC, categoryOptionF ) ) ); + assertTrue( optionCombos.contains( createCategoryOptionCombo( categoryComboA, categoryOptionA, categoryOptionD, categoryOptionE ) ) ); + assertTrue( optionCombos.contains( createCategoryOptionCombo( categoryComboA, categoryOptionA, categoryOptionD, categoryOptionF ) ) ); + assertTrue( optionCombos.contains( createCategoryOptionCombo( categoryComboA, categoryOptionB, categoryOptionC, categoryOptionE ) ) ); + assertTrue( optionCombos.contains( createCategoryOptionCombo( categoryComboA, categoryOptionB, categoryOptionC, categoryOptionF ) ) ); + assertTrue( optionCombos.contains( createCategoryOptionCombo( categoryComboA, categoryOptionB, categoryOptionD, categoryOptionE ) ) ); + assertTrue( optionCombos.contains( createCategoryOptionCombo( categoryComboA, categoryOptionB, categoryOptionD, categoryOptionF ) ) ); + } }