← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 7044: Updated importer/exporter to be more dynamic (reads supported classes from ExchangeClasses). Fixe...

 

------------------------------------------------------------
revno: 7044
committer: Morten Olav Hansen <mortenoh@xxxxxxxxx>
branch nick: dhis2
timestamp: Fri 2012-05-25 23:10:19 +0200
message:
  Updated importer/exporter to be more dynamic (reads supported classes from ExchangeClasses). Fixed several bugs related to collections (on importing). Fixed namespaces for DataDictionary.
added:
  dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/ExchangeClasses.java
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/datadictionary/DataDictionary.java
  dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/DefaultExportService.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/DefaultObjectBridge.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
  dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/ReflectionUtils.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/datadictionary/DataDictionary.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/datadictionary/DataDictionary.java	2012-04-20 18:31:48 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/datadictionary/DataDictionary.java	2012-05-25 21:10:19 +0000
@@ -134,8 +134,8 @@
     // -------------------------------------------------------------------------
 
     @JsonProperty
-    @JsonView( {DetailedView.class, ExportView.class} )
-    @JacksonXmlProperty
+    @JsonView( { DetailedView.class, ExportView.class } )
+    @JacksonXmlProperty( namespace = Dxf2Namespace.NAMESPACE )
     public String getDescription()
     {
         return description;
@@ -147,8 +147,8 @@
     }
 
     @JsonProperty
-    @JsonView( {DetailedView.class, ExportView.class} )
-    @JacksonXmlProperty
+    @JsonView( { DetailedView.class, ExportView.class } )
+    @JacksonXmlProperty( namespace = Dxf2Namespace.NAMESPACE )
     public String getRegion()
     {
         return region;
@@ -161,9 +161,9 @@
 
     @JsonProperty
     @JsonSerialize( contentAs = BaseIdentifiableObject.class )
-    @JsonView( {DetailedView.class, ExportView.class} )
-    @JacksonXmlElementWrapper( localName = "dataElements" )
-    @JacksonXmlProperty( localName = "dataElement" )
+    @JsonView( { DetailedView.class, ExportView.class } )
+    @JacksonXmlElementWrapper( namespace = Dxf2Namespace.NAMESPACE, localName = "dataElements" )
+    @JacksonXmlProperty( namespace = Dxf2Namespace.NAMESPACE, localName = "dataElement" )
     public Set<DataElement> getDataElements()
     {
         return dataElements;
@@ -176,9 +176,9 @@
 
     @JsonProperty
     @JsonSerialize( contentAs = BaseIdentifiableObject.class )
-    @JsonView( {DetailedView.class, ExportView.class} )
-    @JacksonXmlElementWrapper( localName = "indicators" )
-    @JacksonXmlProperty( localName = "indicator" )
+    @JsonView( { DetailedView.class, ExportView.class } )
+    @JacksonXmlElementWrapper( namespace = Dxf2Namespace.NAMESPACE, localName = "indicators" )
+    @JacksonXmlProperty( namespace = Dxf2Namespace.NAMESPACE, localName = "indicator" )
     public Set<Indicator> getIndicators()
     {
         return indicators;

=== modified file 'dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/DefaultExportService.java'
--- dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/DefaultExportService.java	2012-05-16 18:08:43 +0000
+++ dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/DefaultExportService.java	2012-05-25 21:10:19 +0000
@@ -27,43 +27,17 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-import org.hisp.dhis.attribute.Attribute;
-import org.hisp.dhis.chart.Chart;
+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.concept.Concept;
-import org.hisp.dhis.constant.Constant;
-import org.hisp.dhis.datadictionary.DataDictionary;
-import org.hisp.dhis.dataelement.*;
-import org.hisp.dhis.dataset.DataSet;
-import org.hisp.dhis.dataset.Section;
-import org.hisp.dhis.document.Document;
-import org.hisp.dhis.indicator.Indicator;
-import org.hisp.dhis.indicator.IndicatorGroup;
-import org.hisp.dhis.indicator.IndicatorGroupSet;
-import org.hisp.dhis.indicator.IndicatorType;
-import org.hisp.dhis.mapping.MapLayer;
-import org.hisp.dhis.mapping.MapLegend;
-import org.hisp.dhis.mapping.MapLegendSet;
-import org.hisp.dhis.mapping.MapView;
-import org.hisp.dhis.option.OptionSet;
-import org.hisp.dhis.organisationunit.OrganisationUnit;
-import org.hisp.dhis.organisationunit.OrganisationUnitGroup;
-import org.hisp.dhis.organisationunit.OrganisationUnitGroupSet;
-import org.hisp.dhis.organisationunit.OrganisationUnitLevel;
-import org.hisp.dhis.organisationunit.comparator.OrganisationUnitComparator;
-import org.hisp.dhis.report.Report;
-import org.hisp.dhis.reporttable.ReportTable;
-import org.hisp.dhis.sqlview.SqlView;
-import org.hisp.dhis.user.User;
-import org.hisp.dhis.user.UserAuthorityGroup;
-import org.hisp.dhis.user.UserGroup;
-import org.hisp.dhis.validation.ValidationRule;
-import org.hisp.dhis.validation.ValidationRuleGroup;
+import org.hisp.dhis.system.util.ReflectionUtils;
+import org.hisp.dhis.user.CurrentUserService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
 
-import java.util.ArrayList;
-import java.util.Collections;
+import java.util.*;
 
 /**
  * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
@@ -72,9 +46,22 @@
 public class DefaultExportService
     implements ExportService
 {
+    private static final Log log = LogFactory.getLog( DefaultExportService.class );
+
+    //-------------------------------------------------------------------------------------------------------
+    // Dependencies
+    //-------------------------------------------------------------------------------------------------------
+
     @Autowired
     protected IdentifiableObjectManager manager;
 
+    @Autowired
+    private CurrentUserService currentUserService;
+
+    //-------------------------------------------------------------------------------------------------------
+    // ExportService Implementation
+    //-------------------------------------------------------------------------------------------------------
+
     @Override
     public MetaData getMetaData()
     {
@@ -86,188 +73,29 @@
     {
         MetaData metaData = new MetaData();
 
-        if ( exportOptions.isAttributeTypes() )
-        {
-            metaData.setAttributeTypes( new ArrayList<Attribute>( manager.getAll( Attribute.class ) ) );
-        }
-
-        if ( exportOptions.isUsers() )
-        {
-            metaData.setUsers( new ArrayList<User>( manager.getAll( User.class ) ) );
-        }
-
-        if ( exportOptions.isUserAuthorityGroups() )
-        {
-            metaData.setUserAuthorityGroups( new ArrayList<UserAuthorityGroup>( manager.getAll( UserAuthorityGroup.class ) ) );
-        }
-
-        if ( exportOptions.isUserGroups() )
-        {
-            metaData.setUserGroups( new ArrayList<UserGroup>( manager.getAll( UserGroup.class ) ) );
-        }
-
-        if ( exportOptions.isConstants() )
-        {
-            metaData.setConstants( new ArrayList<Constant>( manager.getAll( Constant.class ) ) );
-        }
-
-        if ( exportOptions.isConcepts() )
-        {
-            metaData.setConcepts( new ArrayList<Concept>( manager.getAll( Concept.class ) ) );
-        }
-
-        if ( exportOptions.isDataElements() )
-        {
-            metaData.setDataElements( new ArrayList<DataElement>( manager.getAll( DataElement.class ) ) );
-        }
-
-        if ( exportOptions.isOptionSets() )
-        {
-            metaData.setOptionSets( new ArrayList<OptionSet>( manager.getAll( OptionSet.class ) ) );
-        }
-
-        if ( exportOptions.isDataElementGroups() )
-        {
-            metaData.setDataElementGroups( new ArrayList<DataElementGroup>( manager.getAll( DataElementGroup.class ) ) );
-        }
-
-        if ( exportOptions.isDataElementGroupSets() )
-        {
-            metaData.setDataElementGroupSets( new ArrayList<DataElementGroupSet>( manager.getAll( DataElementGroupSet.class ) ) );
-        }
-
-        if ( exportOptions.isCategories() )
-        {
-            metaData.setCategories( new ArrayList<DataElementCategory>( manager.getAll( DataElementCategory.class ) ) );
-        }
-
-        if ( exportOptions.isCategoryOptions() )
-        {
-            metaData.setCategoryOptions( new ArrayList<DataElementCategoryOption>( manager.getAll( DataElementCategoryOption.class ) ) );
-        }
-
-        if ( exportOptions.isCategoryCombos() )
-        {
-            metaData.setCategoryCombos( new ArrayList<DataElementCategoryCombo>( manager.getAll( DataElementCategoryCombo.class ) ) );
-        }
-
-        if ( exportOptions.isCategoryOptionCombos() )
-        {
-            metaData.setCategoryOptionCombos( new ArrayList<DataElementCategoryOptionCombo>( manager.getAll( DataElementCategoryOptionCombo.class ) ) );
-        }
-
-        if ( exportOptions.isIndicators() )
-        {
-            metaData.setIndicators( new ArrayList<Indicator>( manager.getAll( Indicator.class ) ) );
-        }
-
-        if ( exportOptions.isIndicatorGroups() )
-        {
-            metaData.setIndicatorGroups( new ArrayList<IndicatorGroup>( manager.getAll( IndicatorGroup.class ) ) );
-        }
-
-        if ( exportOptions.isIndicatorGroupSets() )
-        {
-            metaData.setIndicatorGroupSets( new ArrayList<IndicatorGroupSet>( manager.getAll( IndicatorGroupSet.class ) ) );
-        }
-
-        if ( exportOptions.isIndicatorTypes() )
-        {
-            metaData.setIndicatorTypes( new ArrayList<IndicatorType>( manager.getAll( IndicatorType.class ) ) );
-        }
-
-        if ( exportOptions.isOrganisationUnits() )
-        {
-            metaData.setOrganisationUnits( new ArrayList<OrganisationUnit>( manager.getAll( OrganisationUnit.class ) ) );
-
-            // sort according to level
-            Collections.sort( metaData.getOrganisationUnits(), new OrganisationUnitComparator() );
-        }
-
-        if ( exportOptions.isOrganisationUnitLevels() )
-        {
-            metaData.setOrganisationUnitLevels( new ArrayList<OrganisationUnitLevel>( manager.getAll( OrganisationUnitLevel.class ) ) );
-        }
-
-        if ( exportOptions.isOrganisationUnitGroups() )
-        {
-            metaData.setOrganisationUnitGroups( new ArrayList<OrganisationUnitGroup>( manager.getAll( OrganisationUnitGroup.class ) ) );
-        }
-
-        if ( exportOptions.isOrganisationUnitGroupSets() )
-        {
-            metaData.setOrganisationUnitGroupSets( new ArrayList<OrganisationUnitGroupSet>( manager.getAll( OrganisationUnitGroupSet.class ) ) );
-        }
-
-        if ( exportOptions.isSections() )
-        {
-            metaData.setSections( new ArrayList<Section>( manager.getAll( Section.class ) ) );
-        }
-
-        if ( exportOptions.isDataSets() )
-        {
-            metaData.setDataSets( new ArrayList<DataSet>( manager.getAll( DataSet.class ) ) );
-        }
-
-        if ( exportOptions.isValidationRules() )
-        {
-            metaData.setValidationRules( new ArrayList<ValidationRule>( manager.getAll( ValidationRule.class ) ) );
-        }
-
-        if ( exportOptions.isValidationRuleGroups() )
-        {
-            metaData.setValidationRuleGroups( new ArrayList<ValidationRuleGroup>( manager.getAll( ValidationRuleGroup.class ) ) );
-        }
-
-        if ( exportOptions.isSqlViews() )
-        {
-            metaData.setSqlViews( new ArrayList<SqlView>( manager.getAll( SqlView.class ) ) );
-        }
-
-        if ( exportOptions.isDocuments() )
-        {
-            metaData.setDocuments( new ArrayList<Document>( manager.getAll( Document.class ) ) );
-        }
-
-        if ( exportOptions.isReportTables() )
-        {
-            metaData.setReportTables( new ArrayList<ReportTable>( manager.getAll( ReportTable.class ) ) );
-        }
-
-        if ( exportOptions.isReports() )
-        {
-            metaData.setReports( new ArrayList<Report>( manager.getAll( Report.class ) ) );
-        }
-
-        if ( exportOptions.isCharts() )
-        {
-            metaData.setCharts( new ArrayList<Chart>( manager.getAll( Chart.class ) ) );
-        }
-
-        if ( exportOptions.isMaps() )
-        {
-            metaData.setMaps( new ArrayList<MapView>( manager.getAll( MapView.class ) ) );
-        }
-
-        if ( exportOptions.isMapLegends() )
-        {
-            metaData.setMapLegends( new ArrayList<MapLegend>( manager.getAll( MapLegend.class ) ) );
-        }
-
-        if ( exportOptions.isMapLegendSets() )
-        {
-            metaData.setMapLegendSets( new ArrayList<MapLegendSet>( manager.getAll( MapLegendSet.class ) ) );
-        }
-
-        if ( exportOptions.isMapLayers() )
-        {
-            metaData.setMapLayers( new ArrayList<MapLayer>( manager.getAll( MapLayer.class ) ) );
-        }
-
-        if ( exportOptions.isDataDictionaries() )
-        {
-            metaData.setDataDictionaries( new ArrayList<DataDictionary>( manager.getAll( DataDictionary.class ) ) );
-        }
+        log.info( "User '" + currentUserService.getCurrentUsername() + "' started export at " + new Date() );
+
+        for ( Map.Entry<String, Class<?>> entry : ExchangeClasses.getExportMap().entrySet() )
+        {
+            @SuppressWarnings( "unchecked" )
+            Class<? extends IdentifiableObject> idObjectClass = (Class<? extends IdentifiableObject>) entry.getValue();
+
+            Collection<? extends IdentifiableObject> idObjects = manager.getAll( idObjectClass );
+
+            if ( idObjects != null )
+            {
+                log.info( "Exporting " + idObjects.size() + " " + StringUtils.capitalize( entry.getKey() ) );
+
+                List<? extends IdentifiableObject> idObjectsList = new ArrayList<IdentifiableObject>( idObjects );
+                ReflectionUtils.invokeSetterMethod( entry.getKey(), metaData, idObjectsList );
+            }
+            else
+            {
+                log.warn( "Skipping objects of type '" + entry.getValue().getSimpleName() + "'." );
+            }
+        }
+
+        log.info( "Finished export at " + new Date() );
 
         return metaData;
     }

=== 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-05-22 11:04:59 +0000
+++ dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/DefaultImportService.java	2012-05-25 21:10:19 +0000
@@ -33,15 +33,13 @@
 import org.hisp.dhis.cache.HibernateCacheManager;
 import org.hisp.dhis.dxf2.importsummary.ImportConflict;
 import org.hisp.dhis.dxf2.importsummary.ImportSummary;
+import org.hisp.dhis.system.util.ReflectionUtils;
 import org.hisp.dhis.user.CurrentUserService;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.StringUtils;
 
-import java.util.Date;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
 
 /**
  * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
@@ -92,57 +90,30 @@
             objectBridge.setWriteEnabled( false );
         }
 
-        Date startDate = new Date();
-
-        log.info( "User '" + currentUserService.getCurrentUsername() + "' started import at " + startDate );
-
-        doImport( metaData.getSqlViews(), importOptions, importSummary );
-        doImport( metaData.getConcepts(), importOptions, importSummary );
-        doImport( metaData.getConstants(), importOptions, importSummary );
-        doImport( metaData.getDocuments(), importOptions, importSummary );
-        doImport( metaData.getOptionSets(), importOptions, importSummary );
-        doImport( metaData.getAttributeTypes(), importOptions, importSummary );
-
-        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.getCategoryOptions(), importOptions, importSummary );
-        doImport( metaData.getCategories(), importOptions, importSummary );
-        doImport( metaData.getCategoryCombos(), 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 );
-        doImport( metaData.getIndicatorGroupSets(), importOptions, importSummary );
-
-        doImport( metaData.getValidationRules(), importOptions, importSummary );
-        doImport( metaData.getValidationRuleGroups(), importOptions, importSummary );
-
-        // doImport( metaData.getMessageConversations(), importOptions, importSummary );
-
-        doImport( metaData.getDataDictionaries(), importOptions, importSummary );
-        doImport( metaData.getDataSets(), importOptions, importSummary );
-        doImport( metaData.getSections(), importOptions, importSummary );
-
-        doImport( metaData.getReportTables(), importOptions, importSummary );
-        doImport( metaData.getReports(), importOptions, importSummary );
-        doImport( metaData.getCharts(), importOptions, importSummary );
-
-        doImport( metaData.getMaps(), importOptions, importSummary );
-        doImport( metaData.getMapLegends(), importOptions, importSummary );
-        doImport( metaData.getMapLegendSets(), importOptions, importSummary );
-        doImport( metaData.getMapLayers(), importOptions, importSummary );
+        log.info( "User '" + currentUserService.getCurrentUsername() + "' started import at " + new Date() );
+
+        for ( Map.Entry<String, Class<?>> entry : ExchangeClasses.getImportMap().entrySet() )
+        {
+            Object value = ReflectionUtils.invokeGetterMethod( entry.getKey(), metaData );
+
+            if ( value != null )
+            {
+                if ( Collection.class.isAssignableFrom( value.getClass() ) )
+                {
+                    List<?> objects = new ArrayList<Object>( (Collection<?>) value );
+                    log.info( "Importing " + objects.size() + " " + StringUtils.capitalize( entry.getKey() ) );
+                    doImport( objects, importOptions, importSummary );
+                }
+                else
+                {
+                    log.warn( "Getter for '" + entry.getKey() + "' did not return a collection." );
+                }
+            }
+            else
+            {
+                log.warn( "Can not find getter for '" + entry.getKey() + "'." );
+            }
+        }
 
         if ( importOptions.isDryRun() )
         {
@@ -152,8 +123,7 @@
         cacheManager.clearCache();
         objectBridge.destroy();
 
-        Date endDate = new Date();
-        log.info( "Finished import at " + endDate );
+        log.info( "Finished import at " + new Date() );
 
         return importSummary;
     }
@@ -172,6 +142,7 @@
         return null;
     }
 
+    @SuppressWarnings( "unchecked" )
     private <T> Importer<T> findImporterClass( Class<?> clazz )
     {
         for ( Importer<T> i : importerClasses )

=== modified 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	2012-05-22 11:04:59 +0000
+++ dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/DefaultObjectBridge.java	2012-05-25 21:10:19 +0000
@@ -29,44 +29,12 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.hisp.dhis.attribute.Attribute;
-import org.hisp.dhis.chart.Chart;
 import org.hisp.dhis.common.IdentifiableObject;
 import org.hisp.dhis.common.IdentifiableObjectManager;
 import org.hisp.dhis.common.NameableObject;
-import org.hisp.dhis.concept.Concept;
-import org.hisp.dhis.constant.Constant;
-import org.hisp.dhis.datadictionary.DataDictionary;
-import org.hisp.dhis.dataelement.*;
-import org.hisp.dhis.dataset.DataSet;
-import org.hisp.dhis.dataset.Section;
-import org.hisp.dhis.document.Document;
-import org.hisp.dhis.indicator.Indicator;
-import org.hisp.dhis.indicator.IndicatorGroup;
-import org.hisp.dhis.indicator.IndicatorGroupSet;
-import org.hisp.dhis.indicator.IndicatorType;
-import org.hisp.dhis.mapping.MapLayer;
-import org.hisp.dhis.mapping.MapLegend;
-import org.hisp.dhis.mapping.MapLegendSet;
-import org.hisp.dhis.mapping.MapView;
-import org.hisp.dhis.option.OptionSet;
-import org.hisp.dhis.organisationunit.OrganisationUnit;
-import org.hisp.dhis.organisationunit.OrganisationUnitGroup;
-import org.hisp.dhis.organisationunit.OrganisationUnitGroupSet;
-import org.hisp.dhis.organisationunit.OrganisationUnitLevel;
 import org.hisp.dhis.period.PeriodStore;
 import org.hisp.dhis.period.PeriodType;
-import org.hisp.dhis.report.Report;
-import org.hisp.dhis.reporttable.ReportTable;
-import org.hisp.dhis.sqlview.SqlView;
-import org.hisp.dhis.user.User;
-import org.hisp.dhis.user.UserAuthorityGroup;
-import org.hisp.dhis.user.UserGroup;
-import org.hisp.dhis.validation.ValidationRule;
-import org.hisp.dhis.validation.ValidationRuleGroup;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-import org.springframework.transaction.annotation.Transactional;
 
 import java.util.*;
 
@@ -115,49 +83,11 @@
     static
     {
         registeredTypes.add( PeriodType.class );
-        registeredTypes.add( Document.class );
-        registeredTypes.add( Constant.class );
-        registeredTypes.add( Attribute.class );
-        registeredTypes.add( Concept.class );
-        registeredTypes.add( SqlView.class );
-        registeredTypes.add( Chart.class );
-        registeredTypes.add( Report.class );
-        registeredTypes.add( ReportTable.class );
-        registeredTypes.add( DataDictionary.class );
-
-        // registeredTypes.add( User.class );
-        // registeredTypes.add( UserGroup.class );
-        // registeredTypes.add( UserAuthorityGroup.class );
-
-        registeredTypes.add( OrganisationUnitLevel.class );
-        registeredTypes.add( OrganisationUnit.class );
-        registeredTypes.add( OrganisationUnitGroup.class );
-        registeredTypes.add( OrganisationUnitGroupSet.class );
-
-        registeredTypes.add( Indicator.class );
-        registeredTypes.add( IndicatorType.class );
-        registeredTypes.add( IndicatorGroup.class );
-        registeredTypes.add( IndicatorGroupSet.class );
-
-        registeredTypes.add( DataElement.class );
-        registeredTypes.add( OptionSet.class );
-        registeredTypes.add( DataElementGroup.class );
-        registeredTypes.add( DataElementGroupSet.class );
-        registeredTypes.add( DataElementCategory.class );
-        registeredTypes.add( DataElementCategoryOption.class );
-        registeredTypes.add( DataElementCategoryCombo.class );
-        registeredTypes.add( DataElementCategoryOptionCombo.class );
-
-        registeredTypes.add( ValidationRule.class );
-        registeredTypes.add( ValidationRuleGroup.class );
-
-        registeredTypes.add( DataSet.class );
-        registeredTypes.add( Section.class );
-
-        registeredTypes.add( MapView.class );
-        registeredTypes.add( MapLayer.class );
-        registeredTypes.add( MapLegend.class );
-        registeredTypes.add( MapLegendSet.class );
+
+        for ( Class<?> clazz : ExchangeClasses.getImportClasses() )
+        {
+            registeredTypes.add( clazz );
+        }
     }
 
     @Override

=== added file 'dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/ExchangeClasses.java'
--- dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/ExchangeClasses.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/ExchangeClasses.java	2012-05-25 21:10:19 +0000
@@ -0,0 +1,144 @@
+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.hisp.dhis.attribute.Attribute;
+import org.hisp.dhis.chart.Chart;
+import org.hisp.dhis.concept.Concept;
+import org.hisp.dhis.constant.Constant;
+import org.hisp.dhis.datadictionary.DataDictionary;
+import org.hisp.dhis.dataelement.*;
+import org.hisp.dhis.dataset.DataSet;
+import org.hisp.dhis.dataset.Section;
+import org.hisp.dhis.document.Document;
+import org.hisp.dhis.indicator.Indicator;
+import org.hisp.dhis.indicator.IndicatorGroup;
+import org.hisp.dhis.indicator.IndicatorGroupSet;
+import org.hisp.dhis.indicator.IndicatorType;
+import org.hisp.dhis.mapping.MapLayer;
+import org.hisp.dhis.mapping.MapLegend;
+import org.hisp.dhis.mapping.MapLegendSet;
+import org.hisp.dhis.mapping.MapView;
+import org.hisp.dhis.option.OptionSet;
+import org.hisp.dhis.organisationunit.OrganisationUnit;
+import org.hisp.dhis.organisationunit.OrganisationUnitGroup;
+import org.hisp.dhis.organisationunit.OrganisationUnitGroupSet;
+import org.hisp.dhis.organisationunit.OrganisationUnitLevel;
+import org.hisp.dhis.report.Report;
+import org.hisp.dhis.reporttable.ReportTable;
+import org.hisp.dhis.sqlview.SqlView;
+import org.hisp.dhis.validation.ValidationRule;
+import org.hisp.dhis.validation.ValidationRuleGroup;
+
+import java.util.*;
+
+/**
+ * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
+ */
+final public class ExchangeClasses
+{
+    final private static Map<String, Class<?>> exportClasses;
+
+    final private static Map<String, Class<?>> importClasses;
+
+    static
+    {
+        exportClasses = new LinkedHashMap<String, Class<?>>();
+
+        exportClasses.put( "sqlViews", SqlView.class );
+        exportClasses.put( "concepts", Concept.class );
+        exportClasses.put( "constants", Constant.class );
+        exportClasses.put( "documents", Document.class );
+        exportClasses.put( "optionSets", OptionSet.class );
+        exportClasses.put( "attributeTypes", Attribute.class );
+
+        exportClasses.put( "organisationUnits", OrganisationUnit.class );
+        exportClasses.put( "organisationUnitLevels", OrganisationUnitLevel.class );
+        exportClasses.put( "organisationUnitGroups", OrganisationUnitGroup.class );
+        exportClasses.put( "organisationUnitGroupSets", OrganisationUnitGroupSet.class );
+
+        exportClasses.put( "categoryOptions", DataElementCategoryOption.class );
+        exportClasses.put( "categories", DataElementCategory.class );
+        exportClasses.put( "categoryCombos", DataElementCategoryCombo.class );
+        exportClasses.put( "categoryOptionCombos", DataElementCategoryOptionCombo.class );
+
+        exportClasses.put( "dataElements", DataElement.class );
+        exportClasses.put( "dataElementGroups", DataElementGroup.class );
+        exportClasses.put( "dataElementGroupSets", DataElementGroupSet.class );
+
+        exportClasses.put( "indicatorTypes", IndicatorType.class );
+        exportClasses.put( "indicators", Indicator.class );
+        exportClasses.put( "indicatorGroups", IndicatorGroup.class );
+        exportClasses.put( "indicatorGroupSets", IndicatorGroupSet.class );
+
+        exportClasses.put( "dataDictionaries", DataDictionary.class );
+
+        exportClasses.put( "dataSets", DataSet.class );
+        exportClasses.put( "sections", Section.class );
+
+        exportClasses.put( "reportTables", ReportTable.class );
+        exportClasses.put( "reports", Report.class );
+        exportClasses.put( "charts", Chart.class );
+
+        exportClasses.put( "validationRules", ValidationRule.class );
+        exportClasses.put( "validationRuleGroups", ValidationRuleGroup.class );
+
+        exportClasses.put( "maps", MapView.class );
+        exportClasses.put( "mapLegends", MapLegend.class );
+        exportClasses.put( "mapLegendSets", MapLegendSet.class );
+        exportClasses.put( "mapLayers", MapLayer.class );
+
+        importClasses = exportClasses;
+
+
+        // exportClasses.put( "users", User.class );
+        // exportClasses.put( "userGroups", UserGroup.class );
+        // exportClasses.put( "userRoles", UserAuthorityGroup.class );
+        // exportClasses.put( "messageConversations", MessageConversation.class );
+    }
+
+    public static Map<String, Class<?>> getExportMap()
+    {
+        return Collections.unmodifiableMap( exportClasses );
+    }
+
+    public static List<Class<?>> getExportClasses()
+    {
+        return new ArrayList<Class<?>>( exportClasses.values() );
+    }
+
+    public static Map<String, Class<?>> getImportMap()
+    {
+        return Collections.unmodifiableMap( importClasses );
+    }
+
+    public static List<Class<?>> getImportClasses()
+    {
+        return new ArrayList<Class<?>>( importClasses.values() );
+    }
+}

=== 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-05-23 19:58:27 +0000
+++ dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/importers/DefaultIdentifiableObjectImporter.java	2012-05-25 21:10:19 +0000
@@ -180,7 +180,7 @@
         oldObject.mergeWith( object );
         updatePeriodTypes( oldObject );
 
-        importConflicts.addAll( reattachCollectionFields( object, collectionFields ) );
+        importConflicts.addAll( reattachCollectionFields( oldObject, collectionFields ) );
 
         objectBridge.updateObject( oldObject );
 
@@ -737,7 +737,7 @@
 
     private Map<Field, Collection<Object>> detachCollectionFields( Object object )
     {
-        Map<Field, Collection<Object>> collected = new HashMap<Field, Collection<Object>>();
+        Map<Field, Collection<Object>> collectionFields = new HashMap<Field, Collection<Object>>();
         Field[] fields = object.getClass().getDeclaredFields();
 
         for ( Field field : fields )
@@ -751,13 +751,21 @@
 
                 if ( objects != null && !objects.isEmpty() )
                 {
-                    collected.put( field, objects );
-                    objects.clear();
+                    collectionFields.put( field, objects );
+
+                    if ( List.class.isAssignableFrom( field.getType() ) )
+                    {
+                        ReflectionUtils.invokeSetterMethod( field.getName(), object, new ArrayList<Object>() );
+                    }
+                    else if ( Set.class.isAssignableFrom( field.getType() ) )
+                    {
+                        ReflectionUtils.invokeSetterMethod( field.getName(), object, new HashSet<Object>() );
+                    }
                 }
             }
         }
 
-        return collected;
+        return collectionFields;
     }
 
     private List<ImportConflict> reattachCollectionFields( Object object, Map<Field, Collection<Object>> collectionFields )
@@ -766,7 +774,7 @@
 
         for ( Field field : collectionFields.keySet() )
         {
-            Collection<Object> identifiableObjects = collectionFields.get( field );
+            Collection<Object> collection = collectionFields.get( field );
             Collection<Object> objects;
 
             if ( List.class.isAssignableFrom( field.getType() ) )
@@ -783,7 +791,7 @@
                 continue;
             }
 
-            for ( Object idObject : identifiableObjects )
+            for ( Object idObject : collection )
             {
                 IdentifiableObject ref = findObjectByReference( (IdentifiableObject) idObject );
 

=== 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-05-23 18:35:22 +0000
+++ dhis-2/dhis-dxf2/src/main/resources/META-INF/dhis/beans.xml	2012-05-25 21:10:19 +0000
@@ -181,5 +181,10 @@
     <constructor-arg name="importerClass" type="java.lang.Class" value="org.hisp.dhis.validation.ValidationRuleGroup" />
   </bean>
 
+  <bean id="dataDictionaryImporter"
+      class="org.hisp.dhis.dxf2.metadata.importers.DefaultIdentifiableObjectImporter">
+    <constructor-arg name="importerClass" type="java.lang.Class" value="org.hisp.dhis.datadictionary.DataDictionary" />
+  </bean>
+
 
 </beans>

=== modified file 'dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/ReflectionUtils.java'
--- dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/ReflectionUtils.java	2012-05-17 20:26:32 +0000
+++ dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/ReflectionUtils.java	2012-05-25 21:10:19 +0000
@@ -94,9 +94,9 @@
      */
     public static void setProperty( Object object, String name, String value )
     {
-        Object[] arguments = new Object[]{value};
+        Object[] arguments = new Object[]{ value };
 
-        Class<?>[] parameterTypes = new Class<?>[]{String.class};
+        Class<?>[] parameterTypes = new Class<?>[]{ String.class };
 
         if ( name.length() > 0 )
         {