← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 6636: Fixes to the importer. More stuff works, but Period still has issues.

 

------------------------------------------------------------
revno: 6636
committer: Morten Olav Hansen <mortenoh@xxxxxxxxx>
branch nick: dhis2
timestamp: Wed 2012-04-18 23:24:12 +0300
message:
  Fixes to the importer. More stuff works, but Period still has issues.
added:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/adapter/JacksonPeriodDeserializer.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/adapter/JacksonPeriodSerializer.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/annotation/
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/annotation/Scanned.java
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/chart/Chart.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataset/DataSet.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataset/Section.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnit.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnitGroup.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnitGroupSet.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/period/Period.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/reporttable/ReportTable.java
  dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/DefaultImportService.java
  dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/importers/DefaultImporter.java
  dhis-2/dhis-services/dhis-service-reporting/src/main/resources/org/hisp/dhis/reporttable/hibernate/ReportTable.hbm.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/chart/Chart.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/chart/Chart.java	2012-04-17 14:23:08 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/chart/Chart.java	2012-04-18 20:24:12 +0000
@@ -38,6 +38,7 @@
 import org.hisp.dhis.common.Dxf2Namespace;
 import org.hisp.dhis.common.IdentifiableObject;
 import org.hisp.dhis.common.NameableObject;
+import org.hisp.dhis.common.annotation.Scanned;
 import org.hisp.dhis.common.view.DetailedView;
 import org.hisp.dhis.common.view.ExportView;
 import org.hisp.dhis.dataelement.DataElement;
@@ -112,18 +113,22 @@
 
     private String baseLineLabel;
 
+    @Scanned
     private List<Indicator> indicators = new ArrayList<Indicator>();
 
+    @Scanned
     private List<DataElement> dataElements = new ArrayList<DataElement>();
 
+    @Scanned
     private List<DataSet> dataSets = new ArrayList<DataSet>();
 
+    @Scanned
     private List<OrganisationUnit> organisationUnits = new ArrayList<OrganisationUnit>();
 
     private RelativePeriods relatives;
 
     private boolean userOrganisationUnit;
-    
+
     private boolean userOrganisationUnitChildren;
 
     private User user;
@@ -690,9 +695,16 @@
             user = chart.getUser() == null ? user : chart.getUser();
             organisationUnitGroupSet = chart.getOrganisationUnitGroupSet() == null ? organisationUnitGroupSet : chart.getOrganisationUnitGroupSet();
 
+            indicators.clear();
             indicators.addAll( chart.getIndicators() );
+
+            dataElements.clear();
             dataElements.addAll( chart.getDataElements() );
+
+            dataSets.clear();
             dataSets.addAll( chart.getDataSets() );
+
+            organisationUnits.clear();
             organisationUnits.addAll( chart.getOrganisationUnits() );
         }
     }

=== added file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/adapter/JacksonPeriodDeserializer.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/adapter/JacksonPeriodDeserializer.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/adapter/JacksonPeriodDeserializer.java	2012-04-18 20:24:12 +0000
@@ -0,0 +1,52 @@
+package org.hisp.dhis.common.adapter;
+
+/*
+ * 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 com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import org.hisp.dhis.period.Period;
+import org.hisp.dhis.period.PeriodType;
+
+import java.io.IOException;
+
+/**
+ * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
+ */
+public class JacksonPeriodDeserializer
+    extends JsonDeserializer<Period>
+{
+    @Override
+    public Period deserialize( JsonParser jp, DeserializationContext ctxt ) throws IOException, JsonProcessingException
+    {
+        String periodString = jp.readValueAs( String.class );
+
+        return PeriodType.getPeriodFromIsoString( periodString );
+    }
+}

=== added file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/adapter/JacksonPeriodSerializer.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/adapter/JacksonPeriodSerializer.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/adapter/JacksonPeriodSerializer.java	2012-04-18 20:24:12 +0000
@@ -0,0 +1,52 @@
+package org.hisp.dhis.common.adapter;
+
+/*
+ * 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 com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import org.hisp.dhis.period.Period;
+
+import java.io.IOException;
+
+/**
+ * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
+ */
+public class JacksonPeriodSerializer
+    extends JsonSerializer<Period>
+{
+    @Override
+    public void serialize( Period value, JsonGenerator jgen, SerializerProvider provider ) throws IOException, JsonProcessingException
+    {
+        if ( value.getIsoDate() != null )
+        {
+            jgen.writeString( value.getIsoDate() );
+        }
+    }
+}

=== added directory 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/annotation'
=== added 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	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/annotation/Scanned.java	2012-04-18 20:24:12 +0000
@@ -0,0 +1,27 @@
+package org.hisp.dhis.common.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * A very simple annotation that is currently only used for marking identifiable collections
+ * that should be part of the auto-populating reference scanning of the DefaultImporter.
+ *
+ * This is here to separate between collections that we want scanned (e.g. dataSet.indicators) and collections
+ * that we don't want scanned (e.g. reportTable.allIndicators).
+ *
+ * TODO
+ *  - refactor out scanner from DefaultImporter
+ *  - add support for profiling (only scan for this profile, etc)
+ *  - add support for annotation the setter or getter also
+ *
+ * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
+ */
+@Target( {ElementType.FIELD} )
+@Retention( RetentionPolicy.RUNTIME )
+public @interface Scanned
+{
+    String[] value() default {};
+}

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataset/DataSet.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataset/DataSet.java	2012-04-17 08:04:52 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataset/DataSet.java	2012-04-18 20:24:12 +0000
@@ -40,6 +40,7 @@
 import org.hisp.dhis.common.IdentifiableObject;
 import org.hisp.dhis.common.adapter.JacksonPeriodTypeDeserializer;
 import org.hisp.dhis.common.adapter.JacksonPeriodTypeSerializer;
+import org.hisp.dhis.common.annotation.Scanned;
 import org.hisp.dhis.common.view.DetailedView;
 import org.hisp.dhis.common.view.ExportView;
 import org.hisp.dhis.dataelement.DataElement;
@@ -81,28 +82,33 @@
     /**
      * All DataElements associated with this DataSet.
      */
+    @Scanned
     private Set<DataElement> dataElements = new HashSet<DataElement>();
 
     /**
      * Indicators associated with this data set. Indicators are used for view and
      * output purposes, such as calculated fields in forms and reports.
      */
+    @Scanned
     private Set<Indicator> indicators = new HashSet<Indicator>();
 
     /**
      * The DataElementOperands for which data must be entered in order for the
      * DataSet to be considered as complete.
      */
+    @Scanned
     private Set<DataElementOperand> compulsoryDataElementOperands = new HashSet<DataElementOperand>();
 
     /**
      * All Sources that register data with this DataSet.
      */
+    @Scanned
     private Set<OrganisationUnit> sources = new HashSet<OrganisationUnit>();
 
     /**
      * The Sections associated with the DataSet.
      */
+    @Scanned
     private Set<Section> sections = new HashSet<Section>();
 
     /**
@@ -180,6 +186,11 @@
         unit.getDataSets().remove( this );
     }
 
+    public void removeAllOrganisationUnits()
+    {
+        sources.clear();
+    }
+
     public void updateOrganisationUnits( Set<OrganisationUnit> updates )
     {
         for ( OrganisationUnit unit : new HashSet<OrganisationUnit>( sources ) )
@@ -208,6 +219,11 @@
         dataElement.getDataSets().remove( dataElement );
     }
 
+    public void removeAllDataElements()
+    {
+        dataElements.clear();
+    }
+
     public void updateDataElements( Set<DataElement> updates )
     {
         for ( DataElement dataElement : new HashSet<DataElement>( dataElements ) )
@@ -236,6 +252,26 @@
         indicator.getDataSets().remove( this );
     }
 
+    public void removeAllIndicators()
+    {
+        indicators.clear();
+    }
+
+    public void addCompulsoryDataElementOperand( DataElementOperand dataElementOperand )
+    {
+        compulsoryDataElementOperands.add( dataElementOperand );
+    }
+
+    public void removeCompulsoryDataElementOperand( DataElementOperand dataElementOperand )
+    {
+        compulsoryDataElementOperands.remove( dataElementOperand );
+    }
+
+    public void removeAllCompulsoryDataElementOperands()
+    {
+        compulsoryDataElementOperands.clear();
+    }
+
     public boolean hasDataEntryForm()
     {
         return dataEntryForm != null;
@@ -488,45 +524,33 @@
             version = version != null ? version : dataSet.getVersion();
             expiryDays = dataSet.getExpiryDays();
 
-            dataElements.clear();
+            removeAllDataElements();
 
             for ( DataElement dataElement : dataSet.getDataElements() )
             {
                 addDataElement( dataElement );
             }
 
-            indicators.clear();
+            removeAllIndicators();
 
             for ( Indicator indicator : dataSet.getIndicators() )
             {
                 addIndicator( indicator );
             }
 
-            compulsoryDataElementOperands.clear();
+            removeAllCompulsoryDataElementOperands();
 
             for ( DataElementOperand dataElementOperand : dataSet.getCompulsoryDataElementOperands() )
             {
-                compulsoryDataElementOperands.add( dataElementOperand );
+                addCompulsoryDataElementOperand( dataElementOperand );
             }
 
-            sources.clear();
+            removeAllOrganisationUnits();
 
             for ( OrganisationUnit organisationUnit : dataSet.getSources() )
             {
                 addOrganisationUnit( organisationUnit );
             }
-
-            sections.clear();
-
-            for ( Section section : dataSet.getSections() )
-            {
-                sections.add( section );
-
-                if ( section.getDataSet() == null )
-                {
-                    section.setDataSet( this );
-                }
-            }
         }
     }
 }

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataset/Section.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataset/Section.java	2012-04-13 10:38:21 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataset/Section.java	2012-04-18 20:24:12 +0000
@@ -31,6 +31,7 @@
 import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
 import org.hisp.dhis.common.BaseIdentifiableObject;
 import org.hisp.dhis.common.Dxf2Namespace;
+import org.hisp.dhis.common.IdentifiableObject;
 import org.hisp.dhis.common.view.DetailedView;
 import org.hisp.dhis.common.view.ExportView;
 import org.hisp.dhis.dataelement.DataElement;
@@ -79,6 +80,36 @@
     // Logic
     // -------------------------------------------------------------------------
 
+    public void addDataElement( DataElement dataElement )
+    {
+        dataElements.add( dataElement );
+    }
+
+    public void removeDataElement( DataElement dataElement )
+    {
+        dataElements.remove( dataElement );
+    }
+
+    public void addGreyedField( DataElementOperand greyedField )
+    {
+        greyedFields.add( greyedField );
+    }
+
+    public void removeGreyedField( DataElementOperand greyedField )
+    {
+        greyedFields.remove( greyedField );
+    }
+
+    public void removeAllGreyedFields()
+    {
+        greyedFields.clear();
+    }
+
+    public void removeAllDataElements()
+    {
+        dataElements.clear();
+    }
+
     public DataElementCategoryCombo getCategoryCombo()
     {
         return dataElements != null && dataElements.size() > 0 ? dataElements.iterator().next().getCategoryCombo() : null;
@@ -189,11 +220,6 @@
         this.dataElements = dataElements;
     }
 
-    public void addDataElement( DataElement dataElement )
-    {
-        this.dataElements.add( dataElement );
-    }
-
     public int getSortOrder()
     {
         return sortOrder;
@@ -217,4 +243,31 @@
     {
         this.greyedFields = greyedFields;
     }
+
+    @Override
+    public void mergeWith( IdentifiableObject other )
+    {
+        super.mergeWith( other );
+
+        if ( other.getClass().isInstance( this ) )
+        {
+            Section section = (Section) other;
+
+            dataSet = section.getDataSet() == null ? dataSet : section.getDataSet();
+
+            removeAllDataElements();
+
+            for ( DataElement dataElement : section.getDataElements() )
+            {
+                addDataElement( dataElement );
+            }
+
+            removeAllGreyedFields();
+
+            for ( DataElementOperand dataElementOperand : section.getGreyedFields() )
+            {
+                addGreyedField( dataElementOperand );
+            }
+        }
+    }
 }

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnit.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnit.java	2012-04-17 08:04:52 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnit.java	2012-04-18 20:24:12 +0000
@@ -40,6 +40,7 @@
 import org.hisp.dhis.common.BaseNameableObject;
 import org.hisp.dhis.common.Dxf2Namespace;
 import org.hisp.dhis.common.IdentifiableObject;
+import org.hisp.dhis.common.annotation.Scanned;
 import org.hisp.dhis.common.comparator.IdentifiableObjectNameComparator;
 import org.hisp.dhis.common.view.DetailedView;
 import org.hisp.dhis.common.view.ExportView;
@@ -93,10 +94,13 @@
 
     private String url;
 
+    @Scanned
     private Set<OrganisationUnitGroup> groups = new HashSet<OrganisationUnitGroup>();
 
+    @Scanned
     private Set<DataSet> dataSets = new HashSet<DataSet>();
 
+    @Scanned
     private Set<User> users = new HashSet<User>();
 
     private String contactPerson;

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnitGroup.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnitGroup.java	2012-04-17 08:04:52 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnitGroup.java	2012-04-18 20:24:12 +0000
@@ -37,6 +37,7 @@
 import org.hisp.dhis.common.BaseNameableObject;
 import org.hisp.dhis.common.Dxf2Namespace;
 import org.hisp.dhis.common.IdentifiableObject;
+import org.hisp.dhis.common.annotation.Scanned;
 import org.hisp.dhis.common.view.DetailedView;
 import org.hisp.dhis.common.view.ExportView;
 
@@ -55,6 +56,7 @@
      */
     private static final long serialVersionUID = -1131637847640209166L;
 
+    @Scanned
     private Set<OrganisationUnit> members = new HashSet<OrganisationUnit>();
 
     private OrganisationUnitGroupSet groupSet;

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnitGroupSet.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnitGroupSet.java	2012-04-17 08:04:52 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnitGroupSet.java	2012-04-18 20:24:12 +0000
@@ -36,6 +36,7 @@
 import org.hisp.dhis.common.BaseIdentifiableObject;
 import org.hisp.dhis.common.Dxf2Namespace;
 import org.hisp.dhis.common.IdentifiableObject;
+import org.hisp.dhis.common.annotation.Scanned;
 import org.hisp.dhis.common.comparator.IdentifiableObjectNameComparator;
 import org.hisp.dhis.common.view.DetailedView;
 import org.hisp.dhis.common.view.ExportView;
@@ -56,6 +57,7 @@
 
     private static final Comparator<IdentifiableObject> COMPARATOR = new IdentifiableObjectNameComparator();
 
+    @Scanned
     private Set<OrganisationUnitGroup> organisationUnitGroups = new HashSet<OrganisationUnitGroup>();
 
     private String description;

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/period/Period.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/period/Period.java	2012-04-13 10:38:21 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/period/Period.java	2012-04-18 20:24:12 +0000
@@ -29,10 +29,15 @@
 
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.annotation.JsonView;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
 import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
 import org.hisp.dhis.common.BaseNameableObject;
 import org.hisp.dhis.common.Dxf2Namespace;
 import org.hisp.dhis.common.Weighted;
+import org.hisp.dhis.common.adapter.JacksonPeriodTypeDeserializer;
+import org.hisp.dhis.common.adapter.JacksonPeriodTypeSerializer;
 import org.hisp.dhis.common.view.DetailedView;
 import org.hisp.dhis.common.view.ExportView;
 
@@ -246,9 +251,9 @@
         int prime = 31;
         int result = 1;
 
-        result = result * prime + startDate.hashCode();
-        result = result * prime + endDate.hashCode();
-        result = result * prime + periodType.hashCode();
+        result = result * prime + (startDate != null ? startDate.hashCode() : 0);
+        result = result * prime + (endDate != null ? endDate.hashCode() : 0);
+        result = result * prime + (periodType != null ? periodType.hashCode() : 0);
 
         return result;
     }
@@ -300,7 +305,11 @@
         this.endDate = endDate;
     }
 
-    // TODO FIX THIS!
+    @JsonProperty
+    @JsonSerialize( using = JacksonPeriodTypeSerializer.class )
+    @JsonDeserialize( using = JacksonPeriodTypeDeserializer.class )
+    @JsonView( {DetailedView.class, ExportView.class} )
+    @JacksonXmlProperty( namespace = Dxf2Namespace.NAMESPACE )
     public PeriodType getPeriodType()
     {
         return periodType;

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/reporttable/ReportTable.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/reporttable/ReportTable.java	2012-04-13 10:38:21 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/reporttable/ReportTable.java	2012-04-18 20:24:12 +0000
@@ -30,12 +30,16 @@
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.annotation.JsonView;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
 import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
 import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
 import org.apache.commons.lang.StringUtils;
 import org.hisp.dhis.common.*;
+import org.hisp.dhis.common.adapter.JacksonPeriodDeserializer;
+import org.hisp.dhis.common.adapter.JacksonPeriodSerializer;
+import org.hisp.dhis.common.annotation.Scanned;
 import org.hisp.dhis.common.view.DetailedView;
 import org.hisp.dhis.common.view.ExportView;
 import org.hisp.dhis.dataelement.DataElement;
@@ -190,31 +194,37 @@
     /**
      * The list of DataElements the ReportTable contains.
      */
+    @Scanned
     private List<DataElement> dataElements = new ArrayList<DataElement>();
 
     /**
      * The list of Indicators the ReportTable contains.
      */
+    @Scanned
     private List<Indicator> indicators = new ArrayList<Indicator>();
 
     /**
      * The list of DataSets the ReportTable contains.
      */
+    @Scanned
     private List<DataSet> dataSets = new ArrayList<DataSet>();
 
     /**
      * The list of Periods the ReportTable contains.
      */
+    @Scanned
     private List<Period> periods = new ArrayList<Period>();
 
     /**
      * The list of OrganisationUnits the ReportTable contains.
      */
+    @Scanned
     private List<OrganisationUnit> units = new ArrayList<OrganisationUnit>();
 
     /**
      * The list of OrganisationUnitGroups the ReportTable contains.
      */
+    @Scanned
     private List<OrganisationUnitGroup> organisationUnitGroups = new ArrayList<OrganisationUnitGroup>();
 
     /**
@@ -957,7 +967,8 @@
     }
 
     @JsonProperty
-    @JsonSerialize( contentAs = BaseIdentifiableObject.class )
+    @JsonSerialize( contentUsing = JacksonPeriodSerializer.class )
+    @JsonDeserialize( contentUsing = JacksonPeriodDeserializer.class )
     @JsonView( {DetailedView.class, ExportView.class} )
     @JacksonXmlElementWrapper( localName = "periods", namespace = Dxf2Namespace.NAMESPACE )
     @JacksonXmlProperty( localName = "period", namespace = Dxf2Namespace.NAMESPACE )
@@ -1158,6 +1169,7 @@
         return allUnits;
     }
 
+    @JsonIgnore
     public I18nFormat getI18nFormat()
     {
         return i18nFormat;
@@ -1266,11 +1278,22 @@
             sortOrder = reportTable.getSortOrder() == null ? sortOrder : reportTable.getSortOrder();
             topLimit = reportTable.getTopLimit() == null ? topLimit : reportTable.getTopLimit();
 
+            organisationUnitGroups.clear();
             organisationUnitGroups.addAll( reportTable.getOrganisationUnitGroups() );
+
+            units.clear();
             units.addAll( reportTable.getUnits() );
+
+            periods.clear();
             periods.addAll( reportTable.getPeriods() );
+
+            dataSets.clear();
             dataSets.addAll( reportTable.getDataSets() );
+
+            indicators.clear();
             indicators.addAll( reportTable.getIndicators() );
+
+            dataElements.clear();
             dataElements.addAll( reportTable.getDataElements() );
         }
     }

=== 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-17 08:04:52 +0000
+++ dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/DefaultImportService.java	2012-04-18 20:24:12 +0000
@@ -116,10 +116,12 @@
         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;
     }
 

=== modified 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-17 08:04:52 +0000
+++ dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/importers/DefaultImporter.java	2012-04-18 20:24:12 +0000
@@ -30,12 +30,14 @@
 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;
 
@@ -59,6 +61,9 @@
     @Autowired
     protected IdentifiableObjectManager manager;
 
+    @Autowired
+    private PeriodService periodService;
+
     //-------------------------------------------------------------------------------------------------------
     // Constructor
     //-------------------------------------------------------------------------------------------------------
@@ -563,12 +568,20 @@
         return matchedObject;
     }
 
-    // FIXME slow! some kind of global idMap would be needed here, that will also update itself from several importers
+    // 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 ( identifiableObject.getUid() != null )
+        if ( Period.class.isAssignableFrom( identifiableObject.getClass() ) )
+        {
+            // FIXME this is not working..
+            Period period = (Period) identifiableObject;
+            periodService.reloadPeriod( period );
+
+            match = period;
+        }
+        else if ( identifiableObject.getUid() != null )
         {
             match = manager.get( identifiableObject.getClass(), identifiableObject.getUid() );
         }
@@ -590,7 +603,7 @@
 
         log.info( "-> Finding and updating references." );
 
-        Map<String, Set<? extends IdentifiableObject>> collectedCollections = new HashMap<String, Set<? extends IdentifiableObject>>();
+        Map<Field, Set<? extends IdentifiableObject>> collectedCollections = new HashMap<Field, Set<? extends IdentifiableObject>>();
 
         for ( Field field : fields )
         {
@@ -600,29 +613,21 @@
 
                 if ( identifiableObject != null )
                 {
-                    if ( Period.class.isAssignableFrom( identifiableObject.getClass() ) )
+                    IdentifiableObject ref = findObjectByReference( identifiableObject );
+
+                    if ( ref != null )
                     {
-                        // FIXME
-                        log.info( "Skipping Period.class" );
+                        ReflectionUtils.invokeSetterMethod( field.getName(), object, ref );
                     }
                     else
                     {
-                        IdentifiableObject ref = findObjectByReference( identifiableObject );
-
-                        if ( ref != null )
-                        {
-                            ReflectionUtils.invokeSetterMethod( field.getName(), object, ref );
-                        }
-                        else
-                        {
-                            log.info( "--> Ignored reference " + getDisplayName( identifiableObject ) + "." );
-                        }
+                        log.info( "--> Ignored reference " + getDisplayName( identifiableObject ) + "." );
                     }
                 }
             }
             else
             {
-                boolean b = ReflectionUtils.isCollection( field.getName(), object, IdentifiableObject.class );
+                boolean b = ReflectionUtils.isCollection( field.getName(), object, IdentifiableObject.class, Scanned.class );
 
                 if ( b )
                 {
@@ -631,7 +636,7 @@
                     if ( objects != null && !objects.isEmpty() )
                     {
                         Set<IdentifiableObject> identifiableObjects = new HashSet<IdentifiableObject>( objects );
-                        collectedCollections.put( field.getName(), identifiableObjects );
+                        collectedCollections.put( field, identifiableObjects );
                         objects.clear();
                     }
                 }
@@ -643,10 +648,25 @@
             manager.save( object );
         }
 
-        for ( String collectionKey : collectedCollections.keySet() )
+        for ( Field field : collectedCollections.keySet() )
         {
-            Collection<? extends IdentifiableObject> identifiableObjects = collectedCollections.get( collectionKey );
-            Collection<IdentifiableObject> objects = new HashSet<IdentifiableObject>();
+            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 )
             {
@@ -662,7 +682,7 @@
                 }
             }
 
-            ReflectionUtils.invokeSetterMethod( collectionKey, object, objects );
+            ReflectionUtils.invokeSetterMethod( field.getName(), object, objects );
         }
     }
 }

=== modified file 'dhis-2/dhis-services/dhis-service-reporting/src/main/resources/org/hisp/dhis/reporttable/hibernate/ReportTable.hbm.xml'
--- dhis-2/dhis-services/dhis-service-reporting/src/main/resources/org/hisp/dhis/reporttable/hibernate/ReportTable.hbm.xml	2012-03-30 13:32:44 +0000
+++ dhis-2/dhis-services/dhis-service-reporting/src/main/resources/org/hisp/dhis/reporttable/hibernate/ReportTable.hbm.xml	2012-04-18 20:24:12 +0000
@@ -4,7 +4,7 @@
     "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd";
     [<!ENTITY identifiableProperties SYSTEM "classpath://org/hisp/dhis/common/identifiableProperties.hbm">]
     >
-	
+
 <hibernate-mapping>
   <class name="org.hisp.dhis.reporttable.ReportTable" table="reporttable">
 
@@ -16,52 +16,59 @@
     &identifiableProperties;
 
     <property name="regression" />
-	
-	<property name="cumulative" />
+
+    <property name="cumulative" />
 
     <list name="dataElements" table="reporttable_dataelements">
       <cache usage="read-write" />
       <key column="reporttableid" foreign-key="fk_reporttable_dataelements_reporttableid" />
       <list-index column="sort_order" base="0" />
-      <many-to-many column="dataelementid" class="org.hisp.dhis.dataelement.DataElement" foreign-key="fk_reporttable_dataelements_dataelementid" />
+      <many-to-many column="dataelementid" class="org.hisp.dhis.dataelement.DataElement"
+          foreign-key="fk_reporttable_dataelements_dataelementid" />
     </list>
 
     <list name="indicators" table="reporttable_indicators">
       <cache usage="read-write" />
       <key column="reporttableid" foreign-key="fk_reporttable_indicators_reporttableid" />
       <list-index column="sort_order" base="0" />
-      <many-to-many column="indicatorid" class="org.hisp.dhis.indicator.Indicator" foreign-key="fk_reporttable_indicators_indicatorid" />
+      <many-to-many column="indicatorid" class="org.hisp.dhis.indicator.Indicator"
+          foreign-key="fk_reporttable_indicators_indicatorid" />
     </list>
 
     <list name="dataSets" table="reporttable_datasets">
       <cache usage="read-write" />
       <key column="reporttableid" foreign-key="fk_reporttable_datasets_reporttableid" />
       <list-index column="sort_order" base="0" />
-      <many-to-many column="datasetid" class="org.hisp.dhis.dataset.DataSet" foreign-key="fk_reporttable_datasets_datasetid" />
+      <many-to-many column="datasetid" class="org.hisp.dhis.dataset.DataSet"
+          foreign-key="fk_reporttable_datasets_datasetid" />
     </list>
 
-    <many-to-one name="categoryCombo" class="org.hisp.dhis.dataelement.DataElementCategoryCombo" column="categorycomboid"
-      foreign-key="fk_reporttable_categorycombo" />
+    <many-to-one name="categoryCombo" class="org.hisp.dhis.dataelement.DataElementCategoryCombo"
+        column="categorycomboid"
+        foreign-key="fk_reporttable_categorycombo" />
 
     <list name="periods" table="reporttable_periods">
       <cache usage="read-write" />
       <key column="reporttableid" foreign-key="fk_reporttable_periods_reporttableid" />
       <list-index column="sort_order" base="0" />
-      <many-to-many column="periodid" class="org.hisp.dhis.period.Period" foreign-key="fk_reporttable_periods_periodid" />
+      <many-to-many column="periodid" class="org.hisp.dhis.period.Period"
+          foreign-key="fk_reporttable_periods_periodid" />
     </list>
 
     <list name="units" table="reporttable_organisationunits">
       <cache usage="read-write" />
       <key column="reporttableid" foreign-key="fk_reporttable_organisationunits_reporttableid" />
       <list-index column="sort_order" base="0" />
-      <many-to-many column="organisationunitid" class="org.hisp.dhis.organisationunit.OrganisationUnit" foreign-key="fk_reporttable_organisationunits_organisationunitid" />
+      <many-to-many column="organisationunitid" class="org.hisp.dhis.organisationunit.OrganisationUnit"
+          foreign-key="fk_reporttable_organisationunits_organisationunitid" />
     </list>
 
     <list name="organisationUnitGroups" table="reporttable_orgunitgroups">
       <cache usage="read-write" />
       <key column="reporttableid" foreign-key="fk_reporttable_orgunitunitgroups_reporttableid" />
       <list-index column="sort_order" base="0" />
-      <many-to-many column="orgunitgroupid" class="org.hisp.dhis.organisationunit.OrganisationUnitGroup" foreign-key="fk_reporttable_orgunitgroups_orgunitgroupid" />
+      <many-to-many column="orgunitgroupid" class="org.hisp.dhis.organisationunit.OrganisationUnitGroup"
+          foreign-key="fk_reporttable_orgunitgroups_orgunitgroupid" />
     </list>
 
     <property name="doIndicators" />
@@ -84,12 +91,12 @@
       <property name="last5Years" />
       <property name="last12Months" />
       <property name="last4Quarters" />
-	  <property name="last2SixMonths" />
+      <property name="last2SixMonths" />
     </component>
 
     <component name="reportParams">
       <property name="paramReportingMonth" />
-	  <property name="paramLeafParentOrganisationUnit" />
+      <property name="paramLeafParentOrganisationUnit" />
       <property name="paramGrandParentOrganisationUnit" />
       <property name="paramParentOrganisationUnit" />
       <property name="paramOrganisationUnit" />

=== 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-04-17 14:57:04 +0000
+++ dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/ReflectionUtils.java	2012-04-18 20:24:12 +0000
@@ -27,17 +27,14 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.util.Collection;
-
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.springframework.util.StringUtils;
 
+import java.lang.annotation.Annotation;
+import java.lang.reflect.*;
+import java.util.Collection;
+
 /**
  * @author Lars Helge Overland
  */
@@ -48,7 +45,7 @@
     /**
      * Invokes method getId() for this object and returns the return value. An
      * int return type is expected. If the operation fails -1 is returned.
-     * 
+     *
      * @param object object to call getId() on.
      * @return The identifier.
      */
@@ -59,8 +56,7 @@
             Method method = object.getClass().getMethod( "getId" );
 
             return (Integer) method.invoke( object );
-        }
-        catch ( Exception ex )
+        } catch ( Exception ex )
         {
             return -1;
         }
@@ -68,8 +64,8 @@
 
     /**
      * Fetch a property off the object. Returns null if the operation fails.
-     * 
-     * @param object the object.
+     *
+     * @param object   the object.
      * @param property name of the property to get.
      * @return the value of the property or null.
      */
@@ -82,8 +78,7 @@
             Method method = object.getClass().getMethod( "get" + property );
 
             return (String) method.invoke( object );
-        }
-        catch ( Exception ex )
+        } catch ( Exception ex )
         {
             return null;
         }
@@ -92,16 +87,16 @@
     /**
      * Sets a property for the supplied object. Throws an
      * UnsupportedOperationException if the operation fails.
-     * 
+     *
      * @param object Object to modify
-     * @param name Name of property to set
-     * @param value Value the property will be set to
+     * @param name   Name of property to set
+     * @param value  Value the property will be set to
      */
     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 )
         {
@@ -112,8 +107,7 @@
                 Method concatMethod = object.getClass().getMethod( name, parameterTypes );
 
                 concatMethod.invoke( object, arguments );
-            }
-            catch ( Exception ex )
+            } catch ( Exception ex )
             {
                 throw new UnsupportedOperationException( "Failed to set property", ex );
             }
@@ -123,11 +117,11 @@
     /**
      * Sets a property for the supplied object. Throws an
      * UnsupportedOperationException if the operation fails.
-     * 
-     * @param object Object to modify
+     *
+     * @param object     Object to modify
      * @param namePrefix prefix of the property name to set
-     * @param name Name of property to set
-     * @param value Value the property will be set to
+     * @param name       Name of property to set
+     * @param value      Value the property will be set to
      */
     public static void setProperty( Object object, String namePrefix, String name, String value )
     {
@@ -139,7 +133,7 @@
     /**
      * Returns the name of the class that the object is an instance of
      * org.hisp.dhis.indicator.Indicactor returns Indicator.
-     * 
+     *
      * @param object object to determine className for.
      * @return String containing the class name.
      */
@@ -150,7 +144,7 @@
 
     /**
      * Test whether the object is an array or a Collection.
-     * 
+     *
      * @param value the object.
      * @return true if the object is an array or a Collection, false otherwise.
      */
@@ -169,17 +163,29 @@
 
     public static boolean isCollection( String fieldName, Object object, Class<?> type )
     {
+        return isCollection( fieldName, object, type, null );
+    }
+
+    public static boolean isCollection( String fieldName, Object object, Class<?> type, Class<? extends Annotation> annotation )
+    {
         Field field;
 
         try
         {
             field = object.getClass().getDeclaredField( fieldName );
-        }
-        catch ( NoSuchFieldException e )
+        } catch ( NoSuchFieldException e )
         {
             return false;
         }
 
+        if ( annotation != null )
+        {
+            if ( !field.isAnnotationPresent( annotation ) )
+            {
+                return false;
+            }
+        }
+
         try
         {
             if ( Collection.class.isAssignableFrom( field.getType() ) )
@@ -196,8 +202,7 @@
                 }
             }
 
-        }
-        catch ( ClassCastException e )
+        } catch ( ClassCastException e )
         {
             return false;
         }
@@ -210,8 +215,7 @@
         try
         {
             return object.getClass().getMethod( "get" + StringUtils.capitalize( fieldName ), classes );
-        }
-        catch ( NoSuchMethodException e )
+        } catch ( NoSuchMethodException e )
         {
             log.info( "Getter method was not found for fieldName: " + fieldName );
             return null;
@@ -225,21 +229,19 @@
         try
         {
             method = object.getClass().getMethod( "set" + StringUtils.capitalize( fieldName ), classes );
-        }
-        catch ( NoSuchMethodException e )
+        } catch ( NoSuchMethodException e )
         {
         }
 
         // If parameter classes was not given, we will retry using the field type
-        
+
         if ( method == null && classes.length == 0 )
         {
             try
             {
                 Field field = object.getClass().getDeclaredField( fieldName );
                 method = findSetterMethod( fieldName, object, field.getType() );
-            }
-            catch ( NoSuchFieldException ignored )
+            } catch ( NoSuchFieldException ignored )
             {
             }
         }
@@ -265,13 +267,11 @@
         try
         {
             return (T) method.invoke( object );
-        }
-        catch ( InvocationTargetException e )
+        } catch ( InvocationTargetException e )
         {
             log.info( "InvocationTargetException for fieldName: " + fieldName );
             return null;
-        }
-        catch ( IllegalAccessException e )
+        } catch ( IllegalAccessException e )
         {
             log.info( "IllegalAccessException for fieldName: " + fieldName );
             return null;
@@ -291,13 +291,11 @@
         try
         {
             return (T) method.invoke( object, objects );
-        }
-        catch ( InvocationTargetException e )
+        } catch ( InvocationTargetException e )
         {
             log.info( "InvocationTargetException for fieldName: " + fieldName );
             return null;
-        }
-        catch ( IllegalAccessException e )
+        } catch ( IllegalAccessException e )
         {
             log.info( "IllegalAccessException for fieldName: " + fieldName );
             return null;