← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 20334: preheat support for endpoints other than /api/metadata, will only preheat classes that are releva...

 

------------------------------------------------------------
revno: 20334
committer: Morten Olav Hansen <mortenoh@xxxxxxxxx>
branch nick: dhis2
timestamp: Thu 2015-09-24 12:44:40 +0700
message:
  preheat support for endpoints other than /api/metadata, will only preheat classes that are relevant to object that is being imported
modified:
  dhis-2/dhis-services/dhis-service-core/src/main/resources/META-INF/dhis/beans.xml
  dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/DefaultImportService.java
  dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/DefaultObjectBridge.java
  dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/ImportService.java
  dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/ObjectBridge.java
  dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/importers/DefaultIdentifiableObjectImporter.java
  dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/AbstractCrudController.java
  dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/user/UserController.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-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	2015-09-18 16:29:32 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/resources/META-INF/dhis/beans.xml	2015-09-24 05:44:40 +0000
@@ -11,6 +11,10 @@
 
   <context:component-scan base-package="org.hisp.dhis.node" />
 
+  <bean id="org.hisp.dhis.preheat.PreheatService" class="org.hisp.dhis.preheat.DefaultPreheatService" scope="prototype">
+    <aop:scoped-proxy proxy-target-class="false" />
+  </bean>
+
   <bean id="org.hisp.dhis.calendar.CalendarService" class="org.hisp.dhis.calendar.DefaultCalendarService" />
 
   <bean id="org.hisp.dhis.schema.SchemaService" class="org.hisp.dhis.schema.DefaultSchemaService" />

=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/DefaultImportService.java'
--- dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/DefaultImportService.java	2015-09-03 03:11:47 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/DefaultImportService.java	2015-09-24 05:44:40 +0000
@@ -28,25 +28,14 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-import static org.springframework.util.Assert.notNull;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.hibernate.SessionFactory;
 import org.hisp.dhis.cache.HibernateCacheManager;
 import org.hisp.dhis.common.IdentifiableObject;
-import org.hisp.dhis.common.MergeStrategy;
 import org.hisp.dhis.commons.timer.SystemTimer;
 import org.hisp.dhis.commons.timer.Timer;
 import org.hisp.dhis.dxf2.common.ImportOptions;
-import org.hisp.dhis.importexport.ImportStrategy;
 import org.hisp.dhis.scheduling.TaskId;
 import org.hisp.dhis.schema.Schema;
 import org.hisp.dhis.schema.SchemaService;
@@ -59,6 +48,15 @@
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.StringUtils;
 
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import static org.springframework.util.Assert.notNull;
+
 /**
  * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
  */
@@ -98,19 +96,15 @@
     //-------------------------------------------------------------------------------------------------------
 
     @Override
-    public <T extends IdentifiableObject> ImportTypeSummary importObject( String userUid, T object, ImportStrategy importStrategy, MergeStrategy mergeStrategy )
+    public <T extends IdentifiableObject> ImportTypeSummary importObject( String userUid, T object, ImportOptions importOptions )
     {
         User user = userService.getUser( userUid );
 
-        ImportOptions importOptions = new ImportOptions();
-        importOptions.setDryRun( false );
-        importOptions.setPreheatCache( false );
-        importOptions.setImportStrategy( importStrategy );
-        importOptions.setMergeStrategy( mergeStrategy );
-
         objectBridge.setWriteEnabled( !importOptions.isDryRun() );
         objectBridge.setPreheatCache( importOptions.isPreheatCache() );
-        objectBridge.init();
+
+        Schema schema = schemaService.getDynamicSchema( object.getClass() );
+        objectBridge.init( schema.getReferences() );
 
         ImportTypeSummary importTypeSummary = doImport( user, object, importOptions );
 
@@ -153,7 +147,7 @@
 
         objectBridge.setWriteEnabled( !importOptions.isDryRun() );
         objectBridge.setPreheatCache( importOptions.isPreheatCache() );
-        objectBridge.init();
+        objectBridge.init( new HashSet<>() );
 
         for ( Schema schema : schemaService.getMetadataSchemas() )
         {

=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/DefaultObjectBridge.java'
--- dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/DefaultObjectBridge.java	2015-09-22 05:03:02 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/DefaultObjectBridge.java	2015-09-24 05:44:40 +0000
@@ -28,7 +28,6 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-import com.google.common.collect.Lists;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.hibernate.SessionFactory;
@@ -37,6 +36,8 @@
 import org.hisp.dhis.common.IdentifiableObject;
 import org.hisp.dhis.common.IdentifiableObjectManager;
 import org.hisp.dhis.common.IdentifiableProperty;
+import org.hisp.dhis.commons.timer.SystemTimer;
+import org.hisp.dhis.commons.timer.Timer;
 import org.hisp.dhis.organisationunit.OrganisationUnit;
 import org.hisp.dhis.organisationunit.OrganisationUnitService;
 import org.hisp.dhis.period.PeriodStore;
@@ -44,8 +45,6 @@
 import org.hisp.dhis.schema.Schema;
 import org.hisp.dhis.schema.SchemaService;
 import org.hisp.dhis.system.deletion.DeletionManager;
-import org.hisp.dhis.commons.timer.SystemTimer;
-import org.hisp.dhis.commons.timer.Timer;
 import org.hisp.dhis.user.CurrentUserService;
 import org.hisp.dhis.user.User;
 import org.hisp.dhis.user.UserCredentials;
@@ -58,7 +57,6 @@
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.stream.Collectors;
@@ -103,7 +101,7 @@
     // Internal and Semi-Public maps
     //-------------------------------------------------------------------------------------------------------
 
-    private List<Class<?>> registeredTypes = Lists.newArrayList();
+    private Set<Class<?>> supportedTypes = new HashSet<>();
 
     private HashMap<Class<?>, Set<?>> masterMap;
 
@@ -130,15 +128,21 @@
     @PostConstruct
     public void postConstruct()
     {
-        registeredTypes.add( PeriodType.class );
-        registeredTypes.add( UserCredentials.class );
-        registeredTypes.addAll( schemaService.getMetadataSchemas().stream().map( Schema::getKlass ).collect( Collectors.toList() ) );
+        supportedTypes.add( PeriodType.class );
+        supportedTypes.add( UserCredentials.class );
+        supportedTypes.addAll( schemaService.getMetadataSchemas().stream().map( Schema::getKlass ).collect( Collectors.toList() ) );
     }
 
     @Override
-    public void init()
+    @SuppressWarnings( "unchecked" )
+    public void init( Set<Class> preheatClasses )
     {
-        log.info( "Building object-bridge maps (preheatCache: " + preheatCache + ")." );
+        if ( preheatClasses.isEmpty() )
+        {
+            preheatClasses.addAll( supportedTypes );
+        }
+
+        log.info( "Building object-bridge maps (preheatCache: " + preheatCache + ", " + preheatClasses.size() + " classes)." );
         Timer timer = new SystemTimer().start();
 
         masterMap = new HashMap<>();
@@ -152,13 +156,22 @@
         populatePeriodTypeMap( PeriodType.class );
         populateUsernameMap( UserCredentials.class );
 
-        for ( Class<?> type : registeredTypes )
+        for ( Class<?> type : supportedTypes )
         {
-            populateIdentifiableObjectMap( type );
-            populateIdentifiableObjectMap( type, IdentifiableProperty.UID );
-            populateIdentifiableObjectMap( type, IdentifiableProperty.UUID );
-            populateIdentifiableObjectMap( type, IdentifiableProperty.CODE );
-            populateIdentifiableObjectMap( type, IdentifiableProperty.NAME );
+            masterMap.put( type, new HashSet<IdentifiableObject>() );
+            uidMap.put( (Class<? extends IdentifiableObject>) type, new HashMap<>() );
+            uuidMap.put( (Class<? extends IdentifiableObject>) type, new HashMap<>() );
+            codeMap.put( (Class<? extends IdentifiableObject>) type, new HashMap<>() );
+            nameMap.put( (Class<? extends IdentifiableObject>) type, new HashMap<>() );
+
+            if ( preheatClasses.contains( type ) )
+            {
+                populateIdentifiableObjectMap( type );
+                populateIdentifiableObjectMap( type, IdentifiableProperty.UID );
+                populateIdentifiableObjectMap( type, IdentifiableProperty.UUID );
+                populateIdentifiableObjectMap( type, IdentifiableProperty.CODE );
+                populateIdentifiableObjectMap( type, IdentifiableProperty.NAME );
+            }
         }
 
         timer.stop();
@@ -185,14 +198,11 @@
     @SuppressWarnings( "unchecked" )
     private void populateIdentifiableObjectMap( Class<?> clazz )
     {
-        Set<IdentifiableObject> map = new HashSet<>();
-
         if ( preheatCache && IdentifiableObject.class.isAssignableFrom( clazz ) )
         {
-            map = new HashSet<>( manager.getAllNoAcl( (Class<IdentifiableObject>) clazz ) );
+            Set<IdentifiableObject> map = (Set<IdentifiableObject>) masterMap.get( clazz );
+            map.addAll( manager.getAllNoAcl( (Class<IdentifiableObject>) clazz ) );
         }
-
-        masterMap.put( clazz, map );
     }
 
     @SuppressWarnings( "unchecked" )
@@ -282,10 +292,8 @@
         if ( UserCredentials.class.isAssignableFrom( clazz ) )
         {
             Collection<UserCredentials> allUserCredentials = userService.getAllUserCredentials();
-
-            allUserCredentials.stream().filter( userCredentials -> userCredentials.getUsername() != null ).forEach( userCredentials -> {
-                usernameMap.put( userCredentials.getUsername(), userCredentials );
-            } );
+            allUserCredentials.stream().filter( userCredentials -> userCredentials.getUsername() != null )
+                .forEach( userCredentials -> usernameMap.put( userCredentials.getUsername(), userCredentials ) );
         }
     }
 
@@ -649,7 +657,7 @@
             map = uuidMap.get( klass );
         }
 
-        if ( !preheatCache && entity == null )
+        if ( entity == null )
         {
             entity = organisationUnitService.getOrganisationUnitByUuid( organisationUnit.getUuid() );
 
@@ -677,7 +685,7 @@
             map = uidMap.get( identifiableObject.getClass() );
         }
 
-        if ( !preheatCache && entity == null )
+        if ( entity == null )
         {
             entity = manager.get( identifiableObject.getClass(), identifiableObject.getUid() );
 
@@ -710,7 +718,7 @@
             return null;
         }
 
-        if ( !preheatCache && entity == null && identifiableObject.haveUniqueCode() )
+        if ( entity == null && identifiableObject.haveUniqueCode() )
         {
             entity = manager.getByCode( identifiableObject.getClass(), identifiableObject.getCode() );
 
@@ -743,7 +751,7 @@
             return null;
         }
 
-        if ( !preheatCache && entity == null && identifiableObject.haveUniqueNames() )
+        if ( entity == null && identifiableObject.haveUniqueNames() )
         {
             entity = manager.getByName( identifiableObject.getClass(), identifiableObject.getName() );
 
@@ -758,7 +766,7 @@
 
     private boolean _typeSupported( Class<?> clazz )
     {
-        for ( Class<?> c : registeredTypes )
+        for ( Class<?> c : supportedTypes )
         {
             if ( c.isAssignableFrom( clazz ) )
             {

=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/ImportService.java'
--- dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/ImportService.java	2015-02-25 06:11:43 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/ImportService.java	2015-09-24 05:44:40 +0000
@@ -29,9 +29,7 @@
  */
 
 import org.hisp.dhis.common.IdentifiableObject;
-import org.hisp.dhis.common.MergeStrategy;
 import org.hisp.dhis.dxf2.common.ImportOptions;
-import org.hisp.dhis.importexport.ImportStrategy;
 import org.hisp.dhis.scheduling.TaskId;
 import org.springframework.stereotype.Service;
 
@@ -41,7 +39,7 @@
 @Service
 public interface ImportService
 {
-    <T extends IdentifiableObject> ImportTypeSummary importObject( String userUid, T object, ImportStrategy importStrategy, MergeStrategy mergeStrategy );
+    <T extends IdentifiableObject> ImportTypeSummary importObject( String userUid, T object, ImportOptions importOptions );
 
     ImportSummary importMetaData( String userUid, MetaData metaData );
 

=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/ObjectBridge.java'
--- dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/ObjectBridge.java	2015-01-19 09:19:46 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/ObjectBridge.java	2015-09-24 05:44:40 +0000
@@ -32,7 +32,7 @@
 
 /**
  * Acts as a bridge between the importer and the persistence/cache layer.
- * <p/>
+ * <p>
  * The flag {@code writeEnabled} is used to indicate if writing to the persistence layer
  * is enabled or not.
  *
@@ -40,8 +40,9 @@
  */
 public interface ObjectBridge
 {
-    void init(); // FIXME rename or remove.. @PostConstruct worked badly here, some kind of workaround would be nice
-    void destroy(); // FIXME
+    void init( Set<Class> preheatClasses );
+
+    void destroy();
 
     /**
      * Save object. Will save to persistence layer if {@code writeEnabled} is {@code true}.

=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/importers/DefaultIdentifiableObjectImporter.java'
--- dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/importers/DefaultIdentifiableObjectImporter.java	2015-09-13 21:54:23 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/importers/DefaultIdentifiableObjectImporter.java	2015-09-24 05:44:40 +0000
@@ -42,6 +42,7 @@
 import org.hisp.dhis.common.DataDimensionItem;
 import org.hisp.dhis.common.IdentifiableObject;
 import org.hisp.dhis.common.NameableObject;
+import org.hisp.dhis.constant.Constant;
 import org.hisp.dhis.dashboard.DashboardItem;
 import org.hisp.dhis.dataelement.CategoryOptionGroupSet;
 import org.hisp.dhis.dataelement.DataElementCategoryDimension;
@@ -607,7 +608,8 @@
                 && !DataElementCategoryOption.class.isAssignableFrom( object.getClass() )
                 && !CategoryOptionGroupSet.class.isAssignableFrom( object.getClass() )
                 && !DashboardItem.class.isAssignableFrom( object.getClass() )
-                && !ProgramStageDataElement.class.isAssignableFrom( object.getClass() ) )
+                && !ProgramStageDataElement.class.isAssignableFrom( object.getClass() )
+                && !Constant.class.isAssignableFrom( object.getClass() ) )
             {
                 conflict = new ImportConflict( ImportUtils.getDisplayName( object ), "Empty shortName for object " + object );
             }

=== modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/AbstractCrudController.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/AbstractCrudController.java	2015-09-17 15:49:41 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/AbstractCrudController.java	2015-09-24 05:44:40 +0000
@@ -28,19 +28,13 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-import java.io.IOException;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.dataformat.xml.XmlMapper;
+import com.google.common.base.Enums;
+import com.google.common.base.Joiner;
+import com.google.common.base.Optional;
+import com.google.common.collect.Lists;
 import org.hisp.dhis.common.BaseIdentifiableObject;
 import org.hisp.dhis.common.IdentifiableObject;
 import org.hisp.dhis.common.IdentifiableObjectManager;
@@ -96,13 +90,18 @@
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.ResponseBody;
 
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.dataformat.xml.XmlMapper;
-import com.google.common.base.Enums;
-import com.google.common.base.Joiner;
-import com.google.common.base.Optional;
-import com.google.common.collect.Lists;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 /**
  * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
@@ -110,7 +109,7 @@
 public abstract class AbstractCrudController<T extends IdentifiableObject>
 {
     protected static final WebOptions NO_WEB_OPTIONS = new WebOptions( new HashMap<>() );
-    
+
     //--------------------------------------------------------------------------
     // Dependencies
     //--------------------------------------------------------------------------
@@ -318,8 +317,11 @@
             property.getSetterMethod().invoke( persistedObject, value );
         }
 
-        ImportTypeSummary importTypeSummary = importService.importObject( currentUserService.getCurrentUser().getUid(), persistedObject,
-            ImportStrategy.UPDATE, MergeStrategy.MERGE );
+        ImportOptions importOptions = new ImportOptions();
+        importOptions.setStrategy( ImportStrategy.UPDATE );
+        importOptions.setMergeStrategy( MergeStrategy.MERGE );
+
+        ImportTypeSummary importTypeSummary = importService.importObject( currentUserService.getCurrentUser().getUid(), persistedObject, importOptions );
 
         webMessageService.send( WebMessageUtils.importTypeSummary( importTypeSummary ), response, request );
     }
@@ -343,16 +345,7 @@
     private List<String> getPersistedProperties( List<String> properties )
     {
         List<String> persistedProperties = new ArrayList<>();
-
-        Schema schema = getSchema();
-
-        for ( String property : properties )
-        {
-            if ( schema.havePersistedProperty( property ) )
-            {
-                persistedProperties.add( property );
-            }
-        }
+        persistedProperties.addAll( properties.stream().filter( getSchema()::havePersistedProperty ).collect( Collectors.toList() ) );
 
         return persistedProperties;
     }
@@ -399,8 +392,10 @@
 
         property.getSetterMethod().invoke( persistedObject, value );
 
-        ImportTypeSummary importTypeSummary = importService.importObject( currentUserService.getCurrentUser().getUid(), persistedObject,
-            ImportStrategy.UPDATE, MergeStrategy.MERGE );
+        ImportOptions importOptions = new ImportOptions();
+        importOptions.setStrategy( ImportStrategy.UPDATE );
+        importOptions.setMergeStrategy( MergeStrategy.MERGE );
+        ImportTypeSummary importTypeSummary = importService.importObject( currentUserService.getCurrentUser().getUid(), persistedObject, importOptions );
 
         webMessageService.send( WebMessageUtils.importTypeSummary( importTypeSummary ), response, request );
     }
@@ -500,8 +495,8 @@
 
         preCreateEntity( parsed );
 
-        ImportTypeSummary importTypeSummary = importService.importObject( currentUserService.getCurrentUser().getUid(), parsed,
-            ImportStrategy.CREATE, importOptions.getMergeStrategy() );
+        importOptions.setStrategy( ImportStrategy.CREATE );
+        ImportTypeSummary importTypeSummary = importService.importObject( currentUserService.getCurrentUser().getUid(), parsed, importOptions );
 
         if ( ImportStatus.SUCCESS.equals( importTypeSummary.getStatus() ) )
         {
@@ -530,8 +525,8 @@
 
         preCreateEntity( parsed );
 
-        ImportTypeSummary importTypeSummary = importService.importObject( currentUserService.getCurrentUser().getUid(), parsed,
-            ImportStrategy.CREATE, importOptions.getMergeStrategy() );
+        importOptions.setStrategy( ImportStrategy.CREATE );
+        ImportTypeSummary importTypeSummary = importService.importObject( currentUserService.getCurrentUser().getUid(), parsed, importOptions );
 
         if ( ImportStatus.SUCCESS.equals( importTypeSummary.getStatus() ) )
         {
@@ -571,8 +566,8 @@
 
         preUpdateEntity( parsed );
 
-        ImportTypeSummary importTypeSummary = importService.importObject( currentUserService.getCurrentUser().getUid(), parsed,
-            ImportStrategy.UPDATE, importOptions.getMergeStrategy() );
+        importOptions.setStrategy( ImportStrategy.UPDATE );
+        ImportTypeSummary importTypeSummary = importService.importObject( currentUserService.getCurrentUser().getUid(), parsed, importOptions );
 
         if ( ImportStatus.SUCCESS.equals( importTypeSummary.getStatus() ) )
         {
@@ -602,8 +597,8 @@
 
         preUpdateEntity( parsed );
 
-        ImportTypeSummary importTypeSummary = importService.importObject( currentUserService.getCurrentUser().getUid(), parsed,
-            ImportStrategy.UPDATE, importOptions.getMergeStrategy() );
+        importOptions.setStrategy( ImportStrategy.UPDATE );
+        ImportTypeSummary importTypeSummary = importService.importObject( currentUserService.getCurrentUser().getUid(), parsed, importOptions );
 
         if ( ImportStatus.SUCCESS.equals( importTypeSummary.getStatus() ) )
         {

=== modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/user/UserController.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/user/UserController.java	2015-09-17 15:49:41 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/user/UserController.java	2015-09-24 05:44:40 +0000
@@ -28,16 +28,8 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-import static org.hisp.dhis.common.IdentifiableObjectUtils.getUids;
-
-import java.io.IOException;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
+import com.google.common.base.Optional;
+import com.google.common.collect.Lists;
 import org.apache.commons.lang3.StringUtils;
 import org.hisp.dhis.common.CodeGenerator;
 import org.hisp.dhis.common.IdentifiableObjectUtils;
@@ -77,8 +69,14 @@
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
 
-import com.google.common.base.Optional;
-import com.google.common.collect.Lists;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import static org.hisp.dhis.common.IdentifiableObjectUtils.getUids;
 
 /**
  * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
@@ -382,17 +380,17 @@
             throw new WebMessageException( WebMessageUtils.conflict( "You must have permissions to create user, or ability to manage at least one user group for the user." ) );
         }
 
-        ImportTypeSummary summary = importService.importObject( currentUserService.getCurrentUser().getUid(), parsed,
-            ImportStrategy.UPDATE, importOptions.getMergeStrategy() );
+        importOptions.setStrategy( ImportStrategy.UPDATE );
+        ImportTypeSummary importTypeSummary = importService.importObject( currentUserService.getCurrentUser().getUid(), parsed, importOptions );
 
-        if ( summary.isStatus( ImportStatus.SUCCESS ) && summary.getImportCount().getUpdated() == 1 )
+        if ( importTypeSummary.isStatus( ImportStatus.SUCCESS ) && importTypeSummary.getImportCount().getUpdated() == 1 )
         {
             User user = userService.getUser( pvUid );
 
             userGroupService.updateUserGroups( user, IdentifiableObjectUtils.getUids( parsed.getGroups() ) );
         }
 
-        renderService.toXml( response.getOutputStream(), summary );
+        renderService.toXml( response.getOutputStream(), importTypeSummary );
     }
 
     @Override
@@ -419,17 +417,17 @@
             throw new WebMessageException( WebMessageUtils.conflict( "You must have permissions to create user, or ability to manage at least one user group for the user." ) );
         }
 
-        ImportTypeSummary summary = importService.importObject( currentUserService.getCurrentUser().getUid(), parsed,
-            ImportStrategy.UPDATE, importOptions.getMergeStrategy() );
+        importOptions.setStrategy( ImportStrategy.UPDATE );
+        ImportTypeSummary importTypeSummary = importService.importObject( currentUserService.getCurrentUser().getUid(), parsed, importOptions );
 
-        if ( summary.isStatus( ImportStatus.SUCCESS ) && summary.getImportCount().getUpdated() == 1 )
+        if ( importTypeSummary.isStatus( ImportStatus.SUCCESS ) && importTypeSummary.getImportCount().getUpdated() == 1 )
         {
             User user = userService.getUser( pvUid );
 
             userGroupService.updateUserGroups( user, IdentifiableObjectUtils.getUids( parsed.getGroups() ) );
         }
 
-        renderService.toJson( response.getOutputStream(), summary );
+        renderService.toJson( response.getOutputStream(), importTypeSummary );
     }
 
     // -------------------------------------------------------------------------
@@ -481,15 +479,17 @@
         user.getUserCredentials().getCatDimensionConstraints().addAll(
             currentUserService.getCurrentUser().getUserCredentials().getCatDimensionConstraints() );
 
-        ImportTypeSummary summary = importService.importObject( currentUserService.getCurrentUser().getUid(), user,
-            ImportStrategy.CREATE, MergeStrategy.MERGE_IF_NOT_NULL );
+        ImportOptions importOptions = new ImportOptions();
+        importOptions.setStrategy( ImportStrategy.CREATE );
+        importOptions.setMergeStrategy( MergeStrategy.MERGE );
+        ImportTypeSummary importTypeSummary = importService.importObject( currentUserService.getCurrentUser().getUid(), user, importOptions );
 
-        if ( summary.isStatus( ImportStatus.SUCCESS ) && summary.getImportCount().getImported() == 1 )
+        if ( importTypeSummary.isStatus( ImportStatus.SUCCESS ) && importTypeSummary.getImportCount().getImported() == 1 )
         {
             userGroupService.addUserToGroups( user, IdentifiableObjectUtils.getUids( user.getGroups() ) );
         }
 
-        return summary;
+        return importTypeSummary;
     }
 
     /**