← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 20426: InputUtils is moved from web-api to service-dxf2; Web-api now filters events based on attribute o...

 

------------------------------------------------------------
revno: 20426
committer: Abyot Asalefew Gizaw <abyota@xxxxxxxxx>
branch nick: dhis2
timestamp: Thu 2015-10-01 12:05:20 +0200
message:
  InputUtils is moved from web-api to service-dxf2; Web-api now filters events based on attribute option combo.
added:
  dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/utils/
  dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/utils/InputUtils.java
modified:
  dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/event/AbstractEventService.java
  dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/event/EventSearchParams.java
  dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/event/EventService.java
  dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/event/JdbcEventStore.java
  dhis-2/dhis-services/dhis-service-dxf2/src/main/resources/META-INF/dhis/beans.xml
  dhis-2/dhis-support/dhis-support-commons/src/main/java/org/hisp/dhis/commons/util/TextUtils.java
  dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/CompleteDataSetRegistrationController.java
  dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/DataValueController.java
  dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/event/EnrollmentController.java
  dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/event/EventController.java
  dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/event/TrackedEntityInstanceController.java
  dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/utils/ContextUtils.java
  dhis-2/dhis-web/dhis-web-api/src/main/resources/META-INF/dhis/beans.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-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/event/AbstractEventService.java'
--- dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/event/AbstractEventService.java	2015-09-30 03:35:45 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/event/AbstractEventService.java	2015-10-01 10:05:20 +0000
@@ -30,6 +30,7 @@
 
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.ObjectMapper;
+
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -43,6 +44,9 @@
 import org.hisp.dhis.commons.collection.CachingMap;
 import org.hisp.dhis.commons.util.DebugUtils;
 import org.hisp.dhis.dataelement.DataElement;
+import org.hisp.dhis.dataelement.DataElementCategoryCombo;
+import org.hisp.dhis.dataelement.DataElementCategoryOptionCombo;
+import org.hisp.dhis.dataelement.DataElementCategoryService;
 import org.hisp.dhis.dataelement.DataElementService;
 import org.hisp.dhis.dbms.DbmsManager;
 import org.hisp.dhis.dxf2.common.IdSchemes;
@@ -81,6 +85,7 @@
 import org.hisp.dhis.trackedentitydatavalue.TrackedEntityDataValueService;
 import org.hisp.dhis.user.CurrentUserService;
 import org.hisp.dhis.user.User;
+import org.hisp.dhis.dxf2.utils.InputUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.Assert;
@@ -105,6 +110,8 @@
     implements EventService
 {
     private static final Log log = LogFactory.getLog( AbstractEventService.class );
+    
+    public static final String OPTIONS_SEP = ";";
 
     // -------------------------------------------------------------------------
     // Dependencies
@@ -157,6 +164,12 @@
 
     @Autowired
     protected IdentifiableObjectManager manager;
+    
+    @Autowired
+    protected DataElementCategoryService categoryService;
+    
+    @Autowired
+    protected InputUtils inputUtils;
 
     protected static final int FLUSH_FREQUENCY = 20;
 
@@ -490,7 +503,7 @@
     @Override
     public EventSearchParams getFromUrl( String program, String programStage, ProgramStatus programStatus, Boolean followUp, String orgUnit,
         OrganisationUnitSelectionMode orgUnitSelectionMode, String trackedEntityInstance, Date startDate, Date endDate,
-        EventStatus status, Date lastUpdated, IdSchemes idSchemes, Integer page, Integer pageSize, boolean totalPages, boolean skipPaging, boolean includeAttributes )
+        EventStatus status, Date lastUpdated, DataElementCategoryOptionCombo attributeCoc, IdSchemes idSchemes, Integer page, Integer pageSize, boolean totalPages, boolean skipPaging, boolean includeAttributes )
     {
         EventSearchParams params = new EventSearchParams();
 
@@ -521,7 +534,27 @@
         {
             throw new IllegalQueryException( "Tracked entity instance is specified but does not exist: " + trackedEntityInstance );
         }
-
+        
+        if ( attributeCoc.isDefault() )
+        {            
+            DataElementCategoryCombo cc = null;
+            
+            if ( pr != null )
+            {
+                cc = pr.getCategoryCombo();                
+            }
+            
+            if( cc == null && ps != null)
+            {                
+                cc = ps.getProgram().getCategoryCombo();
+            }
+            
+            if( cc != null && !cc.isDefault())
+            {                
+                throw new IllegalQueryException( "Default attribute option combo is specified while program has non-default attribute category combo:  " + cc.getUid() );
+            }
+        }
+        
         params.setProgram( pr );
         params.setProgramStage( ps );
         params.setOrgUnit( ou );
@@ -533,6 +566,7 @@
         params.setEndDate( endDate );
         params.setEventStatus( status );
         params.setLastUpdated( lastUpdated );
+        params.setCategoryOptionCombo( attributeCoc );
         params.setIdSchemes( idSchemes );
         params.setPage( page );
         params.setPageSize( pageSize );
@@ -989,26 +1023,27 @@
 
     private ProgramStageInstance createProgramStageInstance( ProgramStage programStage, ProgramInstance programInstance,
         OrganisationUnit organisationUnit, Date dueDate, Date executionDate, int status,
-        Coordinate coordinate, String storedBy, String programStageInstanceUid )
+        Coordinate coordinate, String storedBy, String programStageInstanceUid, DataElementCategoryOptionCombo coc )
     {
         ProgramStageInstance programStageInstance = new ProgramStageInstance();
         programStageInstance.setUid( CodeGenerator.isValidCode( programStageInstanceUid ) ? programStageInstanceUid : CodeGenerator.generateCode() );
 
         updateProgramStageInstance( programStage, programInstance, organisationUnit, dueDate, executionDate, status,
-            coordinate, storedBy, programStageInstance );
+            coordinate, storedBy, programStageInstance, coc );
 
         return programStageInstance;
     }
 
     private void updateProgramStageInstance( ProgramStage programStage, ProgramInstance programInstance,
         OrganisationUnit organisationUnit, Date dueDate, Date executionDate, int status, Coordinate coordinate,
-        String storedBy, ProgramStageInstance programStageInstance )
+        String storedBy, ProgramStageInstance programStageInstance,  DataElementCategoryOptionCombo coc )
     {
         programStageInstance.setProgramInstance( programInstance );
         programStageInstance.setProgramStage( programStage );
         programStageInstance.setDueDate( dueDate );
         programStageInstance.setExecutionDate( executionDate );
         programStageInstance.setOrganisationUnit( organisationUnit );
+        programStageInstance.setAttributeOptionCombo( coc );
 
         if ( programStage.getCaptureCoordinates() )
         {
@@ -1053,18 +1088,30 @@
         Date dueDate = DateUtils.parseDate( event.getDueDate() );
 
         String storedBy = getStoredBy( event, importSummary, user );
+        
+        DataElementCategoryOptionCombo coc = categoryService.getDefaultDataElementCategoryOptionCombo();
+        
+        if ( event.getAttributeCategoryOptions() != null && program.getCategoryCombo() != null )
+        {
+            coc = inputUtils.getAttributeOptionCombo( program.getCategoryCombo(), program.getCategoryCombo().getUid(), event.getAttributeCategoryOptions() ); //getAttributeOptionCombo( program.getCategoryCombo(), event.getAttributeCategoryOptions() );
+            
+            if ( coc == null)
+            {
+                importSummary.getConflicts().add( new ImportConflict( "Invalid attribute option combo for option names.", event.getAttributeCategoryOptions() ) );
+            }
+        }
 
         if ( !dryRun )
         {
             if ( programStageInstance == null )
             {
                 programStageInstance = createProgramStageInstance( programStage, programInstance, organisationUnit,
-                    dueDate, eventDate, event.getStatus().getValue(), event.getCoordinate(), storedBy, event.getEvent() );
+                    dueDate, eventDate, event.getStatus().getValue(), event.getCoordinate(), storedBy, event.getEvent(), coc );
             }
             else
             {
                 updateProgramStageInstance( programStage, programInstance, organisationUnit, dueDate, eventDate, event
-                    .getStatus().getValue(), event.getCoordinate(), storedBy, programStageInstance );
+                    .getStatus().getValue(), event.getCoordinate(), storedBy, programStageInstance, coc );
             }
 
             saveTrackedEntityComment( programStageInstance, event, storedBy );

=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/event/EventSearchParams.java'
--- dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/event/EventSearchParams.java	2015-06-02 12:59:26 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/event/EventSearchParams.java	2015-10-01 10:05:20 +0000
@@ -31,6 +31,7 @@
 import java.util.Date;
 
 import org.hisp.dhis.common.OrganisationUnitSelectionMode;
+import org.hisp.dhis.dataelement.DataElementCategoryOptionCombo;
 import org.hisp.dhis.dxf2.common.IdSchemes;
 import org.hisp.dhis.event.EventStatus;
 import org.hisp.dhis.organisationunit.OrganisationUnit;
@@ -69,6 +70,8 @@
     private EventStatus eventStatus;
 
     private Date lastUpdated;
+    
+    private DataElementCategoryOptionCombo categoryOptionCombo;
 
     private IdSchemes idSchemes;
 
@@ -298,4 +301,14 @@
         this.includeAttributes = includeAttributes;
     }
 
+    public DataElementCategoryOptionCombo getCategoryOptionCombo()
+    {
+        return categoryOptionCombo;
+    }
+
+    public void setCategoryOptionCombo( DataElementCategoryOptionCombo categoryOptionCombo )
+    {
+        this.categoryOptionCombo = categoryOptionCombo;
+    }
+
 }

=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/event/EventService.java'
--- dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/event/EventService.java	2015-09-30 03:35:45 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/event/EventService.java	2015-10-01 10:05:20 +0000
@@ -34,6 +34,7 @@
 import java.util.List;
 
 import org.hisp.dhis.common.OrganisationUnitSelectionMode;
+import org.hisp.dhis.dataelement.DataElementCategoryOptionCombo;
 import org.hisp.dhis.dxf2.common.IdSchemes;
 import org.hisp.dhis.dxf2.common.ImportOptions;
 import org.hisp.dhis.dxf2.events.report.EventRows;
@@ -59,7 +60,7 @@
 
     EventSearchParams getFromUrl( String program, String programStage, ProgramStatus programStatus, Boolean followUp, String orgUnit,
         OrganisationUnitSelectionMode orgUnitSelectionMode, String trackedEntityInstance, Date startDate, Date endDate, 
-        EventStatus status, Date lastUpdated, IdSchemes idSchemes, Integer page, Integer pageSize, boolean totalPages, boolean skipPaging, boolean includeAttributes );
+        EventStatus status, Date lastUpdated, DataElementCategoryOptionCombo attributeCoc, IdSchemes idSchemes, Integer page, Integer pageSize, boolean totalPages, boolean skipPaging, boolean includeAttributes );
     
     Event getEvent( String uid );
 

=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/event/JdbcEventStore.java'
--- dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/event/JdbcEventStore.java	2015-09-24 08:32:10 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/event/JdbcEventStore.java	2015-10-01 10:05:20 +0000
@@ -385,6 +385,11 @@
         {
             sql += hlp.whereAnd() + " psi.lastupdated > '" + DateUtils.getLongDateString( params.getLastUpdated() ) + "' ";
         }
+        
+        if( params.getCategoryOptionCombo() != null )
+        {
+            sql += hlp.whereAnd() + " psi.attributeoptioncomboid = " + params.getCategoryOptionCombo().getId() + " ";
+        }
 
         if ( params.getEventStatus() == null || EventStatus.isExistingEvent( params.getEventStatus() ) )
         {

=== added directory 'dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/utils'
=== added file 'dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/utils/InputUtils.java'
--- dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/utils/InputUtils.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/utils/InputUtils.java	2015-10-01 10:05:20 +0000
@@ -0,0 +1,130 @@
+package org.hisp.dhis.dxf2.utils;
+
+/*
+ * Copyright (c) 2004-2015, 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 org.hisp.dhis.common.IdentifiableObjectManager;
+import org.hisp.dhis.common.IllegalQueryException;
+import org.hisp.dhis.commons.util.TextUtils;
+import org.hisp.dhis.dataelement.DataElementCategoryCombo;
+import org.hisp.dhis.dataelement.DataElementCategoryOption;
+import org.hisp.dhis.dataelement.DataElementCategoryOptionCombo;
+import org.hisp.dhis.dataelement.DataElementCategoryService;
+import org.hisp.dhis.dxf2.webmessage.WebMessageException;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * @author Lars Helge Overland
+ */
+public class InputUtils
+{
+    @Autowired
+    private DataElementCategoryService categoryService;
+
+    @Autowired
+    private IdentifiableObjectManager idObjectManager;
+
+    /**
+     * Validates and retrieves the attribute option combo. 409 conflict as status
+     * code along with a textual message will be set on the response in case of
+     * invalid input.
+     *
+     * @param cc       the category combo identifier.
+     * @param cp       the category and option query string.
+     * @return the attribute option combo identified from the given input, or null
+     * if the input was invalid.
+     */
+    public DataElementCategoryOptionCombo getAttributeOptionCombo( DataElementCategoryCombo ccombo, String cc, String cp )
+    {
+        Set<String> opts = TextUtils.splitToArray( cp, TextUtils.SEMICOLON );
+
+        // ---------------------------------------------------------------------
+        // Attribute category combo validation
+        // ---------------------------------------------------------------------
+
+        if ( (cc == null && opts != null || (cc != null && opts == null)) )
+        {            
+            throw new IllegalQueryException( "Both or none of category combination and category options must be present" ) ;
+        }
+
+        DataElementCategoryCombo categoryCombo = ccombo;
+
+        if ( categoryCombo == null )
+        {            
+            if ( cc != null && (categoryCombo = idObjectManager.get( DataElementCategoryCombo.class, cc )) == null )
+            {
+                throw new IllegalQueryException( "Illegal category combo identifier: " + cc );
+            }
+        }
+
+        // ---------------------------------------------------------------------
+        // Attribute category options validation
+        // ---------------------------------------------------------------------
+
+        DataElementCategoryOptionCombo attributeOptionCombo = null;
+
+        if ( opts != null )
+        {
+            Set<DataElementCategoryOption> categoryOptions = new HashSet<>();
+
+            for ( String uid : opts )
+            {
+                DataElementCategoryOption categoryOption = idObjectManager.get( DataElementCategoryOption.class, uid );
+
+                if ( categoryOption == null )
+                {
+                    throw new IllegalQueryException( "Illegal category option identifier: " + uid ) ;
+                }
+
+                categoryOptions.add( categoryOption );
+            }
+
+            attributeOptionCombo = categoryService.getDataElementCategoryOptionCombo( categoryCombo, categoryOptions );
+
+            if ( attributeOptionCombo == null )
+            {
+                throw new IllegalQueryException( "Attribute option combo does not exist for given category combo and category options" );
+            }
+        }
+
+        if ( attributeOptionCombo == null )
+        {
+            attributeOptionCombo = categoryService.getDefaultDataElementCategoryOptionCombo();
+        }
+
+        if ( attributeOptionCombo == null )
+        {
+            throw new IllegalQueryException( "Default attribute option combo does not exist" );
+        }
+
+        return attributeOptionCombo;
+    }
+}

=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/main/resources/META-INF/dhis/beans.xml'
--- dhis-2/dhis-services/dhis-service-dxf2/src/main/resources/META-INF/dhis/beans.xml	2015-09-14 09:13:10 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/main/resources/META-INF/dhis/beans.xml	2015-10-01 10:05:20 +0000
@@ -324,9 +324,11 @@
     <constructor-arg name="importerClass" type="java.lang.Class" value="org.hisp.dhis.security.oauth2.OAuth2Client" />
   </bean>
 
+  <bean id="inputUtils" class="org.hisp.dhis.dxf2.utils.InputUtils" />
+  
   <!-- ADX Service -->
 
   <bean id="org.hisp.dhis.dxf2.ADXDataService"
-    class="org.hisp.dhis.dxf2.adx.DefaultADXDataService" />
+    class="org.hisp.dhis.dxf2.adx.DefaultADXDataService" />    
 
 </beans>

=== modified file 'dhis-2/dhis-support/dhis-support-commons/src/main/java/org/hisp/dhis/commons/util/TextUtils.java'
--- dhis-2/dhis-support/dhis-support-commons/src/main/java/org/hisp/dhis/commons/util/TextUtils.java	2015-09-24 21:48:20 +0000
+++ dhis-2/dhis-support/dhis-support-commons/src/main/java/org/hisp/dhis/commons/util/TextUtils.java	2015-10-01 10:05:20 +0000
@@ -34,7 +34,9 @@
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -50,6 +52,7 @@
     public static final String SPACE = " ";
     public static final String SEP = "-";
     public static final String LN = System.getProperty( "line.separator" );
+    public static final String SEMICOLON = ";";
     
     private static final Pattern LINK_PATTERN = Pattern.compile( "((http://|https://|www\\.).+?)($|\\n|\\r|\\r\\n| )" );
     private static final String DELIMITER = ", ";
@@ -560,4 +563,24 @@
         
         return false;
     }
+    
+    /**
+     * Splits the given string value into independent values using a given
+     * separator.
+     *
+     * @param value the string to be splitted.
+     * @param separator for splitting value 
+     * @return the list of independent values.
+     */
+    public static Set<String> splitToArray( String value, String separator )
+    {
+        if ( value == null || value.isEmpty() )
+        {
+            return null;
+        }
+
+        String[] values = value.split( separator );
+
+        return new HashSet<>( Arrays.asList( values ) );
+    }
 }

=== modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/CompleteDataSetRegistrationController.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/CompleteDataSetRegistrationController.java	2015-09-14 17:57:00 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/CompleteDataSetRegistrationController.java	2015-10-01 10:05:20 +0000
@@ -48,7 +48,7 @@
 import org.hisp.dhis.period.PeriodService;
 import org.hisp.dhis.period.PeriodType;
 import org.hisp.dhis.user.CurrentUserService;
-import org.hisp.dhis.webapi.utils.InputUtils;
+import org.hisp.dhis.dxf2.utils.InputUtils;
 import org.hisp.dhis.webapi.utils.WebMessageUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
@@ -192,7 +192,7 @@
             throw new WebMessageException( WebMessageUtils.conflict( "Illegal organisation unit identifier: " + ou ) );
         }
 
-        DataElementCategoryOptionCombo attributeOptionCombo = inputUtils.getAttributeOptionCombo( cc, cp );
+        DataElementCategoryOptionCombo attributeOptionCombo = inputUtils.getAttributeOptionCombo( null, cc, cp );
 
         if ( attributeOptionCombo == null )
         {
@@ -285,7 +285,7 @@
 
             String cc = completeDataSetRegistrationRequest.getCc();
             String cp = completeDataSetRegistrationRequest.getCp();
-            DataElementCategoryOptionCombo attributeOptionCombo = inputUtils.getAttributeOptionCombo( cc, cp );
+            DataElementCategoryOptionCombo attributeOptionCombo = inputUtils.getAttributeOptionCombo( null, cc, cp );
 
             if ( attributeOptionCombo == null )
             {
@@ -372,7 +372,7 @@
             throw new WebMessageException( WebMessageUtils.conflict( "Illegal organisation unit identifier: " + ou ) );
         }
 
-        DataElementCategoryOptionCombo attributeOptionCombo = inputUtils.getAttributeOptionCombo( cc, cp );
+        DataElementCategoryOptionCombo attributeOptionCombo = inputUtils.getAttributeOptionCombo( null, cc, cp );
 
         if ( attributeOptionCombo == null )
         {

=== modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/DataValueController.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/DataValueController.java	2015-10-01 07:51:29 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/DataValueController.java	2015-10-01 10:05:20 +0000
@@ -56,7 +56,7 @@
 import org.hisp.dhis.setting.SystemSettingManager;
 import org.hisp.dhis.system.util.ValidationUtils;
 import org.hisp.dhis.user.CurrentUserService;
-import org.hisp.dhis.webapi.utils.InputUtils;
+import org.hisp.dhis.dxf2.utils.InputUtils;
 import org.hisp.dhis.webapi.utils.WebMessageUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpHeaders;
@@ -673,7 +673,7 @@
     private DataElementCategoryOptionCombo getAndValidateAttributeOptionCombo( String cc, String cp )
         throws WebMessageException
     {
-        DataElementCategoryOptionCombo attributeOptionCombo = inputUtils.getAttributeOptionCombo( cc, cp );
+        DataElementCategoryOptionCombo attributeOptionCombo = inputUtils.getAttributeOptionCombo( null, cc, cp );
 
         if ( attributeOptionCombo == null )
         {

=== modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/event/EnrollmentController.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/event/EnrollmentController.java	2015-09-14 09:13:10 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/event/EnrollmentController.java	2015-10-01 10:05:20 +0000
@@ -29,7 +29,9 @@
  */
 
 import com.google.common.collect.Lists;
+
 import org.hisp.dhis.common.OrganisationUnitSelectionMode;
+import org.hisp.dhis.commons.util.TextUtils;
 import org.hisp.dhis.dxf2.common.JacksonUtils;
 import org.hisp.dhis.dxf2.events.enrollment.Enrollment;
 import org.hisp.dhis.dxf2.events.enrollment.EnrollmentService;
@@ -65,6 +67,7 @@
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Date;
@@ -124,7 +127,8 @@
             fields.add( "enrollment,created,lastUpdated,trackedEntity,trackedEntityInstance,program,status,orgUnit,enrollmentDate,incidentDate,followup" );
         }
 
-        Set<String> orgUnits = ContextUtils.getQueryParamValues( ou );
+        Set<String> orgUnits = TextUtils.splitToArray( ou, TextUtils.SEMICOLON );
+        
         ProgramInstanceQueryParams params = programInstanceService.getFromUrl( orgUnits, ouMode, lastUpdated, program, programStatus, programStartDate,
             programEndDate, trackedEntity, trackedEntityInstance, followUp, page, pageSize, totalPages, skipPaging );
 

=== modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/event/EventController.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/event/EventController.java	2015-09-30 03:35:45 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/event/EventController.java	2015-10-01 10:05:20 +0000
@@ -31,6 +31,7 @@
 import org.hisp.dhis.common.OrganisationUnitSelectionMode;
 import org.hisp.dhis.commons.util.StreamUtils;
 import org.hisp.dhis.dataelement.DataElement;
+import org.hisp.dhis.dataelement.DataElementCategoryOptionCombo;
 import org.hisp.dhis.dataelement.DataElementService;
 import org.hisp.dhis.dxf2.common.IdSchemes;
 import org.hisp.dhis.dxf2.common.ImportOptions;
@@ -58,6 +59,7 @@
 import org.hisp.dhis.user.CurrentUserService;
 import org.hisp.dhis.webapi.service.WebMessageService;
 import org.hisp.dhis.webapi.utils.ContextUtils;
+import org.hisp.dhis.dxf2.utils.InputUtils;
 import org.hisp.dhis.webapi.utils.WebMessageUtils;
 import org.hisp.dhis.webapi.webdomain.WebOptions;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -72,6 +74,7 @@
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -117,6 +120,9 @@
 
     @Autowired
     private WebMessageService webMessageService;
+    
+    @Autowired
+    private InputUtils inputUtils;
 
     // -------------------------------------------------------------------------
     // READ
@@ -136,6 +142,8 @@
         @RequestParam( required = false ) Date endDate,
         @RequestParam( required = false ) EventStatus status,
         @RequestParam( required = false ) Date lastUpdated,
+        @RequestParam( required = false ) String attributeCc,
+        @RequestParam( required = false ) String attributeCos,
         @RequestParam( required = false ) boolean skipMeta,
         @RequestParam( required = false ) Integer page,
         @RequestParam( required = false ) Integer pageSize,
@@ -143,11 +151,19 @@
         @RequestParam( required = false ) boolean skipPaging,
         @RequestParam( required = false ) String attachment,
         @RequestParam Map<String, String> parameters, IdSchemes idSchemes, Model model, HttpServletResponse response, HttpServletRequest request )
+         throws WebMessageException
     {
         WebOptions options = new WebOptions( parameters );
 
+        DataElementCategoryOptionCombo attributeOptionCombo = inputUtils.getAttributeOptionCombo( null, attributeCc, attributeCos );
+        
+        if ( attributeOptionCombo == null )
+        {
+            throw new WebMessageException( WebMessageUtils.conflict( "Illegal attribute option combo identifier: " + attributeCc + " " + attributeCos ) );
+        }
+        
         EventSearchParams params = eventService.getFromUrl( program, programStage, programStatus, followUp, orgUnit, ouMode,
-            trackedEntityInstance, startDate, endDate, status, lastUpdated, idSchemes, page, pageSize, totalPages, skipPaging, false );
+            trackedEntityInstance, startDate, endDate, status, lastUpdated, attributeOptionCombo, idSchemes, page, pageSize, totalPages, skipPaging, false );
 
         Events events = eventService.getEvents( params );
 
@@ -189,6 +205,8 @@
         @RequestParam( required = false ) Date endDate,
         @RequestParam( required = false ) EventStatus status,
         @RequestParam( required = false ) Date lastUpdated,
+        @RequestParam( required = false ) String attributeCc,
+        @RequestParam( required = false ) String attributeCos,
         @RequestParam( required = false ) Integer page,
         @RequestParam( required = false ) Integer pageSize,
         @RequestParam( required = false ) boolean totalPages,
@@ -196,10 +214,18 @@
         @RequestParam( required = false ) String attachment,
         @RequestParam( required = false, defaultValue = "false" ) boolean skipHeader,
         @RequestParam Map<String, String> parameters,
-        IdSchemes idSchemes, Model model, HttpServletResponse response, HttpServletRequest request ) throws IOException
+        IdSchemes idSchemes, Model model, HttpServletResponse response, HttpServletRequest request ) throws IOException, WebMessageException
     {
+        
+        DataElementCategoryOptionCombo attributeOptionCombo = inputUtils.getAttributeOptionCombo( null, attributeCc, attributeCos );
+        
+        if ( attributeOptionCombo == null )
+        {
+            throw new WebMessageException( WebMessageUtils.conflict( "Illegal attribute option combo identifier: " + attributeCc + " " + attributeCos ) );
+        }
+        
         EventSearchParams params = eventService.getFromUrl( program, programStage, programStatus, followUp, orgUnit, ouMode,
-            trackedEntityInstance, startDate, endDate, status, lastUpdated, idSchemes, page, pageSize, totalPages, skipPaging, false );
+            trackedEntityInstance, startDate, endDate, status, lastUpdated, attributeOptionCombo, idSchemes, page, pageSize, totalPages, skipPaging, false );
 
         Events events = eventService.getEvents( params );
 
@@ -231,14 +257,25 @@
         @RequestParam( required = false ) EventStatus eventStatus,
         @RequestParam( required = false ) Date startDate,
         @RequestParam( required = false ) Date endDate,
+        @RequestParam( required = false ) String attributeCc,
+        @RequestParam( required = false ) String attributeCos,
         @RequestParam( required = false ) boolean totalPages,
         @RequestParam( required = false ) boolean skipPaging,
         @RequestParam Map<String, String> parameters, Model model, HttpServletRequest request )
+        throws WebMessageException
+        
     {
         WebOptions options = new WebOptions( parameters );
-
+        
+        DataElementCategoryOptionCombo attributeOptionCombo = inputUtils.getAttributeOptionCombo( null, attributeCc, attributeCos );
+        
+        if ( attributeOptionCombo == null )
+        {
+            throw new WebMessageException( WebMessageUtils.conflict( "Illegal attribute option combo identifier: " + attributeCc + " " + attributeCos ) );
+        }
+        
         EventSearchParams params = eventService.getFromUrl( program, null, programStatus, null,
-            orgUnit, ouMode, null, startDate, endDate, eventStatus, null, null, null, null, totalPages, skipPaging, true );
+            orgUnit, ouMode, null, startDate, endDate, eventStatus, null, attributeOptionCombo, null, null, null, totalPages, skipPaging, true );
 
         EventRows eventRows = eventRowService.getEventRows( params );
 

=== modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/event/TrackedEntityInstanceController.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/event/TrackedEntityInstanceController.java	2015-09-14 09:13:10 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/event/TrackedEntityInstanceController.java	2015-10-01 10:05:20 +0000
@@ -29,10 +29,12 @@
  */
 
 import com.google.common.collect.Lists;
+
 import org.hisp.dhis.common.DxfNamespaces;
 import org.hisp.dhis.common.Grid;
 import org.hisp.dhis.common.OrganisationUnitSelectionMode;
 import org.hisp.dhis.common.cache.CacheStrategy;
+import org.hisp.dhis.commons.util.TextUtils;
 import org.hisp.dhis.dxf2.common.JacksonUtils;
 import org.hisp.dhis.dxf2.events.trackedentity.TrackedEntityInstance;
 import org.hisp.dhis.dxf2.events.trackedentity.TrackedEntityInstanceService;
@@ -69,6 +71,7 @@
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+
 import java.io.IOException;
 import java.util.Date;
 import java.util.List;
@@ -134,7 +137,7 @@
             fields.add( ":all" );
         }
 
-        Set<String> orgUnits = ContextUtils.getQueryParamValues( ou );
+        Set<String> orgUnits = TextUtils.splitToArray( ou, TextUtils.SEMICOLON );
         TrackedEntityInstanceQueryParams params = instanceService.getFromUrl( query, attribute, filter, orgUnits, ouMode,
             program, programStatus, followUp, programStartDate, programEndDate, trackedEntity,
             eventStatus, eventStartDate, eventEndDate, skipMeta, page, pageSize, totalPages, skipPaging );
@@ -171,7 +174,7 @@
         Model model,
         HttpServletResponse response ) throws Exception
     {
-        Set<String> orgUnits = ContextUtils.getQueryParamValues( ou );
+        Set<String> orgUnits = TextUtils.splitToArray( ou, TextUtils.SEMICOLON );
         TrackedEntityInstanceQueryParams params = instanceService.getFromUrl( query, attribute, filter, orgUnits, ouMode,
             program, programStatus, followUp, programStartDate, programEndDate, trackedEntity,
             eventStatus, eventStartDate, eventEndDate, skipMeta, page, pageSize, totalPages, skipPaging );
@@ -209,7 +212,7 @@
         Model model,
         HttpServletResponse response ) throws Exception
     {
-        Set<String> orgUnits = ContextUtils.getQueryParamValues( ou );
+        Set<String> orgUnits = TextUtils.splitToArray( ou, TextUtils.SEMICOLON );
         TrackedEntityInstanceQueryParams params = instanceService.getFromUrl( query, attribute, filter, orgUnits, ouMode,
             program, programStatus, followUp, programStartDate, programEndDate, trackedEntity,
             eventStatus, eventStartDate, eventEndDate, skipMeta, page, pageSize, totalPages, skipPaging );
@@ -243,7 +246,7 @@
         Model model,
         HttpServletResponse response ) throws Exception
     {
-        Set<String> orgUnits = ContextUtils.getQueryParamValues( ou );
+        Set<String> orgUnits = TextUtils.splitToArray( ou, TextUtils.SEMICOLON );
         TrackedEntityInstanceQueryParams params = instanceService.getFromUrl( query, attribute, filter, orgUnits, ouMode,
             program, programStatus, followUp, programStartDate, programEndDate, trackedEntity,
             eventStatus, eventStartDate, eventEndDate, skipMeta, page, pageSize, totalPages, skipPaging );
@@ -277,7 +280,7 @@
         Model model,
         HttpServletResponse response ) throws Exception
     {
-        Set<String> orgUnits = ContextUtils.getQueryParamValues( ou );
+        Set<String> orgUnits = TextUtils.splitToArray( ou, TextUtils.SEMICOLON );
         TrackedEntityInstanceQueryParams params = instanceService.getFromUrl( query, attribute, filter, orgUnits, ouMode,
             program, programStatus, followUp, programStartDate, programEndDate, trackedEntity,
             eventStatus, eventStartDate, eventEndDate, skipMeta, page, pageSize, totalPages, skipPaging );

=== modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/utils/ContextUtils.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/utils/ContextUtils.java	2015-09-21 13:36:12 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/utils/ContextUtils.java	2015-10-01 10:05:20 +0000
@@ -233,25 +233,6 @@
     }
 
     /**
-     * Splits the given query param value into independent values using ; as
-     * separator.
-     *
-     * @param value the query param value.
-     * @return the list of independent values.
-     */
-    public static Set<String> getQueryParamValues( String value )
-    {
-        if ( value == null || value.isEmpty() )
-        {
-            return null;
-        }
-
-        String[] values = value.split( QUERY_PARAM_SEP );
-
-        return new HashSet<>( Arrays.asList( values ) );
-    }
-
-    /**
      * Returns a mapping of dimension identifiers and dimension option identifiers
      * based on the given set of dimension strings. Splits the strings using : as
      * separator. Returns null of dimensions are null or empty.

=== modified file 'dhis-2/dhis-web/dhis-web-api/src/main/resources/META-INF/dhis/beans.xml'
--- dhis-2/dhis-web/dhis-web-api/src/main/resources/META-INF/dhis/beans.xml	2014-12-04 06:39:46 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/resources/META-INF/dhis/beans.xml	2015-10-01 10:05:20 +0000
@@ -3,7 +3,6 @@
 	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
 	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd";>
 	
-  <bean id="contextUtils" class="org.hisp.dhis.webapi.utils.ContextUtils"/>
-  <bean id="inputUtils" class="org.hisp.dhis.webapi.utils.InputUtils" />
+  <bean id="contextUtils" class="org.hisp.dhis.webapi.utils.ContextUtils"/>  
 
 </beans>