← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 6675: Implemented 'ObjectBridge', object proxy between the storage backend of the importers and the act...

 

------------------------------------------------------------
revno: 6675
committer: Morten Olav Hansen <mortenoh@xxxxxxxxx>
branch nick: dhis2
timestamp: Sun 2012-04-22 19:16:24 +0300
message:
  Implemented 'ObjectBridge', object proxy between the storage backend of the importers and the actual persistence store. This enables 'dryRun' and also makes it work correctly with newly introduced objects that might not have been there in the old internal maps. Another feature of this is that reference scanning is about 1000% faster (not measured, its really slow vs really fast).
added:
  dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/DefaultObjectBridge.java
  dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/ObjectBridge.java
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementCategoryCombo.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementCategoryOption.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnit.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnitGroupSet.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/ExportOptions.java
  dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/importers/DefaultIdentifiableObjectImporter.java
  dhis-2/dhis-dxf2/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-api/src/main/java/org/hisp/dhis/dataelement/DataElementCategoryCombo.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementCategoryCombo.java	2012-04-20 18:31:48 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementCategoryCombo.java	2012-04-22 16:16:24 +0000
@@ -152,7 +152,6 @@
     }
 
     //TODO update category option -> category option combo association
-
     public void generateOptionCombos()
     {
         this.optionCombos = new HashSet<DataElementCategoryOptionCombo>( generateOptionCombosList() );

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementCategoryOption.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementCategoryOption.java	2012-04-20 18:31:48 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementCategoryOption.java	2012-04-22 16:16:24 +0000
@@ -39,6 +39,7 @@
 import org.hisp.dhis.common.Dxf2Namespace;
 import org.hisp.dhis.common.IdentifiableObject;
 import org.hisp.dhis.common.view.DetailedView;
+import org.hisp.dhis.common.view.ExportView;
 import org.hisp.dhis.concept.Concept;
 
 import java.util.HashSet;
@@ -166,6 +167,10 @@
         this.category = category;
     }
 
+    @JsonProperty
+    @JsonSerialize( contentAs = BaseIdentifiableObject.class )
+    @JsonView( {DetailedView.class, ExportView.class} )
+    @JacksonXmlProperty( namespace = Dxf2Namespace.NAMESPACE )
     public Concept getConcept()
     {
         return concept;

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnit.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnit.java	2012-04-18 20:24:12 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnit.java	2012-04-22 16:16:24 +0000
@@ -94,15 +94,6 @@
 
     private String url;
 
-    @Scanned
-    private Set<OrganisationUnitGroup> groups = new HashSet<OrganisationUnitGroup>();
-
-    @Scanned
-    private Set<DataSet> dataSets = new HashSet<DataSet>();
-
-    @Scanned
-    private Set<User> users = new HashSet<User>();
-
     private String contactPerson;
 
     private String address;
@@ -113,6 +104,12 @@
 
     private boolean hasPatients;
 
+    private Set<OrganisationUnitGroup> groups = new HashSet<OrganisationUnitGroup>();
+
+    private Set<DataSet> dataSets = new HashSet<DataSet>();
+
+    private Set<User> users = new HashSet<User>();
+
     /**
      * Set of the dynamic attributes values that belong to this
      * organisationUnit.
@@ -695,51 +692,6 @@
         this.url = url;
     }
 
-    @JsonProperty( value = "organisationUnitGroups" )
-    @JsonSerialize( contentAs = BaseIdentifiableObject.class )
-    @JsonView( {DetailedView.class} )
-    @JacksonXmlElementWrapper( localName = "organisationUnitGroups", namespace = Dxf2Namespace.NAMESPACE )
-    @JacksonXmlProperty( localName = "organisationUnitGroup", namespace = Dxf2Namespace.NAMESPACE )
-    public Set<OrganisationUnitGroup> getGroups()
-    {
-        return groups;
-    }
-
-    public void setGroups( Set<OrganisationUnitGroup> groups )
-    {
-        this.groups = groups;
-    }
-
-    @JsonProperty
-    @JsonSerialize( contentAs = BaseIdentifiableObject.class )
-    @JsonView( {DetailedView.class} )
-    @JacksonXmlElementWrapper( localName = "dataSets", namespace = Dxf2Namespace.NAMESPACE )
-    @JacksonXmlProperty( localName = "dataSet", namespace = Dxf2Namespace.NAMESPACE )
-    public Set<DataSet> getDataSets()
-    {
-        return dataSets;
-    }
-
-    public void setDataSets( Set<DataSet> dataSets )
-    {
-        this.dataSets = dataSets;
-    }
-
-    @JsonProperty
-    @JsonSerialize( contentAs = BaseIdentifiableObject.class )
-    @JsonView( {DetailedView.class} )
-    @JacksonXmlElementWrapper( localName = "users", namespace = Dxf2Namespace.NAMESPACE )
-    @JacksonXmlProperty( localName = "user", namespace = Dxf2Namespace.NAMESPACE )
-    public Set<User> getUsers()
-    {
-        return users;
-    }
-
-    public void setUsers( Set<User> users )
-    {
-        this.users = users;
-    }
-
     @JsonProperty
     @JsonView( {DetailedView.class, ExportView.class} )
     @JacksonXmlProperty( namespace = Dxf2Namespace.NAMESPACE )
@@ -818,6 +770,51 @@
         this.type = type;
     }
 
+    @JsonProperty( value = "organisationUnitGroups" )
+    @JsonSerialize( contentAs = BaseIdentifiableObject.class )
+    @JsonView( {DetailedView.class} )
+    @JacksonXmlElementWrapper( localName = "organisationUnitGroups", namespace = Dxf2Namespace.NAMESPACE )
+    @JacksonXmlProperty( localName = "organisationUnitGroup", namespace = Dxf2Namespace.NAMESPACE )
+    public Set<OrganisationUnitGroup> getGroups()
+    {
+        return groups;
+    }
+
+    public void setGroups( Set<OrganisationUnitGroup> groups )
+    {
+        this.groups = groups;
+    }
+
+    @JsonProperty
+    @JsonSerialize( contentAs = BaseIdentifiableObject.class )
+    @JsonView( {DetailedView.class} )
+    @JacksonXmlElementWrapper( localName = "dataSets", namespace = Dxf2Namespace.NAMESPACE )
+    @JacksonXmlProperty( localName = "dataSet", namespace = Dxf2Namespace.NAMESPACE )
+    public Set<DataSet> getDataSets()
+    {
+        return dataSets;
+    }
+
+    public void setDataSets( Set<DataSet> dataSets )
+    {
+        this.dataSets = dataSets;
+    }
+
+    @JsonProperty
+    @JsonSerialize( contentAs = BaseIdentifiableObject.class )
+    @JsonView( {DetailedView.class} )
+    @JacksonXmlElementWrapper( localName = "users", namespace = Dxf2Namespace.NAMESPACE )
+    @JacksonXmlProperty( localName = "user", namespace = Dxf2Namespace.NAMESPACE )
+    public Set<User> getUsers()
+    {
+        return users;
+    }
+
+    public void setUsers( Set<User> users )
+    {
+        this.users = users;
+    }
+
     @JsonProperty( value = "attributes" )
     @JsonView( {DetailedView.class, ExportView.class} )
     @JacksonXmlElementWrapper( localName = "attributes", namespace = Dxf2Namespace.NAMESPACE )

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnitGroupSet.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnitGroupSet.java	2012-04-20 18:31:48 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnitGroupSet.java	2012-04-22 16:16:24 +0000
@@ -57,13 +57,13 @@
 
     private static final Comparator<IdentifiableObject> COMPARATOR = new IdentifiableObjectNameComparator();
 
+    private String description;
+
+    private boolean compulsory;
+
     @Scanned
     private Set<OrganisationUnitGroup> organisationUnitGroups = new HashSet<OrganisationUnitGroup>();
 
-    private String description;
-
-    private boolean compulsory;
-
     // -------------------------------------------------------------------------
     // Constructors
     // -------------------------------------------------------------------------

=== 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-21 11:45:47 +0000
+++ dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/DefaultImportService.java	2012-04-22 16:16:24 +0000
@@ -29,6 +29,7 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.hisp.dhis.cache.HibernateCacheManager;
 import org.hisp.dhis.dxf2.importsummary.ImportConflict;
 import org.hisp.dhis.dxf2.importsummary.ImportCount;
 import org.hisp.dhis.dxf2.importsummary.ImportSummary;
@@ -36,6 +37,7 @@
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.util.Date;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -57,6 +59,12 @@
     @Autowired( required = false )
     private Set<Importer> importerClasses = new HashSet<Importer>();
 
+    @Autowired
+    private ObjectBridge objectBridge;
+
+    @Autowired
+    private HibernateCacheManager cacheManager;
+
     //-------------------------------------------------------------------------------------------------------
     // ImportService Implementation
     //-------------------------------------------------------------------------------------------------------
@@ -71,26 +79,41 @@
     public ImportSummary importMetaData( MetaData metaData, ImportOptions importOptions )
     {
         ImportSummary importSummary = new ImportSummary();
-
-        // Imports.. this could be made even more generic, just need to make sure that everything is imported in
-        // the correct order
-
+        objectBridge.init();
+
+        Date startDate = new Date();
+
+        doImport( metaData.getOrganisationUnits(), importOptions, importSummary );
+        // doImport( metaData.getOrganisationUnitLevels(), importOptions, importSummary );
+        doImport( metaData.getOrganisationUnitGroups(), importOptions, importSummary );
+        doImport( metaData.getOrganisationUnitGroupSets(), importOptions, importSummary );
+
+/*
+        doImport( metaData.getUsers(), importOptions, importSummary );
+        doImport( metaData.getUserGroups(), importOptions, importSummary );
+        doImport( metaData.getUserAuthorityGroups(), importOptions, importSummary );
+*/
+
+/*
         doImport( metaData.getConcepts(), importOptions, importSummary );
         doImport( metaData.getConstants(), importOptions, importSummary );
         doImport( metaData.getDocuments(), importOptions, importSummary );
         doImport( metaData.getAttributeTypes(), importOptions, importSummary );
         doImport( metaData.getOptionSets(), importOptions, importSummary );
+*/
 
-        /*
+/*
+        doImport( metaData.getCategoryOptions(), importOptions, importSummary );
         doImport( metaData.getCategories(), importOptions, importSummary );
         doImport( metaData.getCategoryCombos(), importOptions, importSummary );
-        doImport( metaData.getCategoryOptions(), importOptions, importSummary );
         doImport( metaData.getCategoryOptionCombos(), importOptions, importSummary );
+
         doImport( metaData.getDataElements(), importOptions, importSummary );
         doImport( metaData.getDataElementGroups(), importOptions, importSummary );
         doImport( metaData.getDataElementGroupSets(), importOptions, importSummary );
-        */
+*/
 
+/*
         doImport( metaData.getIndicatorTypes(), importOptions, importSummary );
         doImport( metaData.getIndicators(), importOptions, importSummary );
         doImport( metaData.getIndicatorGroups(), importOptions, importSummary );
@@ -101,14 +124,7 @@
         doImport( metaData.getMapLegendSets(), importOptions, importSummary );
         doImport( metaData.getMapLayers(), importOptions, importSummary );
         // doImport( metaData.getMessageConversations(), importOptions, importSummary );
-        doImport( metaData.getOrganisationUnits(), importOptions, importSummary );
-        // doImport( metaData.getOrganisationUnitLevels(), importOptions, importSummary );
-        doImport( metaData.getOrganisationUnitGroups(), importOptions, importSummary );
-        doImport( metaData.getOrganisationUnitGroupSets(), importOptions, importSummary );
         doImport( metaData.getSqlViews(), importOptions, importSummary );
-        doImport( metaData.getUsers(), importOptions, importSummary );
-        doImport( metaData.getUserGroups(), importOptions, importSummary );
-        doImport( metaData.getUserAuthorityGroups(), importOptions, importSummary );
 
         doImport( metaData.getValidationRules(), importOptions, importSummary );
         doImport( metaData.getValidationRuleGroups(), importOptions, importSummary );
@@ -119,6 +135,13 @@
         doImport( metaData.getCharts(), importOptions, importSummary );
 
         doImport( metaData.getDataSets(), importOptions, importSummary );
+*/
+        Date endDate = new Date();
+        log.info( "Started import at " + startDate );
+        log.info( "Finished import at " + endDate );
+
+        objectBridge.destroy();
+        cacheManager.clearCache();
 
         return importSummary;
     }

=== added file 'dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/DefaultObjectBridge.java'
--- dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/DefaultObjectBridge.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/DefaultObjectBridge.java	2012-04-22 16:16:24 +0000
@@ -0,0 +1,445 @@
+package org.hisp.dhis.dxf2.metadata;
+
+/*
+ * 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.
+ */
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hisp.dhis.common.IdentifiableObject;
+import org.hisp.dhis.common.IdentifiableObjectManager;
+import org.hisp.dhis.common.NameableObject;
+import org.hisp.dhis.organisationunit.OrganisationUnit;
+import org.hisp.dhis.organisationunit.OrganisationUnitGroup;
+import org.hisp.dhis.organisationunit.OrganisationUnitGroupSet;
+import org.hisp.dhis.period.PeriodStore;
+import org.hisp.dhis.period.PeriodType;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.*;
+
+/**
+ * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
+ */
+@Component
+@Transactional( readOnly = true )
+public class DefaultObjectBridge
+    implements ObjectBridge
+{
+    private static final Log log = LogFactory.getLog( DefaultObjectBridge.class );
+
+    //-------------------------------------------------------------------------------------------------------
+    // Dependencies
+    //-------------------------------------------------------------------------------------------------------
+
+    @Autowired
+    private IdentifiableObjectManager manager;
+
+    @Autowired
+    private PeriodStore periodStore;
+
+    //-------------------------------------------------------------------------------------------------------
+    // Internal and Semi-Public maps
+    //-------------------------------------------------------------------------------------------------------
+
+    private Map<Class<?>, Collection<?>> masterMap = new HashMap<Class<?>, Collection<?>>();
+
+    private Map<String, PeriodType> periodTypeMap = new HashMap<String, PeriodType>();
+
+    private Map<Class<? extends IdentifiableObject>, Map<String, IdentifiableObject>> uidMap = new HashMap<Class<? extends IdentifiableObject>, Map<String, IdentifiableObject>>();
+
+    private Map<Class<? extends IdentifiableObject>, Map<String, IdentifiableObject>> codeMap = new HashMap<Class<? extends IdentifiableObject>, Map<String, IdentifiableObject>>();
+
+    private Map<Class<? extends IdentifiableObject>, Map<String, IdentifiableObject>> nameMap = new HashMap<Class<? extends IdentifiableObject>, Map<String, IdentifiableObject>>();
+
+    private Map<Class<? extends NameableObject>, Map<String, NameableObject>> shortNameMap = new HashMap<Class<? extends NameableObject>, Map<String, NameableObject>>();
+
+    private static final List<Class<?>> registeredTypes = new ArrayList<Class<?>>();
+
+    private boolean writeEnabled = true;
+
+    //-------------------------------------------------------------------------------------------------------
+    // Build maps
+    //-------------------------------------------------------------------------------------------------------
+
+    static
+    {
+        registeredTypes.add( PeriodType.class );
+        registeredTypes.add( OrganisationUnit.class );
+        registeredTypes.add( OrganisationUnitGroup.class );
+        registeredTypes.add( OrganisationUnitGroupSet.class );
+    }
+
+    @Override
+    public void init()
+    {
+        log.info( "Started updating lookup maps at " + new Date() );
+
+        for ( Class<?> type : registeredTypes )
+        {
+            populatePeriodTypeMap( type );
+            populateIdentifiableObjectMap( type );
+            populateIdentifiableObjectMap( type, IdentifiableObject.IdentifiableProperty.UID );
+            populateIdentifiableObjectMap( type, IdentifiableObject.IdentifiableProperty.CODE );
+            populateIdentifiableObjectMap( type, IdentifiableObject.IdentifiableProperty.NAME );
+            populateNameableObjectMap( type, NameableObject.NameableProperty.SHORT_NAME );
+        }
+
+        log.info( "Finished updating lookup maps at " + new Date() );
+    }
+
+    @Override
+    public void destroy()
+    {
+        masterMap = null;
+
+        uidMap = null;
+        codeMap = null;
+        nameMap = null;
+        shortNameMap = null;
+
+        periodTypeMap = null;
+    }
+
+    //-------------------------------------------------------------------------------------------------------
+    // Populate Helpers
+    //-------------------------------------------------------------------------------------------------------
+
+    @SuppressWarnings( "unchecked" )
+    private void populateIdentifiableObjectMap( Class<?> clazz )
+    {
+        Collection<IdentifiableObject> map = new ArrayList<IdentifiableObject>();
+
+        if ( IdentifiableObject.class.isAssignableFrom( clazz ) )
+        {
+            map = manager.getAll( (Class<IdentifiableObject>) clazz );
+        }
+
+        if ( map != null )
+        {
+            masterMap.put( clazz, map );
+        }
+    }
+
+    @SuppressWarnings( "unchecked" )
+    private void populateIdentifiableObjectMap( Class<?> clazz, IdentifiableObject.IdentifiableProperty property )
+    {
+        Map<String, IdentifiableObject> map = new HashMap<String, IdentifiableObject>();
+
+        if ( IdentifiableObject.class.isAssignableFrom( clazz ) )
+        {
+            map = (Map<String, IdentifiableObject>) manager.getIdMap( (Class<? extends IdentifiableObject>) clazz, property );
+        }
+
+        if ( map != null )
+        {
+            if ( property == IdentifiableObject.IdentifiableProperty.UID )
+            {
+                uidMap.put( (Class<? extends IdentifiableObject>) clazz, map );
+            }
+            else if ( property == IdentifiableObject.IdentifiableProperty.CODE )
+            {
+                codeMap.put( (Class<? extends IdentifiableObject>) clazz, map );
+            }
+            else if ( property == IdentifiableObject.IdentifiableProperty.NAME )
+            {
+                nameMap.put( (Class<? extends IdentifiableObject>) clazz, map );
+            }
+        }
+    }
+
+    @SuppressWarnings( "unchecked" )
+    private void populateNameableObjectMap( Class<?> clazz, NameableObject.NameableProperty property )
+    {
+        Map<String, NameableObject> map = null;
+
+        if ( NameableObject.class.isAssignableFrom( clazz ) )
+        {
+            map = (Map<String, NameableObject>) manager.getIdMap( (Class<? extends NameableObject>) clazz, property );
+        }
+
+        if ( map != null )
+        {
+            if ( property == NameableObject.NameableProperty.SHORT_NAME )
+            {
+                shortNameMap.put( (Class<? extends NameableObject>) clazz, map );
+            }
+        }
+    }
+
+    private void populatePeriodTypeMap( Class<?> clazz )
+    {
+        Collection<Object> periodTypes = new ArrayList<Object>();
+
+        if ( PeriodType.class.isAssignableFrom( clazz ) )
+        {
+            for ( PeriodType periodType : periodStore.getAllPeriodTypes() )
+            {
+                periodTypes.add( periodType );
+                periodTypeMap.put( periodType.getName(), periodType );
+            }
+        }
+
+        masterMap.put( clazz, periodTypes );
+    }
+
+    //-------------------------------------------------------------------------------------------------------
+    // ObjectBridge Implementation
+    //-------------------------------------------------------------------------------------------------------
+
+    @Override
+    @Transactional( readOnly = false )
+    public void saveObject( Object object )
+    {
+        if ( IdentifiableObject.class.isInstance( object ) )
+        {
+            if ( writeEnabled )
+            {
+                manager.save( (IdentifiableObject) object );
+            }
+        }
+        else
+        {
+            log.warn( "Trying to save unsupported type.. object discarded." );
+        }
+    }
+
+    @Override
+    @Transactional( readOnly = false )
+    public void updateObject( Object object )
+    {
+        if ( IdentifiableObject.class.isInstance( object ) )
+        {
+            if ( writeEnabled )
+            {
+                manager.update( (IdentifiableObject) object );
+            }
+
+            _updateInternalMaps( object );
+        }
+        else
+        {
+            log.warn( "Trying to update unsupported type.. object discarded." );
+        }
+    }
+
+    @Override
+    @SuppressWarnings( "unchecked" )
+    public <T> T getObject( T object )
+    {
+        Collection<T> objects = _findMatches( object );
+
+        if ( objects.size() == 1 )
+        {
+            return objects.iterator().next();
+        }
+        else if ( objects.size() > 1 )
+        {
+            log.warn( "Multiple objects found.. object discarded, returning null." );
+        }
+        else
+        {
+            log.warn( "No object found, returning null." );
+        }
+
+        return null;
+    }
+
+    @Override
+    public <T> Collection<T> getObjects( T object )
+    {
+        return _findMatches( object );
+    }
+
+    @Override
+    @SuppressWarnings( "unchecked" )
+    public <T> Collection<T> getAllObjects( Class<T> clazz )
+    {
+        return (Collection<T>) masterMap.get( clazz );
+    }
+
+    public Map<Class<?>, Collection<?>> getMasterMap()
+    {
+        return masterMap;
+    }
+
+    public void setMasterMap( Map<Class<?>, Collection<?>> masterMap )
+    {
+        this.masterMap = masterMap;
+    }
+
+    @Override
+    public void setWriteEnabled( boolean enabled )
+    {
+        this.writeEnabled = enabled;
+    }
+
+    @Override
+    public boolean isWriteEnabled()
+    {
+        return writeEnabled;
+    }
+
+    //-------------------------------------------------------------------------------------------------------
+    // Internal Methods
+    //-------------------------------------------------------------------------------------------------------
+
+    @SuppressWarnings( "unchecked" )
+    private <T> Collection<T> _findMatches( T object )
+    {
+        Collection<T> objects = new HashSet<T>();
+
+        if ( PeriodType.class.isInstance( object ) )
+        {
+            PeriodType periodType = (PeriodType) object;
+            periodType = periodTypeMap.get( periodType.getName() );
+
+            if ( periodType != null )
+            {
+                objects.add( (T) periodType );
+            }
+        }
+
+        if ( IdentifiableObject.class.isInstance( object ) )
+        {
+            IdentifiableObject identifiableObject = (IdentifiableObject) object;
+
+            if ( identifiableObject.getUid() != null )
+            {
+                IdentifiableObject match = uidMap.get( identifiableObject.getClass() ).get( identifiableObject.getUid() );
+
+                if ( match != null )
+                {
+                    objects.add( (T) match );
+                }
+            }
+
+            if ( identifiableObject.getCode() != null )
+            {
+                IdentifiableObject match = codeMap.get( identifiableObject.getClass() ).get( identifiableObject.getCode() );
+
+                if ( match != null )
+                {
+                    objects.add( (T) match );
+                }
+            }
+
+            if ( identifiableObject.getName() != null )
+            {
+                IdentifiableObject match = nameMap.get( identifiableObject.getClass() ).get( identifiableObject.getName() );
+
+                if ( match != null )
+                {
+                    objects.add( (T) match );
+                }
+            }
+        }
+
+        if ( NameableObject.class.isInstance( object ) )
+        {
+            NameableObject nameableObject = (NameableObject) object;
+
+            if ( nameableObject.getShortName() != null )
+            {
+                IdentifiableObject match = shortNameMap.get( nameableObject.getClass() ).get( nameableObject.getShortName() );
+
+                if ( match != null )
+                {
+                    objects.add( (T) match );
+                }
+            }
+        }
+
+        return objects;
+    }
+
+    private <T> void _updateInternalMaps( T object )
+    {
+        if ( IdentifiableObject.class.isInstance( object ) )
+        {
+            IdentifiableObject identifiableObject = (IdentifiableObject) object;
+
+            if ( identifiableObject.getUid() != null )
+            {
+                Map<String, IdentifiableObject> map = uidMap.get( identifiableObject.getClass() );
+
+                if ( map == null )
+                {
+                    // might be dynamically sub-classed by javassist or cglib, fetch superclass and try again
+                    map = uidMap.get( identifiableObject.getClass().getSuperclass() );
+                }
+
+                map.put( identifiableObject.getUid(), identifiableObject );
+            }
+
+            if ( identifiableObject.getCode() != null )
+            {
+                Map<String, IdentifiableObject> map = codeMap.get( identifiableObject.getClass() );
+
+                if ( map == null )
+                {
+                    // might be dynamically sub-classed by javassist or cglib, fetch superclass and try again
+                    map = uidMap.get( identifiableObject.getClass().getSuperclass() );
+                }
+
+                map.put( identifiableObject.getCode(), identifiableObject );
+            }
+
+            if ( identifiableObject.getName() != null )
+            {
+                Map<String, IdentifiableObject> map = uidMap.get( identifiableObject.getClass() );
+
+                if ( map == null )
+                {
+                    // might be dynamically sub-classed by javassist or cglib, fetch superclass and try again
+                    map = uidMap.get( identifiableObject.getClass().getSuperclass() );
+                }
+
+                map.put( identifiableObject.getName(), identifiableObject );
+            }
+        }
+
+        if ( NameableObject.class.isInstance( object ) )
+        {
+            NameableObject nameableObject = (NameableObject) object;
+
+            if ( nameableObject.getShortName() != null )
+            {
+                Map<String, NameableObject> map = shortNameMap.get( nameableObject.getClass() );
+
+                if ( map == null )
+                {
+                    // might be dynamically sub-classed by javassist or cglib, fetch superclass and try again
+                    map = shortNameMap.get( nameableObject.getClass().getSuperclass() );
+                }
+
+                map.put( nameableObject.getShortName(), nameableObject );
+            }
+        }
+    }
+}

=== modified file 'dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/ExportOptions.java'
--- dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/ExportOptions.java	2012-04-01 12:24:57 +0000
+++ dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/ExportOptions.java	2012-04-22 16:16:24 +0000
@@ -49,14 +49,14 @@
     // means it can be used as a simple argument in controller methods.
     //--------------------------------------------------------------------------
 
+    private boolean users = true;
+
+    private boolean userAuthorityGroups = true;
+
+    private boolean userGroups = true;
+
     private boolean attributeTypes = true;
 
-    private boolean users = false;
-
-    private boolean userAuthorityGroups = false;
-
-    private boolean userGroups = false;
-
     private boolean messageConversations = false;
 
     private boolean dataElements = true;
@@ -107,7 +107,7 @@
 
     private boolean reportTables = true;
 
-    private boolean documents = false;
+    private boolean documents = true;
 
     private boolean constants = true;
 

=== added file 'dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/ObjectBridge.java'
--- dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/ObjectBridge.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/ObjectBridge.java	2012-04-22 16:16:24 +0000
@@ -0,0 +1,99 @@
+package org.hisp.dhis.dxf2.metadata;
+
+/*
+ * 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.
+ */
+
+import java.util.Collection;
+
+/**
+ * Acts as a bridge between the importer and the persistence/cache layer.
+ * <p/>
+ * The flag {@code writeEnabled} is used to indicate if writing to the persistence layer
+ * is enabled or not.
+ *
+ * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
+ */
+public interface ObjectBridge
+{
+    void init(); // FIXME rename or remove.. @PostConstruct worked badly here, some kind of workaround would be nice
+    void destroy(); // FIXME
+
+    /**
+     * Save object. Will save to persistence layer if {@code writeEnabled} is {@code true}.
+     *
+     * @param object Object to write
+     */
+    void saveObject( Object object );
+
+    /**
+     * Update object. Will save to persistence layer if {@code writeEnabled} is {@code true}.
+     *
+     * @param object
+     */
+    void updateObject( Object object );
+
+    /**
+     * Get an object from the internal store. This object might not be a persisted object
+     * depending on the flag {@code writeEnabled}.
+     *
+     * @param object Object to match against
+     * @return Matched object or {@code null} if matched > 1 or no match found
+     */
+    <T> T getObject( T object );
+
+    /**
+     * Return all matches for a given object. These objects might not be a persisted object
+     * depending on the flag {@code writeEnabled}.
+     *
+     * @param object Object to match against
+     * @return A collection of matched objects
+     */
+    <T> Collection<T> getObjects( T object );
+
+    /**
+     * Get all objects for a specified class. These objects might not be a persisted object
+     * depending on the flag {@code writeEnabled}.
+     *
+     * @param clazz Clazz to match against
+     * @return Collection of matches
+     */
+    <T> Collection<T> getAllObjects( Class<T> clazz );
+
+    /**
+     * Enable or disable writing to the persistence store.
+     *
+     * @param enabled {@code boolean} turning writing on or off
+     */
+    void setWriteEnabled( boolean enabled );
+
+    /**
+     * Is persistence storage enabled?
+     *
+     * @return {@code boolean} indicating status of {@code writeEnabled}
+     */
+    boolean isWriteEnabled();
+}

=== modified file 'dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/importers/DefaultIdentifiableObjectImporter.java'
--- dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/importers/DefaultIdentifiableObjectImporter.java	2012-04-21 11:45:47 +0000
+++ dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/importers/DefaultIdentifiableObjectImporter.java	2012-04-22 16:16:24 +0000
@@ -29,19 +29,21 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.hisp.dhis.common.*;
+import org.hisp.dhis.common.BaseIdentifiableObject;
+import org.hisp.dhis.common.CodeGenerator;
+import org.hisp.dhis.common.IdentifiableObject;
 import org.hisp.dhis.common.annotation.Scanned;
 import org.hisp.dhis.dxf2.importsummary.ImportConflict;
 import org.hisp.dhis.dxf2.importsummary.ImportCount;
 import org.hisp.dhis.dxf2.metadata.ImportOptions;
 import org.hisp.dhis.dxf2.metadata.Importer;
+import org.hisp.dhis.dxf2.metadata.ObjectBridge;
 import org.hisp.dhis.dxf2.utils.OrganisationUnitUtils;
 import org.hisp.dhis.importexport.ImportStrategy;
 import org.hisp.dhis.organisationunit.OrganisationUnit;
 import org.hisp.dhis.organisationunit.comparator.OrganisationUnitComparator;
 import org.hisp.dhis.period.Period;
 import org.hisp.dhis.period.PeriodService;
-import org.hisp.dhis.period.PeriodStore;
 import org.hisp.dhis.period.PeriodType;
 import org.hisp.dhis.system.util.ReflectionUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -64,13 +66,10 @@
     //-------------------------------------------------------------------------------------------------------
 
     @Autowired
-    protected IdentifiableObjectManager manager;
-
-    @Autowired
     private PeriodService periodService;
 
     @Autowired
-    private PeriodStore periodStore;
+    private ObjectBridge objectBridge;
 
     //-------------------------------------------------------------------------------------------------------
     // Constructor
@@ -79,13 +78,10 @@
     public DefaultIdentifiableObjectImporter( Class<T> importerClass )
     {
         this.importerClass = importerClass;
-        this.nameable = NameableObject.class.isAssignableFrom( importerClass );
     }
 
     private final Class<T> importerClass;
 
-    private final boolean nameable;
-
     //-------------------------------------------------------------------------------------------------------
     // Current import counts
     //-------------------------------------------------------------------------------------------------------
@@ -97,23 +93,6 @@
     protected int ignored;
 
     //-------------------------------------------------------------------------------------------------------
-    // Mappings from identifier (uid, name, code) to a db object.
-    //
-    // WARNING: These maps might be out-of-date, depending on if new inserts has been made after the were
-    //          fetched.
-    //-------------------------------------------------------------------------------------------------------
-
-    protected Map<String, T> uidMap;
-
-    protected Map<String, T> codeMap;
-
-    protected Map<String, T> nameMap;
-
-    protected Map<String, T> shortNameMap;
-
-    private Map<String, PeriodType> periodTypeMap = new HashMap<String, PeriodType>();
-
-    //-------------------------------------------------------------------------------------------------------
     // Generic implementations of newObject and updatedObject
     //-------------------------------------------------------------------------------------------------------
 
@@ -126,11 +105,6 @@
      */
     protected ImportConflict newObject( T object, ImportOptions options )
     {
-        if ( options.isDryRun() )
-        {
-            return null;
-        }
-
         // make sure that the internalId is 0, so that the system will generate a ID
         object.setId( 0 );
         object.setUid( CodeGenerator.generateCode() );
@@ -141,13 +115,12 @@
 
         updateIdentifiableObjects( object, scanIdentifiableObjects( object ) );
 
-        manager.save( object );
+        objectBridge.saveObject( object );
 
         updateIdentifiableObjectCollections( object, identifiableObjectCollections );
 
         updatePeriodTypes( object );
-        manager.update( object );
-        updateIdMaps( object );
+        objectBridge.updateObject( object );
 
         log.info( "Save successful." );
         log.info( object );
@@ -165,11 +138,6 @@
      */
     protected ImportConflict updatedObject( T object, T oldObject, ImportOptions options )
     {
-        if ( options.isDryRun() )
-        {
-            return null;
-        }
-
         log.info( "Starting update of object " + getDisplayName( oldObject ) + " (" + oldObject.getClass().getSimpleName() + ")" );
 
         updateIdentifiableObjects( object, scanIdentifiableObjects( object ) );
@@ -178,7 +146,7 @@
         oldObject.mergeWith( object );
         updatePeriodTypes( oldObject );
 
-        manager.update( oldObject );
+        objectBridge.updateObject( oldObject );
 
         log.info( "Update successful." );
 
@@ -193,9 +161,7 @@
             if ( PeriodType.class.isAssignableFrom( field.getType() ) )
             {
                 PeriodType periodType = ReflectionUtils.invokeGetterMethod( field.getName(), object );
-
-                periodType = periodTypeMap.get( periodType.getName() );
-
+                periodType = objectBridge.getObject( periodType );
                 ReflectionUtils.invokeSetterMethod( field.getName(), object, periodType );
             }
         }
@@ -216,8 +182,6 @@
             return conflicts;
         }
 
-        populatePeriodTypeMap();
-
         reset();
 
         // FIXME a bit too static.. implement "pre handler" for types?
@@ -243,7 +207,6 @@
     @Override
     public ImportConflict importObject( T object, ImportOptions options )
     {
-        populatePeriodTypeMap();
         reset();
 
         return importObjectLocal( object, options );
@@ -265,42 +228,6 @@
     // Protected methods
     //-------------------------------------------------------------------------------------------------------
 
-    protected void populatePeriodTypeMap()
-    {
-        for ( PeriodType periodType : periodStore.getAllPeriodTypes() )
-        {
-            periodTypeMap.put( periodType.getName(), periodType );
-        }
-    }
-
-    protected void updateIdMaps( T object )
-    {
-        if ( object.getUid() != null )
-        {
-            uidMap.put( object.getUid(), object );
-        }
-
-        if ( object.getCode() != null )
-        {
-            codeMap.put( object.getCode(), object );
-        }
-
-        if ( object.getName() != null )
-        {
-            nameMap.put( object.getName(), object );
-        }
-
-        if ( nameable )
-        {
-            NameableObject nameableObject = (NameableObject) object;
-
-            if ( nameableObject.getShortName() != null )
-            {
-                shortNameMap.put( nameableObject.getShortName(), object );
-            }
-        }
-    }
-
     /**
      * @param object Object to get display name for
      * @return A usable display name
@@ -327,21 +254,11 @@
     // Helpers
     //-------------------------------------------------------------------------------------------------------
 
-    @SuppressWarnings( "unchecked" )
     private void reset()
     {
         imported = 0;
         updated = 0;
         ignored = 0;
-
-        uidMap = manager.getIdMap( importerClass, IdentifiableObject.IdentifiableProperty.UID );
-        codeMap = manager.getIdMap( importerClass, IdentifiableObject.IdentifiableProperty.CODE );
-        nameMap = manager.getIdMap( importerClass, IdentifiableObject.IdentifiableProperty.NAME );
-
-        if ( nameable )
-        {
-            shortNameMap = (Map<String, T>) manager.getIdMap( (Class<? extends NameableObject>) importerClass, NameableObject.NameableProperty.SHORT_NAME );
-        }
     }
 
     private ImportConflict importObjectLocal( T object, ImportOptions options )
@@ -363,7 +280,7 @@
 
     private ImportConflict startImport( T object, ImportOptions options )
     {
-        T oldObject = getObject( object );
+        T oldObject = objectBridge.getObject( object );
         ImportConflict conflict;
 
         if ( ImportStrategy.NEW.equals( options.getImportStrategy() ) )
@@ -419,19 +336,6 @@
 
     private ImportConflict validateIdentifiableObject( T object, ImportOptions options )
     {
-        T uidObject = uidMap.get( object.getUid() );
-        T codeObject = codeMap.get( object.getCode() );
-        T nameObject = nameMap.get( object.getName() );
-
-        T shortNameObject = null;
-
-        if ( nameable )
-        {
-            NameableObject nameableObject = (NameableObject) object;
-
-            shortNameObject = shortNameMap.get( nameableObject.getShortName() );
-        }
-
         ImportConflict conflict = null;
 
         if ( ImportStrategy.NEW.equals( options.getImportStrategy() ) )
@@ -445,7 +349,7 @@
         else if ( ImportStrategy.NEW_AND_UPDATES.equals( options.getImportStrategy() ) )
         {
             // if we have a match on at least one of the objects, then assume update
-            if ( uidObject != null || codeObject != null || nameObject != null || shortNameObject != null )
+            if ( objectBridge.getObjects( object ).size() > 0 )
             {
                 conflict = validateForUpdatesStrategy( object );
             }
@@ -460,48 +364,14 @@
 
     private ImportConflict validateForUpdatesStrategy( T object )
     {
-        T uidObject = uidMap.get( object.getUid() );
-        T codeObject = codeMap.get( object.getCode() );
-        T nameObject = nameMap.get( object.getName() );
-
-        T shortNameObject = null;
-
-        if ( nameable )
-        {
-            NameableObject nameableObject = (NameableObject) object;
-
-            shortNameObject = shortNameMap.get( nameableObject.getShortName() );
-        }
-
         ImportConflict conflict = null;
-
-        Set<T> nonNullObjects = new HashSet<T>();
-
-        if ( uidObject != null )
-        {
-            nonNullObjects.add( uidObject );
-        }
-
-        if ( codeObject != null )
-        {
-            nonNullObjects.add( codeObject );
-        }
-
-        if ( nameObject != null )
-        {
-            nonNullObjects.add( nameObject );
-        }
-
-        if ( shortNameObject != null )
-        {
-            nonNullObjects.add( shortNameObject );
-        }
-
-        if ( nonNullObjects.isEmpty() )
+        Collection<T> objects = objectBridge.getObjects( object );
+
+        if ( objects.isEmpty() )
         {
             conflict = reportLookupConflict( object );
         }
-        else if ( nonNullObjects.size() > 1 )
+        else if ( objects.size() > 1 )
         {
             conflict = reportMoreThanOneConflict( object );
         }
@@ -511,22 +381,10 @@
 
     private ImportConflict validateForNewStrategy( T object )
     {
-        T uidObject = uidMap.get( object.getUid() );
-        T codeObject = codeMap.get( object.getCode() );
-        T nameObject = nameMap.get( object.getName() );
-
-        T shortNameObject = null;
-
-        if ( nameable )
-        {
-            NameableObject nameableObject = (NameableObject) object;
-
-            shortNameObject = shortNameMap.get( nameableObject.getShortName() );
-        }
-
         ImportConflict conflict = null;
+        Collection<T> objects = objectBridge.getObjects( object );
 
-        if ( uidObject != null || codeObject != null || nameObject != null || shortNameObject != null )
+        if ( objects.size() > 0 )
         {
             conflict = reportConflict( object );
         }
@@ -549,45 +407,6 @@
         return new ImportConflict( getDisplayName( object ), "Object already exists." );
     }
 
-    private T getObject( T object )
-    {
-        T matchedObject = uidMap.get( object.getUid() );
-
-        if ( matchedObject != null )
-        {
-            return matchedObject;
-        }
-
-        matchedObject = codeMap.get( object.getCode() );
-
-        if ( matchedObject != null )
-        {
-            return matchedObject;
-        }
-
-        matchedObject = nameMap.get( object.getName() );
-
-        if ( matchedObject != null )
-        {
-            return matchedObject;
-        }
-
-        if ( nameable )
-        {
-            NameableObject nameableObject = (NameableObject) object;
-
-            matchedObject = shortNameMap.get( nameableObject.getShortName() );
-
-            if ( matchedObject != null )
-            {
-                return matchedObject;
-            }
-        }
-
-        return matchedObject;
-    }
-
-    // FIXME slow! some kind of global idMap is needed here, that will also update itself from several importers
     private IdentifiableObject findObjectByReference( IdentifiableObject identifiableObject )
     {
         IdentifiableObject match = null;
@@ -596,22 +415,10 @@
         if ( Period.class.isAssignableFrom( identifiableObject.getClass() ) )
         {
             Period period = (Period) identifiableObject;
-            match = periodService.reloadPeriod( period );
-        }
-        else if ( identifiableObject.getUid() != null )
-        {
-            match = manager.get( identifiableObject.getClass(), identifiableObject.getUid() );
-        }
-        else if ( identifiableObject.getCode() != null )
-        {
-            match = manager.getByCode( identifiableObject.getClass(), identifiableObject.getCode() );
-        }
-        else if ( identifiableObject.getName() != null )
-        {
-            match = manager.getByName( identifiableObject.getClass(), identifiableObject.getName() );
+            return periodService.reloadPeriod( period );
         }
 
-        return match;
+        return objectBridge.getObject( identifiableObject );
     }
 
     private Map<Field, IdentifiableObject> scanIdentifiableObjects( IdentifiableObject identifiableObject )

=== modified file 'dhis-2/dhis-dxf2/src/main/resources/META-INF/dhis/beans.xml'
--- dhis-2/dhis-dxf2/src/main/resources/META-INF/dhis/beans.xml	2012-04-19 16:40:00 +0000
+++ dhis-2/dhis-dxf2/src/main/resources/META-INF/dhis/beans.xml	2012-04-22 16:16:24 +0000
@@ -36,7 +36,8 @@
         value="org.hisp.dhis.dataelement.DataElementCategoryOption" />
   </bean>
 
-  <bean id="categoryOptionComboImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultIdentifiableObjectImporter">
+  <bean id="categoryOptionComboImporter"
+      class="org.hisp.dhis.dxf2.metadata.importers.DefaultIdentifiableObjectImporter">
     <constructor-arg name="importerClass" type="java.lang.Class"
         value="org.hisp.dhis.dataelement.DataElementCategoryOptionCombo" />
   </bean>
@@ -49,7 +50,8 @@
     <constructor-arg name="importerClass" type="java.lang.Class" value="org.hisp.dhis.dataelement.DataElementGroup" />
   </bean>
 
-  <bean id="dataElementGroupSetImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultIdentifiableObjectImporter">
+  <bean id="dataElementGroupSetImporter"
+      class="org.hisp.dhis.dxf2.metadata.importers.DefaultIdentifiableObjectImporter">
     <constructor-arg name="importerClass" type="java.lang.Class"
         value="org.hisp.dhis.dataelement.DataElementGroupSet" />
   </bean>
@@ -106,7 +108,8 @@
     <constructor-arg name="importerClass" type="java.lang.Class" value="org.hisp.dhis.mapping.MapLayer" />
   </bean>
 
-  <bean id="messageConversationImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultIdentifiableObjectImporter">
+  <bean id="messageConversationImporter"
+      class="org.hisp.dhis.dxf2.metadata.importers.DefaultIdentifiableObjectImporter">
     <constructor-arg name="importerClass" type="java.lang.Class" value="org.hisp.dhis.message.MessageConversation" />
   </bean>
 
@@ -115,12 +118,14 @@
         value="org.hisp.dhis.organisationunit.OrganisationUnit" />
   </bean>
 
-  <bean id="organisationUnitGroupImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultIdentifiableObjectImporter">
+  <bean id="organisationUnitGroupImporter"
+      class="org.hisp.dhis.dxf2.metadata.importers.DefaultIdentifiableObjectImporter">
     <constructor-arg name="importerClass" type="java.lang.Class"
         value="org.hisp.dhis.organisationunit.OrganisationUnitGroup" />
   </bean>
 
-  <bean id="organisationUnitGroupSetImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultIdentifiableObjectImporter">
+  <bean id="organisationUnitGroupSetImporter"
+      class="org.hisp.dhis.dxf2.metadata.importers.DefaultIdentifiableObjectImporter">
     <constructor-arg name="importerClass" type="java.lang.Class"
         value="org.hisp.dhis.organisationunit.OrganisationUnitGroupSet" />
   </bean>
@@ -153,7 +158,8 @@
     <constructor-arg name="importerClass" type="java.lang.Class" value="org.hisp.dhis.validation.ValidationRule" />
   </bean>
 
-  <bean id="validationRuleGroupImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultIdentifiableObjectImporter">
+  <bean id="validationRuleGroupImporter"
+      class="org.hisp.dhis.dxf2.metadata.importers.DefaultIdentifiableObjectImporter">
     <constructor-arg name="importerClass" type="java.lang.Class" value="org.hisp.dhis.validation.ValidationRuleGroup" />
   </bean>