← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 6511: Added Mergeable interface, implemented in Identifiable, Nameable and Constant. Re-implemented val...

 

------------------------------------------------------------
revno: 6511
committer: Morten Olav Hansen <mortenoh@xxxxxxxxx>
branch nick: dhis2
timestamp: Fri 2012-04-06 23:31:51 +0200
message:
  Added Mergeable interface, implemented in Identifiable, Nameable and Constant. Re-implemented validation for import objects, still wip. Added generic implementatins of newObject and updatedObject.
added:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/Mergeable.java
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/BaseIdentifiableObject.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/BaseNameableObject.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/IdentifiableObject.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/NameableObject.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/constant/Constant.java
  dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/DefaultImportService.java
  dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/importers/AbstractImporter.java
  dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/importers/ConstantImporter.java


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

Your team DHIS 2 developers is subscribed to branch lp:dhis2.
To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/BaseIdentifiableObject.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/BaseIdentifiableObject.java	2012-04-03 10:59:46 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/BaseIdentifiableObject.java	2012-04-06 21:31:51 +0000
@@ -98,6 +98,14 @@
         this.name = name;
     }
 
+    public BaseIdentifiableObject(IdentifiableObject identifiableObject)
+    {
+        this.id = identifiableObject.getId();
+        this.uid = identifiableObject.getUid();
+        this.name = identifiableObject.getName();
+        this.lastUpdated = identifiableObject.getLastUpdated();
+    }
+
     // -------------------------------------------------------------------------
     // Comparable implementation
     // -------------------------------------------------------------------------
@@ -274,4 +282,14 @@
             ", displayName='" + displayName + '\'' +
             '}';
     }
+
+    @Override
+    public void mergeWith( IdentifiableObject other )
+    {
+        this.id = other.getId() == 0 ? this.id : other.getId();
+        this.uid = other.getUid() == null ? this.uid : other.getUid();
+        this.name = other.getName() == null ? this.name : other.getName();
+        this.code = other.getCode() == null ? this.code : other.getCode();
+        this.lastUpdated = other.getLastUpdated() == null ? this.lastUpdated : other.getLastUpdated();
+    }
 }

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/BaseNameableObject.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/BaseNameableObject.java	2012-03-27 17:38:48 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/BaseNameableObject.java	2012-04-06 21:31:51 +0000
@@ -148,4 +148,18 @@
     {
         this.displayDescription = displayDescription;
     }
+
+    @Override
+    public void mergeWith( IdentifiableObject other )
+    {
+        super.mergeWith( other );
+
+        if ( other.getClass().isInstance( this ) )
+        {
+            NameableObject nameableObject = (NameableObject) other;
+
+            this.shortName = nameableObject.getShortName() == null ? this.shortName : nameableObject.getShortName();
+            this.description = nameableObject.getDescription() == null ? this.description : nameableObject.getDescription();
+        }
+    }
 }

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/IdentifiableObject.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/IdentifiableObject.java	2012-03-29 08:52:54 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/IdentifiableObject.java	2012-04-06 21:31:51 +0000
@@ -30,7 +30,7 @@
 import java.util.Date;
 
 public interface IdentifiableObject
-    extends ImportableObject, LinkableObject, Comparable<IdentifiableObject>
+    extends ImportableObject, LinkableObject, Comparable<IdentifiableObject>, Mergeable<IdentifiableObject>
 {
     final String[] I18N_PROPERTIES = { "name" };
     

=== added file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/Mergeable.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/Mergeable.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/Mergeable.java	2012-04-06 21:31:51 +0000
@@ -0,0 +1,36 @@
+package org.hisp.dhis.common;
+
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+/**
+ * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
+ */
+public interface Mergeable<T>
+{
+    void mergeWith( T other );
+}

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/NameableObject.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/NameableObject.java	2012-01-19 04:42:07 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/NameableObject.java	2012-04-06 21:31:51 +0000
@@ -27,7 +27,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-public interface NameableObject 
+public interface NameableObject
     extends IdentifiableObject
 {
     final String[] I18N_PROPERTIES = { "name", "shortName", "description" };

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/constant/Constant.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/constant/Constant.java	2012-03-27 21:38:22 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/constant/Constant.java	2012-04-06 21:31:51 +0000
@@ -33,6 +33,8 @@
 import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
 import org.hisp.dhis.common.BaseIdentifiableObject;
 import org.hisp.dhis.common.Dxf2Namespace;
+import org.hisp.dhis.common.IdentifiableObject;
+import org.hisp.dhis.common.Mergeable;
 import org.hisp.dhis.common.view.DetailedView;
 import org.hisp.dhis.common.view.ExportView;
 
@@ -128,4 +130,16 @@
     {
         this.value = value;
     }
+
+    @Override
+    public void mergeWith( IdentifiableObject other )
+    {
+        super.mergeWith( other );
+
+        if(other.getClass().isInstance( this ))
+        {
+            Constant constant = (Constant) other;
+            this.value = constant.getValue();
+        }
+    }
 }

=== modified file 'dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/DefaultImportService.java'
--- dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/DefaultImportService.java	2012-04-06 14:20:16 +0000
+++ dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/DefaultImportService.java	2012-04-06 21:31:51 +0000
@@ -58,9 +58,7 @@
     {
         if ( !clazzes.isEmpty() )
         {
-            IdentifiableObject identifiableObject = clazzes.get( 0 );
-
-            return findImporterClass( identifiableObject.getClass() );
+            return findImporterClass( clazzes.get( 0 ).getClass() );
         }
 
         return null;
@@ -81,15 +79,18 @@
 
     private void doImport( List<? extends IdentifiableObject> objects, ImportOptions importOptions, ImportSummary importSummary )
     {
-        Importer importer = findImporterClass( objects );
-
-        if ( importer != null )
+        if ( !objects.isEmpty() )
         {
-            List<ImportConflict> conflicts = importer.importCollection( objects, importOptions );
-            ImportCount count = importer.getCurrentImportCount();
-
-            importSummary.getConflicts().addAll( conflicts );
-            importSummary.getCounts().add( count );
+            Importer importer = findImporterClass( objects );
+
+            if ( importer != null )
+            {
+                List<ImportConflict> conflicts = importer.importCollection( objects, importOptions );
+                ImportCount count = importer.getCurrentImportCount();
+
+                importSummary.getConflicts().addAll( conflicts );
+                importSummary.getCounts().add( count );
+            }
         }
     }
 

=== modified file 'dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/importers/AbstractImporter.java'
--- dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/importers/AbstractImporter.java	2012-04-06 14:20:16 +0000
+++ dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/importers/AbstractImporter.java	2012-04-06 21:31:51 +0000
@@ -83,7 +83,7 @@
     protected Map<String, T> codeMap;
 
     //-------------------------------------------------------------------------------------------------------
-    // Abstract methods that sub-classes needs to implement
+    // Generic implementations of newObject and updatedObject
     //-------------------------------------------------------------------------------------------------------
 
     /**
@@ -93,7 +93,18 @@
      * @param options Current import options
      * @return An ImportConflict instance if there was a conflict, otherwise null
      */
-    protected abstract ImportConflict newObject( T object, ImportOptions options );
+    protected ImportConflict newObject( T object, ImportOptions options )
+    {
+        if ( !options.isDryRun() )
+        {
+            log.info( "Trying to save new object with UID: " + object.getUid() );
+            manager.save( object );
+            log.info( "Save successful." );
+            updateIdMaps( object );
+        }
+
+        return null;
+    }
 
     /**
      * Update object from old => new.
@@ -103,7 +114,20 @@
      * @param options   Current import options
      * @return An ImportConflict instance if there was a conflict, otherwise null
      */
-    protected abstract ImportConflict updatedObject( T object, T oldObject, ImportOptions options );
+    protected ImportConflict updatedObject( T object, T oldObject, ImportOptions options )
+    {
+        oldObject.mergeWith( object );
+
+        if ( !options.isDryRun() )
+        {
+            log.info( "Trying to update object with UID: " + oldObject.getUid() );
+            manager.update( oldObject );
+            log.info( "Update successful." );
+
+        }
+
+        return null;
+    }
 
     /**
      * Current object name, used to fill name part of a ImportConflict
@@ -179,6 +203,24 @@
         codeMap = manager.getIdMap( (Class<T>) type.getClass(), IdentifiableObject.IdentifiableProperty.CODE );
     }
 
+    protected void updateIdMaps( T object )
+    {
+        if ( object.getUid() != null )
+        {
+            uidMap.put( object.getUid(), object );
+        }
+
+        if ( object.getName() != null )
+        {
+            nameMap.put( object.getName(), object );
+        }
+
+        if ( object.getCode() != null )
+        {
+            codeMap.put( object.getCode(), object );
+        }
+    }
+
     private ImportConflict importObjectLocal( T object, ImportOptions options )
     {
         ImportConflict conflict = validateIdentifiableObject( object, options );
@@ -188,13 +230,18 @@
             conflict = startImport( object, options );
         }
 
+        if ( conflict != null )
+        {
+            ignores++;
+        }
+
         return conflict;
     }
 
     private ImportConflict startImport( T object, ImportOptions options )
     {
         T oldObject = getObject( object, options.getIdScheme() );
-        ImportConflict conflict = null;
+        ImportConflict conflict;
 
         if ( options.getImportStrategy().isNewStrategy() )
         {
@@ -251,51 +298,169 @@
 
     private ImportConflict validateIdentifiableObject( T object, ImportOptions options )
     {
-        T uidObject = uidMap.get( object );
-        T nameObject = nameMap.get( object );
-        T codeObject = codeMap.get( object );
+        T uidObject = uidMap.get( object.getUid() );
+        T nameObject = nameMap.get( object.getName() );
+        T codeObject = codeMap.get( object.getCode() );
 
         ImportConflict conflict = null;
 
         if ( options.getImportStrategy().isNewStrategy() )
         {
-            if ( uidObject != null )
-            {
-                conflict = new ImportConflict( getDisplayName( object, options.getIdScheme() ), "Object fails uniqueness constraint on identifier uid." );
-            }
-
-            if ( nameObject != null )
-            {
-                conflict = new ImportConflict( getDisplayName( object, options.getIdScheme() ), "Object fails uniqueness constraint on identifier name." );
-            }
-
-            if ( codeObject != null )
-            {
-                conflict = new ImportConflict( getDisplayName( object, options.getIdScheme() ), "Object fails uniqueness constraint on identifier code." );
-            }
+            conflict = validateForNewStrategy( object, options );
         }
         else if ( options.getImportStrategy().isUpdatesStrategy() )
         {
-            if ( options.getIdScheme().isUidScheme() && uidObject == null )
-            {
-                conflict = new ImportConflict( getDisplayName( object, options.getIdScheme() ), "Object does not exist, did lookup with identifier uid." );
-            }
-
-            if ( options.getIdScheme().isNameScheme() && nameObject == null )
-            {
-                conflict = new ImportConflict( getDisplayName( object, options.getIdScheme() ), "Object does not exist, did lookup with identifier name." );
-            }
-
-            if ( options.getIdScheme().isCodeScheme() && codeObject == null )
-            {
-                conflict = new ImportConflict( getDisplayName( object, options.getIdScheme() ), "Object does not exist, did lookup with identifier code." );
-            }
+            conflict = validateForUpdatesStrategy( object, options );
         }
         else if ( options.getImportStrategy().isNewAndUpdatesStrategy() )
         {
-        }
-
-        return conflict;
+            if ( options.getIdScheme().isUidScheme() )
+            {
+                if ( uidObject == null )
+                {
+                    conflict = validateForNewStrategy( object, options );
+                }
+                else
+                {
+                    conflict = validateForUpdatesStrategy( object, options );
+                }
+            }
+            else if ( options.getIdScheme().isNameScheme() )
+            {
+                if ( nameObject == null )
+                {
+                    conflict = validateForNewStrategy( object, options );
+                }
+                else
+                {
+                    conflict = validateForUpdatesStrategy( object, options );
+                }
+            }
+            else if ( options.getIdScheme().isCodeScheme() )
+            {
+                if ( codeObject == null )
+                {
+                    conflict = validateForNewStrategy( object, options );
+                }
+                else
+                {
+                    conflict = validateForUpdatesStrategy( object, options );
+                }
+            }
+        }
+
+        return conflict;
+    }
+
+    private ImportConflict validateForUpdatesStrategy( T object, ImportOptions options )
+    {
+        T uidObject = uidMap.get( object.getUid() );
+        T nameObject = nameMap.get( object.getName() );
+        T codeObject = codeMap.get( object.getCode() );
+
+        ImportConflict conflict = null;
+
+        if ( options.getIdScheme().isUidScheme() )
+        {
+            if ( uidObject == null )
+            {
+                conflict = reportUidLookupConflict( object, options );
+            }
+            else if ( nameObject != null && nameObject != uidObject )
+            {
+                conflict = reportNameConflict( object, options );
+            }
+            else if ( codeObject != null && codeObject != uidObject )
+            {
+                conflict = reportCodeConflict( object, options );
+            }
+        }
+        else if ( options.getIdScheme().isNameScheme() )
+        {
+            if ( nameObject == null )
+            {
+                conflict = reportNameLookupConflict( object, options );
+            }
+            else if ( uidObject != null && uidObject != nameObject )
+            {
+                conflict = reportNameConflict( object, options );
+            }
+            else if ( codeObject != null && codeObject != nameObject )
+            {
+                conflict = reportCodeConflict( object, options );
+            }
+        }
+        else if ( options.getIdScheme().isCodeScheme() )
+        {
+            if ( codeObject == null )
+            {
+                conflict = reportCodeLookupConflict( object, options );
+            }
+            else if ( uidObject != null && uidObject != codeObject )
+            {
+                conflict = reportNameConflict( object, options );
+            }
+            else if ( nameObject != null && nameObject != codeObject )
+            {
+                conflict = reportCodeConflict( object, options );
+            }
+        }
+
+        return conflict;
+    }
+
+    private ImportConflict validateForNewStrategy( T object, ImportOptions options )
+    {
+        T uidObject = uidMap.get( object.getUid() );
+        T nameObject = nameMap.get( object.getName() );
+        T codeObject = codeMap.get( object.getCode() );
+
+        ImportConflict conflict = null;
+
+        if ( uidObject != null )
+        {
+            conflict = reportUidConflict( object, options );
+        }
+        else if ( nameObject != null )
+        {
+            conflict = reportNameConflict( object, options );
+        }
+        else if ( codeObject != null )
+        {
+            conflict = reportCodeConflict( object, options );
+        }
+
+        return conflict;
+    }
+
+    private ImportConflict reportUidLookupConflict( IdentifiableObject object, ImportOptions options )
+    {
+        return new ImportConflict( getDisplayName( object, options.getIdScheme() ), "UID LOOKUP CONFLICT" );
+    }
+
+    private ImportConflict reportNameLookupConflict( IdentifiableObject object, ImportOptions options )
+    {
+        return new ImportConflict( getDisplayName( object, options.getIdScheme() ), "NAME LOOKUP CONFLICT" );
+    }
+
+    private ImportConflict reportCodeLookupConflict( IdentifiableObject object, ImportOptions options )
+    {
+        return new ImportConflict( getDisplayName( object, options.getIdScheme() ), "CODE LOOKUP CONFLICT" );
+    }
+
+    private ImportConflict reportUidConflict( IdentifiableObject object, ImportOptions options )
+    {
+        return new ImportConflict( getDisplayName( object, options.getIdScheme() ), "UID CONFLICT" );
+    }
+
+    private ImportConflict reportNameConflict( IdentifiableObject object, ImportOptions options )
+    {
+        return new ImportConflict( getDisplayName( object, options.getIdScheme() ), "NAME CONFLICT" );
+    }
+
+    private ImportConflict reportCodeConflict( IdentifiableObject object, ImportOptions options )
+    {
+        return new ImportConflict( getDisplayName( object, options.getIdScheme() ), "CODE CONFLICT" );
     }
 
     private T getObject( T object, IdScheme scheme )
@@ -318,9 +483,13 @@
 
     protected void prepareIdentifiableObject( BaseIdentifiableObject object )
     {
-        if ( object.getUid() == null )
-        {
-            object.setUid( generateUid() );
+        if ( object.getUid() == null && object.getLastUpdated() == null )
+        {
+            object.setAutoFields();
+        }
+        else if ( object.getUid() == null )
+        {
+            object.setUid( CodeGenerator.generateCode() );
         }
     }
 

=== modified file 'dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/importers/ConstantImporter.java'
--- dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/importers/ConstantImporter.java	2012-04-06 14:20:16 +0000
+++ dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/importers/ConstantImporter.java	2012-04-06 21:31:51 +0000
@@ -30,8 +30,6 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.hisp.dhis.constant.Constant;
-import org.hisp.dhis.dxf2.importsummary.ImportConflict;
-import org.hisp.dhis.dxf2.metadata.ImportOptions;
 import org.springframework.stereotype.Component;
 
 /**
@@ -44,34 +42,6 @@
     private static final Log log = LogFactory.getLog( ConstantImporter.class );
 
     @Override
-    protected ImportConflict newObject( Constant constant, ImportOptions options )
-    {
-        if ( !options.isDryRun() )
-        {
-            log.info( "Trying to save new object with UID: " + constant.getUid() );
-            manager.save( constant );
-            log.info( "Save successful." );
-        }
-
-        return null;
-    }
-
-    @Override
-    protected ImportConflict updatedObject( Constant constant, Constant oldConstant, ImportOptions options )
-    {
-        oldConstant.setValue( constant.getValue() );
-
-        if ( !options.isDryRun() )
-        {
-            log.info( "Trying to update object with UID: " + oldConstant.getUid() );
-            manager.update( oldConstant );
-            log.info( "Update successful." );
-        }
-
-        return null;
-    }
-
-    @Override
     protected String getObjectName()
     {
         return this.getClass().getName();