← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 4277: Initial version of Version object. Also contains important fixes for ouwt (sorry for including in...

 

------------------------------------------------------------
revno: 4277
committer: Morten Olav Hansen <mortenoh@xxxxxxxxx>
branch nick: dhis2
timestamp: Thu 2011-08-11 13:31:42 +0200
message:
  Initial version of Version object. Also contains important fixes for ouwt (sorry for including in same commit, but they were really necessary)
added:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/version/
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/version/Version.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/version/VersionService.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/version/VersionStore.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/version/
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/version/DefaultVersionService.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/version/hibernate/
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/version/hibernate/HibernateVersionStore.java
  dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/version/
  dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/version/hibernate/
  dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/version/hibernate/Version.hbm.xml
modified:
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/organisationunit/DefaultOrganisationUnitService.java
  dhis-2/dhis-services/dhis-service-core/src/main/resources/META-INF/dhis/beans.xml
  dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/constant/hibernate/Constant.hbm.xml
  dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/ouwt/ouwt.js
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-organisationunit/src/main/webapp/dhis-web-maintenance-organisationunit/javascript/organisationUnit.js
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/webapp/dhis-web-maintenance-user/javascript/user_tmpl.js


--
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
=== added directory 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/version'
=== added file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/version/Version.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/version/Version.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/version/Version.java	2011-08-11 11:31:42 +0000
@@ -0,0 +1,109 @@
+package org.hisp.dhis.version;
+
+/*
+ * Copyright (c) 2004-2010, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this
+ *   list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of the HISP project nor the names of its contributors may
+ *   be used to endorse or promote products derived from this software without
+ *   specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @author mortenoh
+ */
+public class Version
+{
+    private int id;
+
+    private String key;
+
+    private String value;
+
+    @Override
+    public int hashCode()
+    {
+        return key.hashCode();
+    }
+
+    @Override
+    public String toString()
+    {
+        return "[" + key + "]";
+    }
+
+    @Override
+    public boolean equals( Object o )
+    {
+        if ( this == o )
+        {
+            return true;
+        }
+
+        if ( o == null )
+        {
+            return false;
+        }
+
+        if ( !(o instanceof Version) )
+        {
+            return false;
+        }
+
+        final Version other = (Version) o;
+
+        return key.equals( other.getKey() );
+    }
+
+    // -------------------------------------------------------------------------
+    // Getter & Setter
+    // -------------------------------------------------------------------------
+
+    public int getId()
+    {
+        return id;
+    }
+
+    public void setId( int id )
+    {
+        this.id = id;
+    }
+
+    public String getKey()
+    {
+        return key;
+    }
+
+    public void setKey( String key )
+    {
+        this.key = key;
+    }
+
+    public String getValue()
+    {
+        return value;
+    }
+
+    public void setValue( String value )
+    {
+        this.value = value;
+    }
+}

=== added file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/version/VersionService.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/version/VersionService.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/version/VersionService.java	2011-08-11 11:31:42 +0000
@@ -0,0 +1,79 @@
+package org.hisp.dhis.version;
+
+/*
+ * Copyright (c) 2004-2010, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this
+ *   list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of the HISP project nor the names of its contributors may
+ *   be used to endorse or promote products derived from this software without
+ *   specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.util.Collection;
+
+/**
+ * @author mortenoh
+ */
+public interface VersionService
+{
+    public final String ORGANISATIONUNIT_VERSION = "organisationUnit";
+
+    String ID = VersionService.class.getName();
+
+    /**
+     * @param version Version object to add.
+     * @return ID of the saved version object.
+     */
+    int addVersion( Version version );
+
+    /**
+     * @param version Version object to update.
+     */
+    void updateVersion( Version version );
+
+    /**
+     * @param key
+     * @param value
+     */
+    void updateVersion( String key, String value );
+
+    /**
+     * @param version Version object to delete.
+     */
+    void deleteVersion( Version version );
+
+    /**
+     * @param id Get Version with this ID.
+     * @return Version that matched ID, or null if there was no match.
+     */
+    Version getVersion( int id );
+
+    /**
+     * @param key Key to lookup the value with.
+     * @return Version that matched key, or null if there was no match.
+     */
+    Version getVersionByKey( String key );
+
+    /**
+     * @return Collection of all version objects.
+     */
+    Collection<Version> getAllVersions();
+}

=== added file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/version/VersionStore.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/version/VersionStore.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/version/VersionStore.java	2011-08-11 11:31:42 +0000
@@ -0,0 +1,45 @@
+package org.hisp.dhis.version;
+
+/*
+ * Copyright (c) 2004-2010, 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.common.GenericStore;
+
+/**
+ * @author mortenoh
+ */
+public interface VersionStore
+    extends GenericStore<Version>
+{
+    String ID = VersionStore.class.getName();
+
+    /**
+     * @param key Key to lookup.
+     * @return Value that matched key, or null if there was no match.
+     */
+    Version getVersionByKey( String key );
+}

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/organisationunit/DefaultOrganisationUnitService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/organisationunit/DefaultOrganisationUnitService.java	2011-07-26 07:39:20 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/organisationunit/DefaultOrganisationUnitService.java	2011-08-11 11:31:42 +0000
@@ -36,6 +36,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.UUID;
 
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.logging.Log;
@@ -50,6 +51,8 @@
 import org.hisp.dhis.system.util.UUIdUtils;
 import org.hisp.dhis.user.CurrentUserService;
 import org.hisp.dhis.user.User;
+import org.hisp.dhis.version.Version;
+import org.hisp.dhis.version.VersionService;
 import org.springframework.transaction.annotation.Transactional;
 
 /**
@@ -83,6 +86,13 @@
         this.currentUserService = currentUserService;
     }
 
+    private VersionService versionService;
+
+    public void setVersionService( VersionService versionService )
+    {
+        this.versionService = versionService;
+    }
+
     // -------------------------------------------------------------------------
     // OrganisationUnit
     // -------------------------------------------------------------------------
@@ -98,8 +108,8 @@
 
         int id = organisationUnitStore.save( organisationUnit );
 
-        log.info( AuditLogUtil.logMessage( currentUserService.getCurrentUsername(),
-            AuditLogUtil.ACTION_ADD, OrganisationUnit.class.getSimpleName(), organisationUnit.getName() ) );
+        log.info( AuditLogUtil.logMessage( currentUserService.getCurrentUsername(), AuditLogUtil.ACTION_ADD,
+            OrganisationUnit.class.getSimpleName(), organisationUnit.getName() ) );
 
         return id;
     }
@@ -110,8 +120,8 @@
 
         organisationUnitStore.update( organisationUnit );
 
-        log.info( AuditLogUtil.logMessage( currentUserService.getCurrentUsername(),
-            AuditLogUtil.ACTION_EDIT, OrganisationUnit.class.getSimpleName(), organisationUnit.getName() ) );
+        log.info( AuditLogUtil.logMessage( currentUserService.getCurrentUsername(), AuditLogUtil.ACTION_EDIT,
+            OrganisationUnit.class.getSimpleName(), organisationUnit.getName() ) );
     }
 
     public void updateOrganisationUnit( OrganisationUnit organisationUnit, boolean updateHierarchy )
@@ -138,8 +148,8 @@
 
         organisationUnitStore.delete( organisationUnit );
 
-        log.info( AuditLogUtil.logMessage( currentUserService.getCurrentUsername(),
-            AuditLogUtil.ACTION_DELETE, OrganisationUnit.class.getSimpleName(), organisationUnit.getName() ) );
+        log.info( AuditLogUtil.logMessage( currentUserService.getCurrentUsername(), AuditLogUtil.ACTION_DELETE,
+            OrganisationUnit.class.getSimpleName(), organisationUnit.getName() ) );
     }
 
     public OrganisationUnit getOrganisationUnit( int id )
@@ -174,7 +184,7 @@
     {
         return organisationUnitStore.getByName( name );
     }
-    
+
     public OrganisationUnit getOrganisationUnitByNameIgnoreCase( String name )
     {
         return organisationUnitStore.getOrganisationUnitByNameIgnoreCase( name );
@@ -219,7 +229,7 @@
         }
 
         List<OrganisationUnit> childList = parent.getSortedChildren();
-        
+
         for ( OrganisationUnit child : childList )
         {
             child.setLevel( level );
@@ -397,84 +407,93 @@
         return organisationUnitStore.getOrganisationUnitsWithoutGroups();
     }
 
-    public Collection<OrganisationUnit> getOrganisationUnitsByNameAndGroups( String name, Collection<OrganisationUnitGroup> groups, boolean limit )
+    public Collection<OrganisationUnit> getOrganisationUnitsByNameAndGroups( String name,
+        Collection<OrganisationUnitGroup> groups, boolean limit )
     {
         return organisationUnitStore.getOrganisationUnitsByNameAndGroups( name, groups, limit );
     }
 
-    @SuppressWarnings("unchecked")    
-    public Collection<OrganisationUnit> getOrganisationUnitsByNameAndGroups( String name, Collection<OrganisationUnitGroup> groups, OrganisationUnit parent, boolean limit )
+    @SuppressWarnings( "unchecked" )
+    public Collection<OrganisationUnit> getOrganisationUnitsByNameAndGroups( String name,
+        Collection<OrganisationUnitGroup> groups, OrganisationUnit parent, boolean limit )
     {
-        boolean _limit = limit && parent == null; // Can only limit in query if parent is not set and we get all units
-        
-        final Collection<OrganisationUnit> result = organisationUnitStore.getOrganisationUnitsByNameAndGroups( name, groups, _limit );
-        
+        boolean _limit = limit && parent == null; // Can only limit in query if
+                                                  // parent is not set and we
+                                                  // get all units
+
+        final Collection<OrganisationUnit> result = organisationUnitStore.getOrganisationUnitsByNameAndGroups( name,
+            groups, _limit );
+
         if ( parent == null )
         {
             return result;
         }
-        
+
         final Collection<OrganisationUnit> subTree = getOrganisationUnitWithChildren( parent.getId() );
-        
-        List<OrganisationUnit> intersection = new ArrayList<OrganisationUnit>( CollectionUtils.intersection( subTree, result ) );
-
-        return limit && intersection != null && intersection.size() > MAX_LIMIT ? intersection.subList( 0, MAX_LIMIT ) : intersection;   
+
+        List<OrganisationUnit> intersection = new ArrayList<OrganisationUnit>( CollectionUtils.intersection( subTree,
+            result ) );
+
+        return limit && intersection != null && intersection.size() > MAX_LIMIT ? intersection.subList( 0, MAX_LIMIT )
+            : intersection;
     }
-    
+
     public OrganisationUnitDataSetAssociationSet getOrganisationUnitDataSetAssociationSet()
     {
         Map<Integer, Set<Integer>> associationSet = organisationUnitStore.getOrganisationUnitDataSetAssocationMap();
-        
+
         filterUserDataSets( associationSet );
         filterChildOrganisationUnits( associationSet );
-        
+
         OrganisationUnitDataSetAssociationSet set = new OrganisationUnitDataSetAssociationSet();
-        
+
         for ( Map.Entry<Integer, Set<Integer>> entry : associationSet.entrySet() )
         {
             int index = set.getDataSetAssociationSets().indexOf( entry.getValue() );
-            
+
             if ( index == -1 ) // Association set does not exist, add new
             {
                 index = set.getDataSetAssociationSets().size();
                 set.getDataSetAssociationSets().add( entry.getValue() );
             }
-            
+
             set.getOrganisationUnitAssociationSetMap().put( entry.getKey(), index );
         }
-        
+
         return set;
     }
-    
+
     private void filterUserDataSets( Map<Integer, Set<Integer>> associationMap )
     {
         User currentUser = currentUserService.getCurrentUser();
-        
+
         if ( currentUser != null && !currentUser.getUserCredentials().isSuper() )
         {
-            Collection<Integer> userDataSets = ConversionUtils.getIdentifiers( DataSet.class, currentUser.getUserCredentials().getAllDataSets() );
-            
+            Collection<Integer> userDataSets = ConversionUtils.getIdentifiers( DataSet.class, currentUser
+                .getUserCredentials().getAllDataSets() );
+
             for ( Set<Integer> dataSets : associationMap.values() )
             {
                 dataSets.retainAll( userDataSets );
             }
         }
     }
-    
+
     private void filterChildOrganisationUnits( Map<Integer, Set<Integer>> associatonMap )
     {
         User currentUser = currentUserService.getCurrentUser();
-        
+
         if ( currentUser != null )
         {
-            Collection<Integer> parentIds = ConversionUtils.getIdentifiers( OrganisationUnit.class, currentUser.getOrganisationUnits() );
-            
+            Collection<Integer> parentIds = ConversionUtils.getIdentifiers( OrganisationUnit.class,
+                currentUser.getOrganisationUnits() );
+
             Collection<Integer> children = getOrganisationUnitHierarchy().getChildren( parentIds );
-        
+
             associatonMap.keySet().retainAll( children );
         }
     }
-    
+
     // -------------------------------------------------------------------------
     // OrganisationUnitHierarchy
     // -------------------------------------------------------------------------
@@ -560,8 +579,8 @@
 
     public List<OrganisationUnitLevel> getOrganisationUnitLevels()
     {
-        List<OrganisationUnitLevel> levels = new ArrayList<OrganisationUnitLevel>( organisationUnitStore
-            .getOrganisationUnitLevels() );
+        List<OrganisationUnitLevel> levels = new ArrayList<OrganisationUnitLevel>(
+            organisationUnitStore.getOrganisationUnitLevels() );
 
         Collections.sort( levels, new OrganisationUnitLevelComparator() );
 
@@ -600,7 +619,7 @@
         Map<Integer, OrganisationUnitLevel> levelMap = new HashMap<Integer, OrganisationUnitLevel>();
 
         Collection<OrganisationUnitLevel> levels = getOrganisationUnitLevels();
-        
+
         for ( OrganisationUnitLevel level : levels )
         {
             levelMap.put( level.getLevel(), level );
@@ -620,16 +639,32 @@
     {
         return organisationUnitStore.getMaxOfOrganisationUnitLevels();
     }
-    
+
     @Override
     public void updateOrganisationUnits( Collection<OrganisationUnit> units )
     {
         organisationUnitStore.update( units );
     }
-    
+
     @Override
     public Collection<OrganisationUnit> getOrganisationUnits( Boolean hasPatients )
     {
-        return organisationUnitStore.get(hasPatients);
+        return organisationUnitStore.get( hasPatients );
+    }
+
+    private void updateVersion()
+    {
+        String uuid = UUID.randomUUID().toString();
+        Version orgUnitVersion = versionService.getVersionByKey( VersionService.ORGANISATIONUNIT_VERSION );
+
+        if ( orgUnitVersion == null )
+        {
+            orgUnitVersion = new Version();
+            orgUnitVersion.setKey( VersionService.ORGANISATIONUNIT_VERSION );
+        }
+
+        orgUnitVersion.setValue( uuid );
+
+        versionService.updateVersion( orgUnitVersion );
     }
 }

=== added directory 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/version'
=== added file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/version/DefaultVersionService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/version/DefaultVersionService.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/version/DefaultVersionService.java	2011-08-11 11:31:42 +0000
@@ -0,0 +1,94 @@
+package org.hisp.dhis.version;
+
+/*
+ * Copyright (c) 2004-2010, University of Oslo All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met: *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer. * Redistributions in binary
+ * form must reproduce the above copyright notice, this list of conditions and
+ * the following disclaimer in the documentation and/or other materials provided
+ * with the distribution. * Neither the name of the HISP project nor the names
+ * of its contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. THIS SOFTWARE IS
+ * PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.util.Collection;
+
+public class DefaultVersionService
+    implements VersionService
+{
+    // -------------------------------------------------------------------------
+    // Dependencies
+    // -------------------------------------------------------------------------
+
+    private VersionStore versionStore;
+
+    public void setVersionStore( VersionStore versionStore )
+    {
+        this.versionStore = versionStore;
+    }
+
+    // -------------------------------------------------------------------------
+    // VersionService implementation
+    // -------------------------------------------------------------------------
+
+    @Override
+    public int addVersion( Version version )
+    {
+        return versionStore.save( version );
+    }
+
+    @Override
+    public void updateVersion( Version version )
+    {
+        versionStore.update( version );
+    }
+
+    @Override
+    public void updateVersion( String key, String value )
+    {
+        Version version = getVersionByKey( key );
+
+        if ( version != null )
+        {
+            version.setValue( value );
+            versionStore.update( version );
+        }
+    }
+
+    @Override
+    public void deleteVersion( Version version )
+    {
+        versionStore.delete( version );
+    }
+
+    @Override
+    public Version getVersion( int id )
+    {
+        return versionStore.get( id );
+    }
+
+    @Override
+    public Version getVersionByKey( String key )
+    {
+        return versionStore.getVersionByKey( key );
+    }
+
+    @Override
+    public Collection<Version> getAllVersions()
+    {
+        return versionStore.getAll();
+    }
+
+}

=== added directory 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/version/hibernate'
=== added file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/version/hibernate/HibernateVersionStore.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/version/hibernate/HibernateVersionStore.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/version/hibernate/HibernateVersionStore.java	2011-08-11 11:31:42 +0000
@@ -0,0 +1,47 @@
+package org.hisp.dhis.version.hibernate;
+
+/*
+ * Copyright (c) 2004-2010, 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.hibernate.Criteria;
+import org.hibernate.Session;
+import org.hibernate.criterion.Restrictions;
+import org.hisp.dhis.hibernate.HibernateGenericStore;
+import org.hisp.dhis.version.Version;
+import org.hisp.dhis.version.VersionStore;
+
+public class HibernateVersionStore
+    extends HibernateGenericStore<Version>
+    implements VersionStore
+{
+    @Override
+    public Version getVersionByKey( String key )
+    {
+        Session session = sessionFactory.getCurrentSession();
+        Criteria criteria = session.createCriteria( Version.class );
+        criteria.add( Restrictions.eq( "key", key ) );
+        criteria.setCacheable( true );
+        return (Version) criteria.uniqueResult();
+    }
+
+}

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/resources/META-INF/dhis/beans.xml'
--- dhis-2/dhis-services/dhis-service-core/src/main/resources/META-INF/dhis/beans.xml	2011-08-11 02:59:26 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/resources/META-INF/dhis/beans.xml	2011-08-11 11:31:42 +0000
@@ -6,7 +6,7 @@
 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
 http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd";>
 
-	<!-- Store definitions -->
+  <!-- Store definitions -->
 
   <bean id="org.hisp.dhis.dataelement.DataElementOperandStore" class="org.hisp.dhis.hibernate.HibernateGenericStore">
     <property name="clazz" value="org.hisp.dhis.dataelement.DataElementOperand" />
@@ -204,7 +204,7 @@
   <bean id="org.hisp.dhis.message.MessageConversationStore" class="org.hisp.dhis.message.hibernate.HibernateMessageConversationStore">
     <property name="clazz" value="org.hisp.dhis.message.MessageConversation" />
     <property name="sessionFactory" ref="sessionFactory" />
-	<property name="jdbcTemplate" ref="jdbcTemplate" />
+    <property name="jdbcTemplate" ref="jdbcTemplate" />
     <property name="cacheable" value="true" />
   </bean>
 
@@ -222,13 +222,18 @@
     <property name="sessionFactory" ref="sessionFactory" />
     <property name="clazz" value="org.hisp.dhis.configuration.Configuration" />
   </bean>
-  
+
   <bean id="org.hisp.dhis.constant.ConstantStore" class="org.hisp.dhis.hibernate.HibernateGenericStore">
     <property name="sessionFactory" ref="sessionFactory" />
-	<property name="clazz" value="org.hisp.dhis.constant.Constant" />
-  </bean>
-  
-	<!-- Service definitions -->
+    <property name="clazz" value="org.hisp.dhis.constant.Constant" />
+  </bean>
+
+  <bean id="org.hisp.dhis.version.VersionStore" class="org.hisp.dhis.version.hibernate.HibernateVersionStore">
+    <property name="sessionFactory" ref="sessionFactory" />
+    <property name="clazz" value="org.hisp.dhis.version.Version" />
+  </bean>
+
+  <!-- Service definitions -->
 
   <bean id="org.hisp.dhis.dataelement.DataElementOperandService" class="org.hisp.dhis.dataelement.DefaultDataElementOperandService">
     <property name="dataElementOperandStore" ref="org.hisp.dhis.dataelement.DataElementOperandStore" />
@@ -296,7 +301,7 @@
   <bean id="org.hisp.dhis.expression.ExpressionService" class="org.hisp.dhis.expression.DefaultExpressionService">
     <property name="expressionStore" ref="org.hisp.dhis.expression.ExpressionStore" />
     <property name="dataElementService" ref="org.hisp.dhis.dataelement.DataElementService" />
-	<property name="constantService" ref="org.hisp.dhis.constant.ConstantService" />
+    <property name="constantService" ref="org.hisp.dhis.constant.ConstantService" />
     <property name="dataValueService" ref="org.hisp.dhis.datavalue.DataValueService" />
     <property name="aggregatedDataValueService" ref="org.hisp.dhis.aggregation.AggregatedDataValueService" />
     <property name="categoryService" ref="org.hisp.dhis.dataelement.DataElementCategoryService" />
@@ -322,6 +327,7 @@
   <bean id="org.hisp.dhis.organisationunit.OrganisationUnitService" class="org.hisp.dhis.organisationunit.DefaultOrganisationUnitService">
     <property name="organisationUnitStore" ref="org.hisp.dhis.organisationunit.OrganisationUnitStore" />
     <property name="currentUserService" ref="org.hisp.dhis.user.CurrentUserService" />
+    <property name="versionService" ref="org.hisp.dhis.version.VersionService" />
   </bean>
 
   <bean id="org.hisp.dhis.organisationunit.OrganisationUnitGroupService" class="org.hisp.dhis.organisationunit.DefaultOrganisationUnitGroupService">
@@ -436,7 +442,11 @@
     <property name="constantStore" ref="org.hisp.dhis.constant.ConstantStore" />
   </bean>
 
-	<!-- I18nService -->
+  <bean id="org.hisp.dhis.version.VersionService" class="org.hisp.dhis.version.DefaultVersionService">
+    <property name="versionStore" ref="org.hisp.dhis.version.VersionStore" />
+  </bean>
+
+  <!-- I18nService -->
 
   <bean id="org.hisp.dhis.i18n.I18nService" class="org.hisp.dhis.i18n.DefaultI18nService">
     <property name="localeManager">
@@ -462,7 +472,7 @@
     </property>
   </bean>
 
-	<!-- I18n object definitions -->
+  <!-- I18n object definitions -->
 
   <bean id="I18nDataElement" class="org.hisp.dhis.i18n.I18nObject">
     <property name="className" value="DataElement" />
@@ -940,7 +950,7 @@
     </property>
   </bean>
 
-	<!-- Startup routine definitions -->
+  <!-- Startup routine definitions -->
 
   <bean id="org.hisp.dhis.startup.TableAlteror" class="org.hisp.dhis.startup.TableAlteror">
     <property name="statementManager" ref="statementManager" />
@@ -988,9 +998,9 @@
     <property name="runlevel" value="5" />
     <property name="skipInTests" value="true" />
   </bean>
-  
+
   <bean id="org.hisp.dhis.dataentryform.DataEntryFormUpgrader" class="org.hisp.dhis.dataentryform.DataEntryFormUpgrader">
-	<property name="dataEntryFormService" ref="org.hisp.dhis.dataentryform.DataEntryFormService"/>
+    <property name="dataEntryFormService" ref="org.hisp.dhis.dataentryform.DataEntryFormService" />
     <property name="runlevel" value="5" />
     <property name="skipInTests" value="true" />
   </bean>
@@ -1008,13 +1018,13 @@
           <ref local="org.hisp.dhis.dataset.DataSetShortNamePopulator" />
           <ref local="org.hisp.dhis.organisationunit.OrganisationUnitGroupSetPopulator" />
           <ref local="org.hisp.dhis.dataentryform.DataEntryFormPopulator" />
-		  <ref local="org.hisp.dhis.dataentryform.DataEntryFormUpgrader" />
+          <ref local="org.hisp.dhis.dataentryform.DataEntryFormUpgrader" />
         </list>
       </list>
     </property>
   </bean>
 
-	<!-- DeletionHandlers -->
+  <!-- DeletionHandlers -->
 
   <bean id="org.hisp.dhis.datadictionary.DataDictionaryDeletionHandler" class="org.hisp.dhis.datadictionary.DataDictionaryDeletionHandler">
     <property name="dataDictionaryService" ref="org.hisp.dhis.datadictionary.DataDictionaryService" />
@@ -1128,8 +1138,8 @@
   <bean id="org.hisp.dhis.dataelement.DataElementGroupSetDeletionHandler" class="org.hisp.dhis.dataelement.DataElementGroupSetDeletionHandler">
     <property name="dataElementService" ref="org.hisp.dhis.dataelement.DataElementService" />
   </bean>
-	
-	<!-- DeletionManager -->
+
+  <!-- DeletionManager -->
 
   <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
     <property name="targetObject" ref="deletionManager" />
@@ -1169,13 +1179,13 @@
     </property>
   </bean>
 
-	<!-- Min/Max validation -->
+  <!-- Min/Max validation -->
 
   <bean id="org.hisp.dhis.minmax.validation.MinMaxValuesGenerationService" class="org.hisp.dhis.minmax.validation.DefaultMinMaxValuesGenerationService">
     <property name="dataAnalysisStore" ref="org.hisp.dhis.dataanalysis.jdbc.DataAnalysisStore" />
   </bean>
 
-	<!-- AOP definitions -->
+  <!-- AOP definitions -->
 
   <aop:config>
 
@@ -1208,31 +1218,31 @@
         method="intercept" />
     </aop:aspect>
 
-		<!--
-			<aop:aspect ref="i18nTranslationInterceptor"> <aop:after-returning
-			pointcut="execution( *
-			org.hisp.dhis.dataelement.DataElementService.get*(..) )"
-			method="intercept" returning="object"/> <aop:after-returning
-			pointcut="execution( *
-			org.hisp.dhis.dataelement.DataElementCategoryService.get*(..) )"
-			method="intercept" returning="object"/> <aop:after-returning
-			pointcut="execution( *
-			org.hisp.dhis.indicator.IndicatorService.get*(..) )"
-			method="intercept" returning="object"/> <aop:after-returning
-			pointcut="execution( *
-			org.hisp.dhis.datadictionary.DataDictionaryService.get*(..) )"
-			method="intercept" returning="object"/> <aop:after-returning
-			pointcut="execution( * org.hisp.dhis.dataset.DataSetService.get*(..)
-			)" method="intercept" returning="object"/> <aop:after-returning
-			pointcut="execution( *
-			org.hisp.dhis.organisationunit.OrganisationUnitService.get*(..) )"
-			method="intercept" returning="object"/> <aop:after-returning
-			pointcut="execution( *
-			org.hisp.dhis.organisationunit.OrganisationUnitGroupService.get*(..)
-			)" method="intercept" returning="object"/> </aop:aspect>
-		-->
+    <!--
+      <aop:aspect ref="i18nTranslationInterceptor"> <aop:after-returning
+      pointcut="execution( *
+      org.hisp.dhis.dataelement.DataElementService.get*(..) )"
+      method="intercept" returning="object"/> <aop:after-returning
+      pointcut="execution( *
+      org.hisp.dhis.dataelement.DataElementCategoryService.get*(..) )"
+      method="intercept" returning="object"/> <aop:after-returning
+      pointcut="execution( *
+      org.hisp.dhis.indicator.IndicatorService.get*(..) )"
+      method="intercept" returning="object"/> <aop:after-returning
+      pointcut="execution( *
+      org.hisp.dhis.datadictionary.DataDictionaryService.get*(..) )"
+      method="intercept" returning="object"/> <aop:after-returning
+      pointcut="execution( * org.hisp.dhis.dataset.DataSetService.get*(..)
+      )" method="intercept" returning="object"/> <aop:after-returning
+      pointcut="execution( *
+      org.hisp.dhis.organisationunit.OrganisationUnitService.get*(..) )"
+      method="intercept" returning="object"/> <aop:after-returning
+      pointcut="execution( *
+      org.hisp.dhis.organisationunit.OrganisationUnitGroupService.get*(..)
+      )" method="intercept" returning="object"/> </aop:aspect>
+    -->
   </aop:config>
 
-	<!-- Security import -->
+  <!-- Security import -->
   <import resource="security.xml" />
 </beans>

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/constant/hibernate/Constant.hbm.xml'
--- dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/constant/hibernate/Constant.hbm.xml	2011-06-29 08:51:25 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/constant/hibernate/Constant.hbm.xml	2011-08-11 11:31:42 +0000
@@ -7,7 +7,7 @@
   <class name="org.hisp.dhis.constant.Constant" table="constant">
 
     <cache usage="read-write" />
-  
+
     <id name="id" column="constantid">
       <generator class="native" />
     </id>
@@ -15,8 +15,8 @@
     <property name="name">
       <column name="name" not-null="true" unique="true" length="230" />
     </property>
-	
-	<property name="value" />
+
+    <property name="value" />
 
   </class>
 </hibernate-mapping>

=== added directory 'dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/version'
=== added directory 'dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/version/hibernate'
=== added file 'dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/version/hibernate/Version.hbm.xml'
--- dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/version/hibernate/Version.hbm.xml	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/version/hibernate/Version.hbm.xml	2011-08-11 11:31:42 +0000
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+  "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+  "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd";>
+
+<hibernate-mapping>
+  <class name="org.hisp.dhis.version.Version" table="Version">
+
+    <cache usage="read-write" />
+
+    <id name="id" column="versionid">
+      <generator class="native" />
+    </id>
+
+    <property name="key">
+      <column name="key" not-null="true" unique="true" length="230" />
+    </property>
+
+    <property name="value" />
+
+  </class>
+</hibernate-mapping>

=== modified file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/ouwt/ouwt.js'
--- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/ouwt/ouwt.js	2011-08-11 07:20:39 +0000
+++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/ouwt/ouwt.js	2011-08-11 11:31:42 +0000
@@ -22,15 +22,6 @@
 $( document ).ready( function()
 {
     selection.load();
-
-    jQuery( "body" ).bind( "ajaxComplete", function( e, xhr, settings )
-    {
-        if ( settings.url.indexOf( "getOrganisationUnitTree" ) )
-        {
-            selection.responseReceived();
-            jQuery( "body" ).unbind( "ajaxSuccess" );
-        }
-    } );
 } );
 
 // -----------------------------------------------------------------------------
@@ -41,9 +32,21 @@
 {
     var listenerFunction, multipleSelectionAllowed = false, unselectAllowed = false;
 
-    this.setListenerFunction = function( listenerFunction_ )
+    this.setListenerFunction = function( listenerFunction_, skipInitialCall )
     {
         listenerFunction = listenerFunction_;
+
+        if ( !skipInitialCall )
+        {
+            jQuery( "body" ).bind( "ajaxComplete", function( e, xhr, settings )
+            {
+                if ( settings.url.indexOf( "getOrganisationUnitTree" ) )
+                {
+                    selection.responseReceived();
+                    jQuery( "body" ).unbind( "ajaxSuccess" );
+                }
+            } );
+        }
     };
 
     this.setMultipleSelectionAllowed = function( allowed )
@@ -88,7 +91,6 @@
 
             selection.sync();
             subtree.reloadTree();
-            selection.responseReceived();
 
             $( "#ouwt_loader" ).hide();
         } );

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-organisationunit/src/main/webapp/dhis-web-maintenance-organisationunit/javascript/organisationUnit.js'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-organisationunit/src/main/webapp/dhis-web-maintenance-organisationunit/javascript/organisationUnit.js	2011-08-08 15:09:46 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-organisationunit/src/main/webapp/dhis-web-maintenance-organisationunit/javascript/organisationUnit.js	2011-08-11 11:31:42 +0000
@@ -4,7 +4,7 @@
 
 $( document ).ready( function()
 {
-    selection.setListenerFunction( organisationUnitSelected );
+    selection.setListenerFunction( organisationUnitSelected, true );
 } )
 
 function organisationUnitSelected( orgUnitIds )

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/webapp/dhis-web-maintenance-user/javascript/user_tmpl.js'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/webapp/dhis-web-maintenance-user/javascript/user_tmpl.js	2011-03-14 21:10:15 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/webapp/dhis-web-maintenance-user/javascript/user_tmpl.js	2011-08-11 11:31:42 +0000
@@ -2,11 +2,11 @@
 
 jQuery( document ).ready( function()
 {
-	tableSorter( 'userList' );
-	selection.setListenerFunction( orgUnitSelected );
+    tableSorter( 'userList' );
+    selection.setListenerFunction( orgUnitSelected, true );
 } );
 
 function orgUnitSelected( orgUnitIds )
 {
-	window.location.href = "user.action";
+    window.location.href = "user.action";
 }