← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 6647: sort organisationUnits (based on parent) on both import and export

 

------------------------------------------------------------
revno: 6647
committer: Morten Olav Hansen <mortenoh@xxxxxxxxx>
branch nick: dhis2
timestamp: Thu 2012-04-19 19:40:00 +0300
message:
  sort organisationUnits (based on parent) on both import and export
removed:
  dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/importers/DefaultImporter.java
added:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/comparator/OrganisationUnitComparator.java
  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/utils/OrganisationUnitUtils.java
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/annotation/Scanned.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/resources/META-INF/dhis/beans.xml
  dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/DataValueSetController.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/annotation/Scanned.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/annotation/Scanned.java	2012-04-18 20:24:12 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/annotation/Scanned.java	2012-04-19 16:40:00 +0000
@@ -1,5 +1,32 @@
 package org.hisp.dhis.common.annotation;
 
+/*
+ * Copyright (c) 2004-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 <ORGANIZATION> 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.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -13,7 +40,7 @@
  * that we don't want scanned (e.g. reportTable.allIndicators).
  *
  * TODO
- *  - refactor out scanner from DefaultImporter
+ *  - refactor out scanner from DefaultIdentifiableObjectImporter
  *  - add support for profiling (only scan for this profile, etc)
  *  - add support for annotation the setter or getter also
  *

=== added file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/comparator/OrganisationUnitComparator.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/comparator/OrganisationUnitComparator.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/comparator/OrganisationUnitComparator.java	2012-04-19 16:40:00 +0000
@@ -0,0 +1,61 @@
+package org.hisp.dhis.organisationunit.comparator;
+
+/*
+ * Copyright (c) 2004-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.organisationunit.OrganisationUnit;
+
+import java.util.Comparator;
+
+/**
+ * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
+ */
+public class OrganisationUnitComparator
+    implements Comparator<OrganisationUnit>
+{
+    private int countParents( OrganisationUnit organisationUnit )
+    {
+        int parents = 0;
+        OrganisationUnit currentOrganisationUnit = organisationUnit;
+
+        while ( (currentOrganisationUnit = currentOrganisationUnit.getParent()) != null )
+        {
+            parents++;
+        }
+
+        return parents;
+    }
+
+    @Override
+    public int compare( OrganisationUnit organisationUnit1, OrganisationUnit organisationUnit2 )
+    {
+        Integer parents1 = countParents( organisationUnit1 );
+        Integer parents2 = countParents( organisationUnit2 );
+
+        return parents1.compareTo( parents2 );
+    }
+}

=== 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-04-11 15:11:09 +0000
+++ dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/DefaultExportService.java	2012-04-19 16:40:00 +0000
@@ -27,23 +27,16 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-import java.util.ArrayList;
-
 import org.hisp.dhis.attribute.Attribute;
 import org.hisp.dhis.chart.Chart;
 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.DataElement;
-import org.hisp.dhis.dataelement.DataElementCategory;
-import org.hisp.dhis.dataelement.DataElementCategoryCombo;
-import org.hisp.dhis.dataelement.DataElementCategoryOption;
-import org.hisp.dhis.dataelement.DataElementCategoryOptionCombo;
-import org.hisp.dhis.dataelement.DataElementGroup;
-import org.hisp.dhis.dataelement.DataElementGroupSet;
+import org.hisp.dhis.dataelement.*;
 import org.hisp.dhis.dataset.DataSet;
 import org.hisp.dhis.document.Document;
+import org.hisp.dhis.dxf2.utils.OrganisationUnitUtils;
 import org.hisp.dhis.indicator.Indicator;
 import org.hisp.dhis.indicator.IndicatorGroup;
 import org.hisp.dhis.indicator.IndicatorGroupSet;
@@ -57,6 +50,7 @@
 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;
@@ -68,6 +62,9 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.util.ArrayList;
+import java.util.Collections;
+
 /**
  * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
  */
@@ -87,183 +84,186 @@
     @Override
     public MetaData getMetaData( ExportOptions exportOptions )
     {
-        MetaData dxf2 = new MetaData();
+        MetaData metaData = new MetaData();
 
         if ( exportOptions.isAttributeTypes() )
         {
-            dxf2.setAttributeTypes( new ArrayList<Attribute>( manager.getAll( Attribute.class ) ) );
+            metaData.setAttributeTypes( new ArrayList<Attribute>( manager.getAll( Attribute.class ) ) );
         }
 
         if ( exportOptions.isUsers() )
         {
-            dxf2.setUsers( new ArrayList<User>( manager.getAll( User.class ) ) );
+            metaData.setUsers( new ArrayList<User>( manager.getAll( User.class ) ) );
         }
 
         if ( exportOptions.isUserAuthorityGroups() )
         {
-            dxf2.setUserAuthorityGroups( new ArrayList<UserAuthorityGroup>( manager.getAll( UserAuthorityGroup.class ) ) );
+            metaData.setUserAuthorityGroups( new ArrayList<UserAuthorityGroup>( manager.getAll( UserAuthorityGroup.class ) ) );
         }
 
         if ( exportOptions.isUserGroups() )
         {
-            dxf2.setUserGroups( new ArrayList<UserGroup>( manager.getAll( UserGroup.class ) ) );
+            metaData.setUserGroups( new ArrayList<UserGroup>( manager.getAll( UserGroup.class ) ) );
         }
 
         if ( exportOptions.isConstants() )
         {
-            dxf2.setConstants( new ArrayList<Constant>( manager.getAll( Constant.class ) ) );
+            metaData.setConstants( new ArrayList<Constant>( manager.getAll( Constant.class ) ) );
         }
 
         if ( exportOptions.isConcepts() )
         {
-            dxf2.setConcepts( new ArrayList<Concept>( manager.getAll( Concept.class ) ) );
+            metaData.setConcepts( new ArrayList<Concept>( manager.getAll( Concept.class ) ) );
         }
 
         if ( exportOptions.isDataElements() )
         {
-            dxf2.setDataElements( new ArrayList<DataElement>( manager.getAll( DataElement.class ) ) );
+            metaData.setDataElements( new ArrayList<DataElement>( manager.getAll( DataElement.class ) ) );
         }
 
         if ( exportOptions.isOptionSets() )
         {
-            dxf2.setOptionSets( new ArrayList<OptionSet>( manager.getAll( OptionSet.class ) ) );
+            metaData.setOptionSets( new ArrayList<OptionSet>( manager.getAll( OptionSet.class ) ) );
         }
 
         if ( exportOptions.isDataElementGroups() )
         {
-            dxf2.setDataElementGroups( new ArrayList<DataElementGroup>( manager.getAll( DataElementGroup.class ) ) );
+            metaData.setDataElementGroups( new ArrayList<DataElementGroup>( manager.getAll( DataElementGroup.class ) ) );
         }
 
         if ( exportOptions.isDataElementGroupSets() )
         {
-            dxf2.setDataElementGroupSets( new ArrayList<DataElementGroupSet>( manager.getAll( DataElementGroupSet.class ) ) );
+            metaData.setDataElementGroupSets( new ArrayList<DataElementGroupSet>( manager.getAll( DataElementGroupSet.class ) ) );
         }
 
         if ( exportOptions.isCategories() )
         {
-            dxf2.setCategories( new ArrayList<DataElementCategory>( manager.getAll( DataElementCategory.class ) ) );
+            metaData.setCategories( new ArrayList<DataElementCategory>( manager.getAll( DataElementCategory.class ) ) );
         }
 
         if ( exportOptions.isCategoryOptions() )
         {
-            dxf2.setCategoryOptions( new ArrayList<DataElementCategoryOption>( manager.getAll( DataElementCategoryOption.class ) ) );
+            metaData.setCategoryOptions( new ArrayList<DataElementCategoryOption>( manager.getAll( DataElementCategoryOption.class ) ) );
         }
 
         if ( exportOptions.isCategoryCombos() )
         {
-            dxf2.setCategoryCombos( new ArrayList<DataElementCategoryCombo>( manager.getAll( DataElementCategoryCombo.class ) ) );
+            metaData.setCategoryCombos( new ArrayList<DataElementCategoryCombo>( manager.getAll( DataElementCategoryCombo.class ) ) );
         }
 
         if ( exportOptions.isCategoryOptionCombos() )
         {
-            dxf2.setCategoryOptionCombos( new ArrayList<DataElementCategoryOptionCombo>( manager.getAll( DataElementCategoryOptionCombo.class ) ) );
+            metaData.setCategoryOptionCombos( new ArrayList<DataElementCategoryOptionCombo>( manager.getAll( DataElementCategoryOptionCombo.class ) ) );
         }
 
         if ( exportOptions.isIndicators() )
         {
-            dxf2.setIndicators( new ArrayList<Indicator>( manager.getAll( Indicator.class ) ) );
+            metaData.setIndicators( new ArrayList<Indicator>( manager.getAll( Indicator.class ) ) );
         }
 
         if ( exportOptions.isIndicatorGroups() )
         {
-            dxf2.setIndicatorGroups( new ArrayList<IndicatorGroup>( manager.getAll( IndicatorGroup.class ) ) );
+            metaData.setIndicatorGroups( new ArrayList<IndicatorGroup>( manager.getAll( IndicatorGroup.class ) ) );
         }
 
         if ( exportOptions.isIndicatorGroupSets() )
         {
-            dxf2.setIndicatorGroupSets( new ArrayList<IndicatorGroupSet>( manager.getAll( IndicatorGroupSet.class ) ) );
+            metaData.setIndicatorGroupSets( new ArrayList<IndicatorGroupSet>( manager.getAll( IndicatorGroupSet.class ) ) );
         }
 
         if ( exportOptions.isIndicatorTypes() )
         {
-            dxf2.setIndicatorTypes( new ArrayList<IndicatorType>( manager.getAll( IndicatorType.class ) ) );
+            metaData.setIndicatorTypes( new ArrayList<IndicatorType>( manager.getAll( IndicatorType.class ) ) );
         }
 
         if ( exportOptions.isOrganisationUnits() )
         {
-            dxf2.setOrganisationUnits( new ArrayList<OrganisationUnit>( manager.getAll( OrganisationUnit.class ) ) );
+            metaData.setOrganisationUnits( new ArrayList<OrganisationUnit>( manager.getAll( OrganisationUnit.class ) ) );
+
+            // sort according to level
+            Collections.sort( metaData.getOrganisationUnits(), new OrganisationUnitComparator() );
         }
 
         if ( exportOptions.isOrganisationUnitLevels() )
         {
-            dxf2.setOrganisationUnitLevels( new ArrayList<OrganisationUnitLevel>( manager.getAll( OrganisationUnitLevel.class ) ) );
+            metaData.setOrganisationUnitLevels( new ArrayList<OrganisationUnitLevel>( manager.getAll( OrganisationUnitLevel.class ) ) );
         }
 
         if ( exportOptions.isOrganisationUnitGroups() )
         {
-            dxf2.setOrganisationUnitGroups( new ArrayList<OrganisationUnitGroup>( manager.getAll( OrganisationUnitGroup.class ) ) );
+            metaData.setOrganisationUnitGroups( new ArrayList<OrganisationUnitGroup>( manager.getAll( OrganisationUnitGroup.class ) ) );
         }
 
         if ( exportOptions.isOrganisationUnitGroupSets() )
         {
-            dxf2.setOrganisationUnitGroupSets( new ArrayList<OrganisationUnitGroupSet>( manager.getAll( OrganisationUnitGroupSet.class ) ) );
+            metaData.setOrganisationUnitGroupSets( new ArrayList<OrganisationUnitGroupSet>( manager.getAll( OrganisationUnitGroupSet.class ) ) );
         }
 
         if ( exportOptions.isDataSets() )
         {
-            dxf2.setDataSets( new ArrayList<DataSet>( manager.getAll( DataSet.class ) ) );
+            metaData.setDataSets( new ArrayList<DataSet>( manager.getAll( DataSet.class ) ) );
         }
 
         if ( exportOptions.isValidationRules() )
         {
-            dxf2.setValidationRules( new ArrayList<ValidationRule>( manager.getAll( ValidationRule.class ) ) );
+            metaData.setValidationRules( new ArrayList<ValidationRule>( manager.getAll( ValidationRule.class ) ) );
         }
 
         if ( exportOptions.isValidationRuleGroups() )
         {
-            dxf2.setValidationRuleGroups( new ArrayList<ValidationRuleGroup>( manager.getAll( ValidationRuleGroup.class ) ) );
+            metaData.setValidationRuleGroups( new ArrayList<ValidationRuleGroup>( manager.getAll( ValidationRuleGroup.class ) ) );
         }
 
         if ( exportOptions.isSqlViews() )
         {
-            dxf2.setSqlViews( new ArrayList<SqlView>( manager.getAll( SqlView.class ) ) );
+            metaData.setSqlViews( new ArrayList<SqlView>( manager.getAll( SqlView.class ) ) );
         }
 
         if ( exportOptions.isDocuments() )
         {
-            dxf2.setDocuments( new ArrayList<Document>( manager.getAll( Document.class ) ) );
+            metaData.setDocuments( new ArrayList<Document>( manager.getAll( Document.class ) ) );
         }
 
         if ( exportOptions.isReportTables() )
         {
-            dxf2.setReportTables( new ArrayList<ReportTable>( manager.getAll( ReportTable.class ) ) );
+            metaData.setReportTables( new ArrayList<ReportTable>( manager.getAll( ReportTable.class ) ) );
         }
 
         if ( exportOptions.isReports() )
         {
-            dxf2.setReports( new ArrayList<Report>( manager.getAll( Report.class ) ) );
+            metaData.setReports( new ArrayList<Report>( manager.getAll( Report.class ) ) );
         }
 
         if ( exportOptions.isCharts() )
         {
-            dxf2.setCharts( new ArrayList<Chart>( manager.getAll( Chart.class ) ) );
+            metaData.setCharts( new ArrayList<Chart>( manager.getAll( Chart.class ) ) );
         }
 
         if ( exportOptions.isMaps() )
         {
-            dxf2.setMaps( new ArrayList<MapView>( manager.getAll( MapView.class ) ) );
+            metaData.setMaps( new ArrayList<MapView>( manager.getAll( MapView.class ) ) );
         }
 
         if ( exportOptions.isMapLegends() )
         {
-            dxf2.setMapLegends( new ArrayList<MapLegend>( manager.getAll( MapLegend.class ) ) );
+            metaData.setMapLegends( new ArrayList<MapLegend>( manager.getAll( MapLegend.class ) ) );
         }
 
         if ( exportOptions.isMapLegendSets() )
         {
-            dxf2.setMapLegendSets( new ArrayList<MapLegendSet>( manager.getAll( MapLegendSet.class ) ) );
+            metaData.setMapLegendSets( new ArrayList<MapLegendSet>( manager.getAll( MapLegendSet.class ) ) );
         }
 
         if ( exportOptions.isMapLayers() )
         {
-            dxf2.setMapLayers( new ArrayList<MapLayer>( manager.getAll( MapLayer.class ) ) );
+            metaData.setMapLayers( new ArrayList<MapLayer>( manager.getAll( MapLayer.class ) ) );
         }
 
         if ( exportOptions.isDataDictionaries() )
         {
-            dxf2.setDataDictionaries( new ArrayList<DataDictionary>( manager.getAll( DataDictionary.class ) ) );
+            metaData.setDataDictionaries( new ArrayList<DataDictionary>( manager.getAll( DataDictionary.class ) ) );
         }
 
-        return dxf2;
+        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-04-18 20:24:12 +0000
+++ dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/DefaultImportService.java	2012-04-19 16:40:00 +0000
@@ -76,15 +76,11 @@
         // the correct order
 
         // FIXME this is not currently in the "correct" order
-/*        doImport( metaData.getConcepts(), 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.getCategories(), importOptions, importSummary );
         doImport( metaData.getCategoryCombos(), importOptions, importSummary );
         doImport( metaData.getCategoryOptions(), importOptions, importSummary );
@@ -101,13 +97,9 @@
         doImport( metaData.getMapLegendSets(), importOptions, importSummary );
         doImport( metaData.getMapLayers(), importOptions, importSummary );
         doImport( metaData.getMessageConversations(), importOptions, importSummary );
-*/
-
         doImport( metaData.getOrganisationUnits(), 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 );
@@ -116,10 +108,8 @@
         doImport( metaData.getValidationRuleGroups(), importOptions, importSummary );
         doImport( metaData.getDataDictionaries(), importOptions, importSummary );
         doImport( metaData.getReports(), importOptions, importSummary );
-*/
         doImport( metaData.getReportTables(), importOptions, importSummary );
-
-//        doImport( metaData.getCharts(), importOptions, importSummary );
+        doImport( metaData.getCharts(), importOptions, importSummary );
         doImport( metaData.getDataSets(), importOptions, importSummary );
 
         return importSummary;

=== added 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	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/importers/DefaultIdentifiableObjectImporter.java	2012-04-19 16:40:00 +0000
@@ -0,0 +1,707 @@
+package org.hisp.dhis.dxf2.metadata.importers;
+
+/*
+ * 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.*;
+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.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.system.util.ReflectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.lang.reflect.Field;
+import java.util.*;
+
+/**
+ * Importer that can handle IdentifiableObject and NameableObject.
+ *
+ * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
+ */
+public class DefaultIdentifiableObjectImporter<T extends BaseIdentifiableObject>
+    implements Importer<T>
+{
+    private static final Log log = LogFactory.getLog( DefaultIdentifiableObjectImporter.class );
+
+    //-------------------------------------------------------------------------------------------------------
+    // Dependencies
+    //-------------------------------------------------------------------------------------------------------
+
+    @Autowired
+    protected IdentifiableObjectManager manager;
+
+    @Autowired
+    private PeriodService periodService;
+
+    //-------------------------------------------------------------------------------------------------------
+    // Constructor
+    //-------------------------------------------------------------------------------------------------------
+
+    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
+    //-------------------------------------------------------------------------------------------------------
+
+    protected int imported;
+
+    protected int updated;
+
+    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;
+
+    //-------------------------------------------------------------------------------------------------------
+    // Generic implementations of newObject and updatedObject
+    //-------------------------------------------------------------------------------------------------------
+
+    /**
+     * Called every time a new object is to be imported.
+     *
+     * @param object  Object to import
+     * @param options Current import options
+     * @return An ImportConflict instance if there was a conflict, otherwise null
+     */
+    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() );
+
+        log.info( "Trying to save new object with UID: " + object.getUid() );
+
+        saveOrUpdateObjectWithReferences( object, false );
+
+        manager.update( object );
+        updateIdMaps( object );
+
+        log.info( "Save successful." );
+        log.info( object );
+
+        return null;
+    }
+
+    /**
+     * Update object from old => new.
+     *
+     * @param object    Object to import
+     * @param oldObject The current version of the object
+     * @param options   Current import options
+     * @return An ImportConflict instance if there was a conflict, otherwise null
+     */
+    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() + ")" );
+
+        saveOrUpdateObjectWithReferences( object, true );
+
+        oldObject.mergeWith( object );
+        manager.update( oldObject );
+
+        log.info( "Update successful." );
+        log.info( oldObject );
+
+        return null;
+    }
+
+    //-------------------------------------------------------------------------------------------------------
+    // Importer<T> Implementation
+    //-------------------------------------------------------------------------------------------------------
+
+    @Override
+    public List<ImportConflict> importObjects( List<T> objects, ImportOptions options )
+    {
+        List<ImportConflict> conflicts = new ArrayList<ImportConflict>();
+
+        if ( objects.isEmpty() )
+        {
+            return conflicts;
+        }
+
+        reset();
+
+        if ( OrganisationUnit.class.isAssignableFrom( objects.get( 0 ).getClass() ) )
+        {
+            OrganisationUnitUtils.updateParents( (Collection<OrganisationUnit>) objects );
+            Collections.sort( (List<OrganisationUnit>) objects, new OrganisationUnitComparator() );
+        }
+
+        for ( T object : objects )
+        {
+            ImportConflict importConflict = importObjectLocal( object, options );
+
+            if ( importConflict != null )
+            {
+                conflicts.add( importConflict );
+            }
+        }
+
+        return conflicts;
+    }
+
+    @Override
+    public ImportConflict importObject( T object, ImportOptions options )
+    {
+        reset();
+
+        return importObjectLocal( object, options );
+    }
+
+    @Override
+    public ImportCount getCurrentImportCount()
+    {
+        return new ImportCount( imported, updated, ignored );
+    }
+
+    @Override
+    public boolean canHandle( Class<?> clazz )
+    {
+        return importerClass.equals( clazz );
+    }
+
+    //-------------------------------------------------------------------------------------------------------
+    // Protected methods
+    //-------------------------------------------------------------------------------------------------------
+
+    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
+     */
+    protected String getDisplayName( IdentifiableObject object )
+    {
+        if ( object.getUid() != null )
+        {
+            return object.getUid();
+        }
+        else if ( object.getCode() != null )
+        {
+            return object.getCode();
+        }
+        else if ( object.getName() != null )
+        {
+            return object.getName();
+        }
+
+        return object.getClass().getName();
+    }
+
+    /**
+     * Current object name, used to fill name part of a ImportConflict
+     *
+     * @return Name of object
+     */
+    protected String getClassName()
+    {
+        return importerClass.getSimpleName();
+    }
+
+    //-------------------------------------------------------------------------------------------------------
+    // Helpers
+    //-------------------------------------------------------------------------------------------------------
+
+    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 )
+    {
+        ImportConflict conflict = validateIdentifiableObject( object, options );
+
+        if ( conflict == null )
+        {
+            conflict = startImport( object, options );
+        }
+
+        if ( conflict != null )
+        {
+            ignored++;
+        }
+
+        return conflict;
+    }
+
+    private ImportConflict startImport( T object, ImportOptions options )
+    {
+        T oldObject = getObject( object );
+        ImportConflict conflict;
+
+        if ( ImportStrategy.NEW.equals( options.getImportStrategy() ) )
+        {
+            conflict = newObject( object, options );
+
+            if ( conflict != null )
+            {
+                return conflict;
+            }
+
+            imported++;
+        }
+        else if ( ImportStrategy.UPDATES.equals( options.getImportStrategy() ) )
+        {
+            conflict = updatedObject( object, oldObject, options );
+
+            if ( conflict != null )
+            {
+                return conflict;
+            }
+
+            updated++;
+        }
+        else if ( ImportStrategy.NEW_AND_UPDATES.equals( options.getImportStrategy() ) )
+        {
+            if ( oldObject != null )
+            {
+                conflict = updatedObject( object, oldObject, options );
+
+                if ( conflict != null )
+                {
+                    return conflict;
+                }
+
+                updated++;
+            }
+            else
+            {
+                conflict = newObject( object, options );
+
+                if ( conflict != null )
+                {
+                    return conflict;
+                }
+
+                imported++;
+            }
+        }
+
+        return null;
+    }
+
+    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;
+        T alternativeNameObject = null;
+
+        if ( nameable )
+        {
+            NameableObject nameableObject = (NameableObject) object;
+
+            shortNameObject = shortNameMap.get( nameableObject.getShortName() );
+        }
+
+        ImportConflict conflict = null;
+
+        if ( ImportStrategy.NEW.equals( options.getImportStrategy() ) )
+        {
+            conflict = validateForNewStrategy( object, options );
+        }
+        else if ( ImportStrategy.UPDATES.equals( options.getImportStrategy() ) )
+        {
+            conflict = validateForUpdatesStrategy( object, options );
+        }
+        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 || alternativeNameObject != null )
+            {
+                conflict = validateForUpdatesStrategy( object, options );
+            }
+            else
+            {
+                conflict = validateForNewStrategy( object, options );
+            }
+        }
+
+        return conflict;
+    }
+
+    private ImportConflict validateForUpdatesStrategy( 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;
+        T alternativeNameObject = 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 ( alternativeNameObject != null )
+        {
+            nonNullObjects.add( alternativeNameObject );
+        }
+
+        if ( nonNullObjects.isEmpty() )
+        {
+            conflict = reportLookupConflict( object, options );
+        }
+        else if ( nonNullObjects.size() > 1 )
+        {
+            conflict = reportMoreThanOneConflict( object, options );
+        }
+
+        return conflict;
+    }
+
+    private ImportConflict validateForNewStrategy( 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;
+        T alternativeNameObject = null;
+
+        if ( nameable )
+        {
+            NameableObject nameableObject = (NameableObject) object;
+
+            shortNameObject = shortNameMap.get( nameableObject.getShortName() );
+        }
+
+        ImportConflict conflict = null;
+
+        if ( uidObject != null || codeObject != null || nameObject != null || shortNameObject != null || alternativeNameObject != null )
+        {
+            conflict = reportConflict( object, options );
+        }
+
+        return conflict;
+    }
+
+    private ImportConflict reportLookupConflict( IdentifiableObject object, ImportOptions options )
+    {
+        return new ImportConflict( getDisplayName( object ), "Object does not exist." );
+    }
+
+    private ImportConflict reportMoreThanOneConflict( IdentifiableObject object, ImportOptions options )
+    {
+        return new ImportConflict( getDisplayName( object ), "More than one object matches identifiers." );
+    }
+
+    private ImportConflict reportConflict( IdentifiableObject object, ImportOptions options )
+    {
+        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;
+
+        // FIXME this is a bit too static ATM, should be refactored out into its own "type handler"
+        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 match;
+    }
+
+    private Map<Field, IdentifiableObject> scanIdentifiableObjects( IdentifiableObject identifiableObject )
+    {
+        Map<Field, IdentifiableObject> identifiableObjects = new HashMap<Field, IdentifiableObject>();
+        Field[] fields = identifiableObject.getClass().getDeclaredFields();
+
+        for ( Field field : fields )
+        {
+            if ( ReflectionUtils.isType( field, IdentifiableObject.class ) )
+            {
+                IdentifiableObject ref = ReflectionUtils.invokeGetterMethod( field.getName(), identifiableObject );
+
+                if ( ref != null )
+                {
+                    identifiableObjects.put( field, ref );
+                }
+            }
+        }
+
+        return identifiableObjects;
+    }
+
+    private void updateIdentifiableObjects( IdentifiableObject identifiableObject, Map<Field, IdentifiableObject> identifiableObjects )
+    {
+        for ( Field field : identifiableObjects.keySet() )
+        {
+            IdentifiableObject ref = findObjectByReference( identifiableObject );
+
+            if ( ref != null )
+            {
+                ReflectionUtils.invokeSetterMethod( field.getName(), identifiableObject, ref );
+            }
+            else
+            {
+                log.info( "--> Ignored reference " + getDisplayName( identifiableObject ) + "." );
+            }
+        }
+    }
+
+    private Map<Field, Set<? extends IdentifiableObject>> scanIdentifiableObjectCollections( IdentifiableObject identifiableObject )
+    {
+        Map<Field, Set<? extends IdentifiableObject>> collected = new HashMap<Field, Set<? extends IdentifiableObject>>();
+        Field[] fields = identifiableObject.getClass().getDeclaredFields();
+
+        for ( Field field : fields )
+        {
+            boolean b = ReflectionUtils.isCollection( field.getName(), identifiableObject, IdentifiableObject.class, Scanned.class );
+
+            if ( b )
+            {
+                Collection<IdentifiableObject> objects = ReflectionUtils.invokeGetterMethod( field.getName(), identifiableObject );
+
+                if ( objects != null && !objects.isEmpty() )
+                {
+                    Set<IdentifiableObject> identifiableObjects = new HashSet<IdentifiableObject>( objects );
+                    collected.put( field, identifiableObjects );
+                    objects.clear();
+                }
+            }
+        }
+
+        return collected;
+    }
+
+    private void updateIdentifiableObjectCollections( IdentifiableObject identifiableObject,
+                                                      Map<Field, Set<? extends IdentifiableObject>> identifiableObjectCollections )
+    {
+        for ( Field field : identifiableObjectCollections.keySet() )
+        {
+            Collection<? extends IdentifiableObject> identifiableObjects = identifiableObjectCollections.get( field );
+            Collection<IdentifiableObject> objects = null;
+
+            if ( List.class.isAssignableFrom( field.getType() ) )
+            {
+                objects = new ArrayList<IdentifiableObject>();
+            }
+            else if ( Set.class.isAssignableFrom( field.getType() ) )
+            {
+                objects = new HashSet<IdentifiableObject>();
+            }
+            else
+            {
+                log.warn( "Unknown Collection type!" );
+            }
+
+            for ( IdentifiableObject idObject : identifiableObjects )
+            {
+                IdentifiableObject ref = findObjectByReference( idObject );
+
+                if ( ref != null )
+                {
+                    objects.add( ref );
+                }
+                else
+                {
+                    log.info( "--> Ignored reference " + getDisplayName( identifiableObject ) + "." );
+                }
+            }
+
+            ReflectionUtils.invokeSetterMethod( field.getName(), identifiableObject, objects );
+        }
+    }
+
+    private void saveOrUpdateObjectWithReferences( T object, boolean update )
+    {
+        log.info( "-> Finding and updating references." );
+
+        Map<Field, IdentifiableObject> identifiableObjects = scanIdentifiableObjects( object );
+        Map<Field, Set<? extends IdentifiableObject>> identifiableObjectCollections = scanIdentifiableObjectCollections( object );
+
+        updateIdentifiableObjects( object, identifiableObjects );
+
+        if ( !update )
+        {
+            manager.save( object );
+        }
+
+        updateIdentifiableObjectCollections( object, identifiableObjectCollections );
+    }
+}

=== removed file 'dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/importers/DefaultImporter.java'
--- dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/importers/DefaultImporter.java	2012-04-18 20:36:56 +0000
+++ dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/importers/DefaultImporter.java	1970-01-01 00:00:00 +0000
@@ -1,686 +0,0 @@
-package org.hisp.dhis.dxf2.metadata.importers;
-
-/*
- * 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.*;
-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.importexport.ImportStrategy;
-import org.hisp.dhis.period.Period;
-import org.hisp.dhis.period.PeriodService;
-import org.hisp.dhis.system.util.ReflectionUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-
-import java.lang.reflect.Field;
-import java.util.*;
-
-/**
- * Importer that can handle IdentifiableObject and NameableObject.
- *
- * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
- */
-public class DefaultImporter<T extends BaseIdentifiableObject>
-    implements Importer<T>
-{
-    private static final Log log = LogFactory.getLog( DefaultImporter.class );
-
-    //-------------------------------------------------------------------------------------------------------
-    // Dependencies
-    //-------------------------------------------------------------------------------------------------------
-
-    @Autowired
-    protected IdentifiableObjectManager manager;
-
-    @Autowired
-    private PeriodService periodService;
-
-    //-------------------------------------------------------------------------------------------------------
-    // Constructor
-    //-------------------------------------------------------------------------------------------------------
-
-    public DefaultImporter( Class<T> importerClass )
-    {
-        this.importerClass = importerClass;
-        this.nameable = NameableObject.class.isAssignableFrom( importerClass );
-    }
-
-    private final Class<T> importerClass;
-
-    private final boolean nameable;
-
-    //-------------------------------------------------------------------------------------------------------
-    // Current import counts
-    //-------------------------------------------------------------------------------------------------------
-
-    protected int imported;
-
-    protected int updated;
-
-    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;
-
-    protected Map<String, T> alternativeNameMap;
-
-    //-------------------------------------------------------------------------------------------------------
-    // Generic implementations of newObject and updatedObject
-    //-------------------------------------------------------------------------------------------------------
-
-    /**
-     * Called every time a new object is to be imported.
-     *
-     * @param object  Object to import
-     * @param options Current import options
-     * @return An ImportConflict instance if there was a conflict, otherwise null
-     */
-    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() );
-
-        log.info( "Trying to save new object with UID: " + object.getUid() );
-
-        saveOrUpdateObjectWithReferences( object, false );
-
-        manager.update( object );
-        updateIdMaps( object );
-
-        log.info( "Save successful." );
-        log.info( object );
-
-        return null;
-    }
-
-    /**
-     * Update object from old => new.
-     *
-     * @param object    Object to import
-     * @param oldObject The current version of the object
-     * @param options   Current import options
-     * @return An ImportConflict instance if there was a conflict, otherwise null
-     */
-    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() + ")" );
-
-        saveOrUpdateObjectWithReferences( object, true );
-
-        oldObject.mergeWith( object );
-        manager.update( oldObject );
-
-        log.info( "Update successful." );
-        log.info( oldObject );
-
-        return null;
-    }
-
-    //-------------------------------------------------------------------------------------------------------
-    // Importer<T> Implementation
-    //-------------------------------------------------------------------------------------------------------
-
-    @Override
-    public List<ImportConflict> importObjects( List<T> objects, ImportOptions options )
-    {
-        List<ImportConflict> conflicts = new ArrayList<ImportConflict>();
-
-        if ( objects.isEmpty() )
-        {
-            return conflicts;
-        }
-
-        reset();
-
-        for ( T object : objects )
-        {
-            ImportConflict importConflict = importObjectLocal( object, options );
-
-            if ( importConflict != null )
-            {
-                conflicts.add( importConflict );
-            }
-        }
-
-        return conflicts;
-    }
-
-    @Override
-    public ImportConflict importObject( T object, ImportOptions options )
-    {
-        reset();
-
-        return importObjectLocal( object, options );
-    }
-
-    @Override
-    public ImportCount getCurrentImportCount()
-    {
-        return new ImportCount( imported, updated, ignored );
-    }
-
-    @Override
-    public boolean canHandle( Class<?> clazz )
-    {
-        return importerClass.equals( clazz );
-    }
-
-    //-------------------------------------------------------------------------------------------------------
-    // Protected methods
-    //-------------------------------------------------------------------------------------------------------
-
-    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 );
-            }
-
-            if ( nameableObject.getAlternativeName() != null )
-            {
-                alternativeNameMap.put( nameableObject.getAlternativeName(), object );
-            }
-        }
-    }
-
-    /**
-     * @param object Object to get display name for
-     * @return A usable display name
-     */
-    protected String getDisplayName( IdentifiableObject object )
-    {
-        if ( object.getUid() != null )
-        {
-            return object.getUid();
-        }
-        else if ( object.getCode() != null )
-        {
-            return object.getCode();
-        }
-        else if ( object.getName() != null )
-        {
-            return object.getName();
-        }
-
-        return object.getClass().getName();
-    }
-
-    /**
-     * Current object name, used to fill name part of a ImportConflict
-     *
-     * @return Name of object
-     */
-    protected String getClassName()
-    {
-        return importerClass.getSimpleName();
-    }
-
-    //-------------------------------------------------------------------------------------------------------
-    // Helpers
-    //-------------------------------------------------------------------------------------------------------
-
-    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 );
-            alternativeNameMap = (Map<String, T>) manager.getIdMap( (Class<? extends NameableObject>) importerClass, NameableObject.NameableProperty.ALTERNATIVE_NAME );
-        }
-    }
-
-    private ImportConflict importObjectLocal( T object, ImportOptions options )
-    {
-        ImportConflict conflict = validateIdentifiableObject( object, options );
-
-        if ( conflict == null )
-        {
-            conflict = startImport( object, options );
-        }
-
-        if ( conflict != null )
-        {
-            ignored++;
-        }
-
-        return conflict;
-    }
-
-    private ImportConflict startImport( T object, ImportOptions options )
-    {
-        T oldObject = getObject( object );
-        ImportConflict conflict;
-
-        if ( ImportStrategy.NEW.equals( options.getImportStrategy() ) )
-        {
-            conflict = newObject( object, options );
-
-            if ( conflict != null )
-            {
-                return conflict;
-            }
-
-            imported++;
-        }
-        else if ( ImportStrategy.UPDATES.equals( options.getImportStrategy() ) )
-        {
-            conflict = updatedObject( object, oldObject, options );
-
-            if ( conflict != null )
-            {
-                return conflict;
-            }
-
-            updated++;
-        }
-        else if ( ImportStrategy.NEW_AND_UPDATES.equals( options.getImportStrategy() ) )
-        {
-            if ( oldObject != null )
-            {
-                conflict = updatedObject( object, oldObject, options );
-
-                if ( conflict != null )
-                {
-                    return conflict;
-                }
-
-                updated++;
-            }
-            else
-            {
-                conflict = newObject( object, options );
-
-                if ( conflict != null )
-                {
-                    return conflict;
-                }
-
-                imported++;
-            }
-        }
-
-        return null;
-    }
-
-    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;
-        T alternativeNameObject = null;
-
-        if ( nameable )
-        {
-            NameableObject nameableObject = (NameableObject) object;
-
-            shortNameObject = shortNameMap.get( nameableObject.getShortName() );
-            alternativeNameObject = alternativeNameMap.get( nameableObject.getAlternativeName() );
-        }
-
-        ImportConflict conflict = null;
-
-        if ( ImportStrategy.NEW.equals( options.getImportStrategy() ) )
-        {
-            conflict = validateForNewStrategy( object, options );
-        }
-        else if ( ImportStrategy.UPDATES.equals( options.getImportStrategy() ) )
-        {
-            conflict = validateForUpdatesStrategy( object, options );
-        }
-        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 || alternativeNameObject != null )
-            {
-                conflict = validateForUpdatesStrategy( object, options );
-            }
-            else
-            {
-                conflict = validateForNewStrategy( object, options );
-            }
-        }
-
-        return conflict;
-    }
-
-    private ImportConflict validateForUpdatesStrategy( 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;
-        T alternativeNameObject = null;
-
-        if ( nameable )
-        {
-            NameableObject nameableObject = (NameableObject) object;
-
-            shortNameObject = shortNameMap.get( nameableObject.getShortName() );
-            alternativeNameObject = alternativeNameMap.get( nameableObject.getAlternativeName() );
-        }
-
-        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 ( alternativeNameObject != null )
-        {
-            nonNullObjects.add( alternativeNameObject );
-        }
-
-        if ( nonNullObjects.isEmpty() )
-        {
-            conflict = reportLookupConflict( object, options );
-        }
-        else if ( nonNullObjects.size() > 1 )
-        {
-            conflict = reportMoreThanOneConflict( object, options );
-        }
-
-        return conflict;
-    }
-
-    private ImportConflict validateForNewStrategy( 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;
-        T alternativeNameObject = null;
-
-        if ( nameable )
-        {
-            NameableObject nameableObject = (NameableObject) object;
-
-            shortNameObject = shortNameMap.get( nameableObject.getShortName() );
-            alternativeNameObject = alternativeNameMap.get( nameableObject.getAlternativeName() );
-        }
-
-        ImportConflict conflict = null;
-
-        if ( uidObject != null || codeObject != null || nameObject != null || shortNameObject != null || alternativeNameObject != null )
-        {
-            conflict = reportConflict( object, options );
-        }
-
-        return conflict;
-    }
-
-    private ImportConflict reportLookupConflict( IdentifiableObject object, ImportOptions options )
-    {
-        return new ImportConflict( getDisplayName( object ), "Object does not exist." );
-    }
-
-    private ImportConflict reportMoreThanOneConflict( IdentifiableObject object, ImportOptions options )
-    {
-        return new ImportConflict( getDisplayName( object ), "More than one object matches identifiers." );
-    }
-
-    private ImportConflict reportConflict( IdentifiableObject object, ImportOptions options )
-    {
-        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;
-            }
-
-            matchedObject = alternativeNameMap.get( nameableObject.getAlternativeName() );
-
-            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;
-
-        if ( Period.class.isAssignableFrom( identifiableObject.getClass() ) )
-        {
-            // FIXME this is not working..
-            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 match;
-    }
-
-    private void saveOrUpdateObjectWithReferences( T object, boolean update )
-    {
-        Field[] fields = object.getClass().getDeclaredFields();
-
-        log.info( "-> Finding and updating references." );
-
-        Map<Field, Set<? extends IdentifiableObject>> collectedCollections = new HashMap<Field, Set<? extends IdentifiableObject>>();
-
-        for ( Field field : fields )
-        {
-            if ( ReflectionUtils.isType( field, IdentifiableObject.class ) )
-            {
-                IdentifiableObject identifiableObject = ReflectionUtils.invokeGetterMethod( field.getName(), object );
-
-                if ( identifiableObject != null )
-                {
-                    IdentifiableObject ref = findObjectByReference( identifiableObject );
-
-                    if ( ref != null )
-                    {
-                        ReflectionUtils.invokeSetterMethod( field.getName(), object, ref );
-                    }
-                    else
-                    {
-                        log.info( "--> Ignored reference " + getDisplayName( identifiableObject ) + "." );
-                    }
-                }
-            }
-            else
-            {
-                boolean b = ReflectionUtils.isCollection( field.getName(), object, IdentifiableObject.class, Scanned.class );
-
-                if ( b )
-                {
-                    Collection<IdentifiableObject> objects = ReflectionUtils.invokeGetterMethod( field.getName(), object );
-
-                    if ( objects != null && !objects.isEmpty() )
-                    {
-                        Set<IdentifiableObject> identifiableObjects = new HashSet<IdentifiableObject>( objects );
-                        collectedCollections.put( field, identifiableObjects );
-                        objects.clear();
-                    }
-                }
-            }
-        }
-
-        if ( !update )
-        {
-            manager.save( object );
-        }
-
-        for ( Field field : collectedCollections.keySet() )
-        {
-            log.info( field.getName() );
-
-            Collection<? extends IdentifiableObject> identifiableObjects = collectedCollections.get( field );
-            Collection<IdentifiableObject> objects = null;
-
-            if ( List.class.isAssignableFrom( field.getType() ) )
-            {
-                objects = new ArrayList<IdentifiableObject>();
-            }
-            else if ( Set.class.isAssignableFrom( field.getType() ) )
-            {
-                objects = new HashSet<IdentifiableObject>();
-            }
-            else
-            {
-                log.warn( "Unknown Collection type!" );
-            }
-
-            for ( IdentifiableObject identifiableObject : identifiableObjects )
-            {
-                IdentifiableObject ref = findObjectByReference( identifiableObject );
-
-                if ( ref != null )
-                {
-                    objects.add( ref );
-                }
-                else
-                {
-                    log.info( "--> Ignored reference " + getDisplayName( identifiableObject ) + "." );
-                }
-            }
-
-            ReflectionUtils.invokeSetterMethod( field.getName(), object, objects );
-        }
-    }
-}

=== added file 'dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/utils/OrganisationUnitUtils.java'
--- dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/utils/OrganisationUnitUtils.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/utils/OrganisationUnitUtils.java	2012-04-19 16:40:00 +0000
@@ -0,0 +1,105 @@
+package org.hisp.dhis.dxf2.utils;
+
+/*
+ * 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.organisationunit.OrganisationUnit;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
+ */
+public class OrganisationUnitUtils
+{
+    private static Map<String, OrganisationUnit> getOrganisationUnitMap( Collection<OrganisationUnit> organisationUnits )
+    {
+        Map<String, OrganisationUnit> organisationUnitMap = new HashMap<String, OrganisationUnit>();
+
+        for ( OrganisationUnit organisationUnit : organisationUnits )
+        {
+            OrganisationUnit parent = organisationUnit.getParent();
+
+            if ( parent != null )
+            {
+                if ( parent.getUid() != null )
+                {
+                    organisationUnitMap.put( parent.getUid(), parent );
+                }
+
+                if ( parent.getCode() != null )
+                {
+                    organisationUnitMap.put( parent.getCode(), parent );
+                }
+
+                if ( parent.getName() != null )
+                {
+                    organisationUnitMap.put( parent.getName(), parent );
+                }
+
+                if ( parent.getShortName() != null )
+                {
+                    organisationUnitMap.put( parent.getShortName(), parent );
+                }
+            }
+        }
+
+        return organisationUnitMap;
+    }
+
+    public static void updateParents( Collection<OrganisationUnit> organisationUnits )
+    {
+        Map<String, OrganisationUnit> organisationUnitMap = getOrganisationUnitMap( organisationUnits );
+
+        for ( OrganisationUnit organisationUnit : organisationUnits )
+        {
+            OrganisationUnit parent = organisationUnit.getParent();
+
+            if ( parent != null )
+            {
+                if ( parent.getUid() != null )
+                {
+                    organisationUnit.setParent( organisationUnitMap.get( parent.getUid() ) );
+                }
+                else if ( parent.getCode() != null )
+                {
+                    organisationUnit.setParent( organisationUnitMap.get( parent.getCode() ) );
+                }
+                else if ( parent.getName() != null )
+                {
+                    organisationUnit.setParent( organisationUnitMap.get( parent.getName() ) );
+                }
+                else if ( parent.getShortName() != null )
+                {
+                    organisationUnit.setParent( organisationUnitMap.get( parent.getShortName() ) );
+                }
+            }
+        }
+    }
+}

=== 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-17 08:04:52 +0000
+++ dhis-2/dhis-dxf2/src/main/resources/META-INF/dhis/beans.xml	2012-04-19 16:40:00 +0000
@@ -13,147 +13,147 @@
 
   <!-- register importers -->
 
-  <bean id="attributeTypeImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultImporter">
+  <bean id="attributeTypeImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultIdentifiableObjectImporter">
     <constructor-arg name="importerClass" type="java.lang.Class" value="org.hisp.dhis.attribute.Attribute" />
   </bean>
 
-  <bean id="optionSetImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultImporter">
+  <bean id="optionSetImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultIdentifiableObjectImporter">
     <constructor-arg name="importerClass" type="java.lang.Class" value="org.hisp.dhis.option.OptionSet" />
   </bean>
 
-  <bean id="categoryImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultImporter">
+  <bean id="categoryImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultIdentifiableObjectImporter">
     <constructor-arg name="importerClass" type="java.lang.Class"
         value="org.hisp.dhis.dataelement.DataElementCategory" />
   </bean>
 
-  <bean id="categoryComboImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultImporter">
+  <bean id="categoryComboImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultIdentifiableObjectImporter">
     <constructor-arg name="importerClass" type="java.lang.Class"
         value="org.hisp.dhis.dataelement.DataElementCategoryCombo" />
   </bean>
 
-  <bean id="categoryOptionImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultImporter">
+  <bean id="categoryOptionImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultIdentifiableObjectImporter">
     <constructor-arg name="importerClass" type="java.lang.Class"
         value="org.hisp.dhis.dataelement.DataElementCategoryOption" />
   </bean>
 
-  <bean id="categoryOptionComboImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultImporter">
+  <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>
 
-  <bean id="dataElementImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultImporter">
+  <bean id="dataElementImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultIdentifiableObjectImporter">
     <constructor-arg name="importerClass" type="java.lang.Class" value="org.hisp.dhis.dataelement.DataElement" />
   </bean>
 
-  <bean id="dataElementGroupImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultImporter">
+  <bean id="dataElementGroupImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultIdentifiableObjectImporter">
     <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.DefaultImporter">
+  <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>
 
-  <bean id="chartImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultImporter">
+  <bean id="chartImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultIdentifiableObjectImporter">
     <constructor-arg name="importerClass" type="java.lang.Class" value="org.hisp.dhis.chart.Chart" />
   </bean>
 
-  <bean id="conceptImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultImporter">
+  <bean id="conceptImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultIdentifiableObjectImporter">
     <constructor-arg name="importerClass" type="java.lang.Class" value="org.hisp.dhis.concept.Concept" />
   </bean>
 
-  <bean id="constantImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultImporter">
+  <bean id="constantImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultIdentifiableObjectImporter">
     <constructor-arg name="importerClass" type="java.lang.Class" value="org.hisp.dhis.constant.Constant" />
   </bean>
 
-  <bean id="dataSetImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultImporter">
+  <bean id="dataSetImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultIdentifiableObjectImporter">
     <constructor-arg name="importerClass" type="java.lang.Class" value="org.hisp.dhis.dataset.DataSet" />
   </bean>
 
-  <bean id="documentImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultImporter">
+  <bean id="documentImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultIdentifiableObjectImporter">
     <constructor-arg name="importerClass" type="java.lang.Class" value="org.hisp.dhis.document.Document" />
   </bean>
 
-  <bean id="indicatorImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultImporter">
+  <bean id="indicatorImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultIdentifiableObjectImporter">
     <constructor-arg name="importerClass" type="java.lang.Class" value="org.hisp.dhis.indicator.Indicator" />
   </bean>
 
-  <bean id="indicatorTypeImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultImporter">
+  <bean id="indicatorTypeImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultIdentifiableObjectImporter">
     <constructor-arg name="importerClass" type="java.lang.Class" value="org.hisp.dhis.indicator.IndicatorType" />
   </bean>
 
-  <bean id="indicatorGroupImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultImporter">
+  <bean id="indicatorGroupImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultIdentifiableObjectImporter">
     <constructor-arg name="importerClass" type="java.lang.Class" value="org.hisp.dhis.indicator.IndicatorGroup" />
   </bean>
 
-  <bean id="indicatorGroupSetImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultImporter">
+  <bean id="indicatorGroupSetImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultIdentifiableObjectImporter">
     <constructor-arg name="importerClass" type="java.lang.Class" value="org.hisp.dhis.indicator.IndicatorGroupSet" />
   </bean>
 
-  <bean id="mapViewImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultImporter">
+  <bean id="mapViewImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultIdentifiableObjectImporter">
     <constructor-arg name="importerClass" type="java.lang.Class" value="org.hisp.dhis.mapping.MapView" />
   </bean>
 
-  <bean id="mapLegendImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultImporter">
+  <bean id="mapLegendImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultIdentifiableObjectImporter">
     <constructor-arg name="importerClass" type="java.lang.Class" value="org.hisp.dhis.mapping.MapLegend" />
   </bean>
 
-  <bean id="mapLegendSetImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultImporter">
+  <bean id="mapLegendSetImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultIdentifiableObjectImporter">
     <constructor-arg name="importerClass" type="java.lang.Class" value="org.hisp.dhis.mapping.MapLegendSet" />
   </bean>
 
-  <bean id="mapLayerImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultImporter">
+  <bean id="mapLayerImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultIdentifiableObjectImporter">
     <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.DefaultImporter">
+  <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>
 
-  <bean id="organisationUnitImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultImporter">
+  <bean id="organisationUnitImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultIdentifiableObjectImporter">
     <constructor-arg name="importerClass" type="java.lang.Class"
         value="org.hisp.dhis.organisationunit.OrganisationUnit" />
   </bean>
 
-  <bean id="organisationUnitGroupImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultImporter">
+  <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.DefaultImporter">
+  <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>
 
-  <bean id="reportImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultImporter">
+  <bean id="reportImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultIdentifiableObjectImporter">
     <constructor-arg name="importerClass" type="java.lang.Class" value="org.hisp.dhis.report.Report" />
   </bean>
 
-  <bean id="reportTableImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultImporter">
+  <bean id="reportTableImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultIdentifiableObjectImporter">
     <constructor-arg name="importerClass" type="java.lang.Class" value="org.hisp.dhis.reporttable.ReportTable" />
   </bean>
 
-  <bean id="sqlViewImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultImporter">
+  <bean id="sqlViewImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultIdentifiableObjectImporter">
     <constructor-arg name="importerClass" type="java.lang.Class" value="org.hisp.dhis.sqlview.SqlView" />
   </bean>
 
-  <bean id="userImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultImporter">
+  <bean id="userImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultIdentifiableObjectImporter">
     <constructor-arg name="importerClass" type="java.lang.Class" value="org.hisp.dhis.user.User" />
   </bean>
 
-  <bean id="userGroupImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultImporter">
+  <bean id="userGroupImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultIdentifiableObjectImporter">
     <constructor-arg name="importerClass" type="java.lang.Class" value="org.hisp.dhis.user.UserGroup" />
   </bean>
 
-  <bean id="userAuthorityGroupImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultImporter">
+  <bean id="userAuthorityGroupImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultIdentifiableObjectImporter">
     <constructor-arg name="importerClass" type="java.lang.Class" value="org.hisp.dhis.user.UserAuthorityGroup" />
   </bean>
 
-  <bean id="validationRuleImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultImporter">
+  <bean id="validationRuleImporter" class="org.hisp.dhis.dxf2.metadata.importers.DefaultIdentifiableObjectImporter">
     <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.DefaultImporter">
+  <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>
 

=== modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/DataValueSetController.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/DataValueSetController.java	2012-04-15 20:21:18 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/DataValueSetController.java	2012-04-19 16:40:00 +0000
@@ -81,11 +81,11 @@
                                  HttpServletResponse response ) throws IOException
     {
         log.info( "Get data value set for data set: " + dataSet + ", period: " + period + ", org unit: " + orgUnit );
-        
+
         response.setContentType( CONTENT_TYPE_XML );
         dataValueSetService.writeDataValueSet( dataSet, period, orgUnit, response.getOutputStream() );
     }
-    
+
     @RequestMapping( method = RequestMethod.POST, headers = {"Content-Type=application/xml"} )
     @PreAuthorize( "hasRole('ALL') or hasRole('F_DATAVALUE_ADD')" )
     public void postDataValueSet( ImportOptions importOptions,