=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/GenericStore.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/GenericStore.java 2015-01-19 05:09:11 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/GenericStore.java 2015-02-17 05:01:28 +0000 @@ -28,6 +28,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +import org.hisp.dhis.query.Order; + import java.util.List; /** @@ -90,13 +92,27 @@ List getAll(); /** - * Retrieves a List of all objects. + * Retrieves a List of all objects, ordered as specified (only persisted properties are supported). + * + * @return a List of all objects. + */ + List getAll( Order order ); + + /** + * Retrieves a paged List of all objects. * * @return a List of all objects. */ List getAll( int first, int max ); /** + * Retrieves a paged List of all objects, ordered as specified (only persisted properties are supported). + * + * @return a List of all objects. + */ + List getAll( int first, int max, Order order ); + + /** * Removes the given object instance. * * @param object the object instance to delete. === modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/IdentifiableObjectManager.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/IdentifiableObjectManager.java 2015-01-19 05:09:11 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/IdentifiableObjectManager.java 2015-02-17 05:01:28 +0000 @@ -29,6 +29,7 @@ */ import org.hisp.dhis.common.NameableObject.NameableProperty; +import org.hisp.dhis.query.Order; import java.util.Collection; import java.util.Date; @@ -69,6 +70,8 @@ Collection getAll( Class clazz ); + Collection getAll( Class clazz, Order order ); + Collection getAllByName( Class clazz, String name ); Collection getAllByNameIgnoreCase( Class clazz, String name ); @@ -85,6 +88,8 @@ List getBetween( Class clazz, int first, int max ); + List getBetween( Class clazz, int first, int max, Order order ); + List getBetweenSorted( Class clazz, int first, int max ); List getBetweenLikeName( Class clazz, String name, int first, int max ); === added directory 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/query' === added file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/query/Order.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/query/Order.java 1970-01-01 00:00:00 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/query/Order.java 2015-02-17 05:01:28 +0000 @@ -0,0 +1,80 @@ +package org.hisp.dhis.query; + +/* + * Copyright (c) 2004-2015, 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.schema.Property; + +/** + * @author Morten Olav Hansen + */ +public class Order +{ + private boolean ascending; + + private boolean ignoreCase; + + private Property property; + + public Order( Property property, boolean ascending ) + { + this.property = property; + this.ascending = ascending; + } + + public Order ignoreCase() + { + this.ignoreCase = true; + return this; + } + + public boolean isAscending() + { + return ascending; + } + + public boolean isIgnoreCase() + { + return ignoreCase; + } + + public Property getProperty() + { + return property; + } + + public static Order asc( Property property ) + { + return new Order( property, true ); + } + + public static Order desc( Property property ) + { + return new Order( property, false ); + } +} === modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/common/DefaultIdentifiableObjectManager.java' --- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/common/DefaultIdentifiableObjectManager.java 2015-01-19 05:09:11 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/common/DefaultIdentifiableObjectManager.java 2015-02-17 05:01:28 +0000 @@ -33,6 +33,7 @@ import org.hibernate.SessionFactory; import org.hisp.dhis.common.NameableObject.NameableProperty; import org.hisp.dhis.common.comparator.IdentifiableObjectNameComparator; +import org.hisp.dhis.query.Order; import org.hisp.dhis.user.UserCredentials; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; @@ -267,6 +268,20 @@ @Override @SuppressWarnings( "unchecked" ) + public Collection getAll( Class clazz, Order order ) + { + GenericIdentifiableObjectStore store = getIdentifiableObjectStore( clazz ); + + if ( store == null ) + { + return new ArrayList<>(); + } + + return (Collection) store.getAll( order ); + } + + @Override + @SuppressWarnings( "unchecked" ) public Collection getAllByName( Class clazz, String name ) { GenericIdentifiableObjectStore store = getIdentifiableObjectStore( clazz ); @@ -470,6 +485,20 @@ @Override @SuppressWarnings( "unchecked" ) + public List getBetween( Class clazz, int first, int max, Order order ) + { + GenericIdentifiableObjectStore store = getIdentifiableObjectStore( clazz ); + + if ( store == null ) + { + return new ArrayList<>(); + } + + return (List) store.getAll( first, max, order ); + } + + @Override + @SuppressWarnings( "unchecked" ) public List getBetweenSorted( Class clazz, int first, int max ) { GenericIdentifiableObjectStore store = getIdentifiableObjectStore( clazz ); === modified file 'dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/common/IdentifiableObjectManagerTest.java' --- dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/common/IdentifiableObjectManagerTest.java 2015-02-09 09:38:38 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/common/IdentifiableObjectManagerTest.java 2015-02-17 05:01:28 +0000 @@ -38,6 +38,8 @@ import org.hisp.dhis.hibernate.exception.CreateAccessDeniedException; import org.hisp.dhis.hibernate.exception.DeleteAccessDeniedException; import org.hisp.dhis.organisationunit.OrganisationUnit; +import org.hisp.dhis.query.Order; +import org.hisp.dhis.schema.Property; import org.hisp.dhis.user.User; import org.hisp.dhis.user.UserGroup; import org.hisp.dhis.user.UserGroupAccess; @@ -569,4 +571,68 @@ assertTrue( cd.contains( dataElementC ) ); assertTrue( cd.contains( dataElementD ) ); } + + @Test + public void orderTest() + { + DataElement dataElementC = createDataElement( 'C' ); + DataElement dataElementA = createDataElement( 'A' ); + DataElement dataElementD = createDataElement( 'D' ); + DataElement dataElementB = createDataElement( 'B' ); + + identifiableObjectManager.save( dataElementA ); + identifiableObjectManager.save( dataElementB ); + identifiableObjectManager.save( dataElementC ); + identifiableObjectManager.save( dataElementD ); + + Property property = new Property( DataElement.class, null, null ); + property.setPersisted( true ); + property.setFieldName( "name" ); + + List asc = new ArrayList<>( identifiableObjectManager.getAll( DataElement.class, Order.asc( property ) ) ); + assertTrue( "DataElementA".equals( asc.get( 0 ).getName() ) ); + assertTrue( "DataElementB".equals( asc.get( 1 ).getName() ) ); + assertTrue( "DataElementC".equals( asc.get( 2 ).getName() ) ); + assertTrue( "DataElementD".equals( asc.get( 3 ).getName() ) ); + + List desc = new ArrayList<>( identifiableObjectManager.getAll( DataElement.class, Order.desc( property ) ) ); + assertTrue( "DataElementD".equals( desc.get( 0 ).getName() ) ); + assertTrue( "DataElementC".equals( desc.get( 1 ).getName() ) ); + assertTrue( "DataElementB".equals( desc.get( 2 ).getName() ) ); + assertTrue( "DataElementA".equals( desc.get( 3 ).getName() ) ); + } + + @Test + public void pagedOrderTest() + { + DataElement dataElementC = createDataElement( 'C' ); + DataElement dataElementA = createDataElement( 'A' ); + DataElement dataElementD = createDataElement( 'D' ); + DataElement dataElementB = createDataElement( 'B' ); + + identifiableObjectManager.save( dataElementA ); + identifiableObjectManager.save( dataElementB ); + identifiableObjectManager.save( dataElementC ); + identifiableObjectManager.save( dataElementD ); + + Property property = new Property( DataElement.class, null, null ); + property.setPersisted( true ); + property.setFieldName( "name" ); + + List asc = new ArrayList<>( identifiableObjectManager.getBetween( DataElement.class, 0, 2, Order.asc( property ) ) ); + assertTrue( "DataElementA".equals( asc.get( 0 ).getName() ) ); + assertTrue( "DataElementB".equals( asc.get( 1 ).getName() ) ); + + asc = new ArrayList<>( identifiableObjectManager.getBetween( DataElement.class, 2, 2, Order.asc( property ) ) ); + assertTrue( "DataElementC".equals( asc.get( 0 ).getName() ) ); + assertTrue( "DataElementD".equals( asc.get( 1 ).getName() ) ); + + List desc = new ArrayList<>( identifiableObjectManager.getBetween( DataElement.class, 0, 2, Order.desc( property ) ) ); + assertTrue( "DataElementD".equals( desc.get( 0 ).getName() ) ); + assertTrue( "DataElementC".equals( desc.get( 1 ).getName() ) ); + + desc = new ArrayList<>( identifiableObjectManager.getBetween( DataElement.class, 2, 2, Order.desc( property ) ) ); + assertTrue( "DataElementB".equals( desc.get( 0 ).getName() ) ); + assertTrue( "DataElementA".equals( desc.get( 1 ).getName() ) ); + } } === modified file 'dhis-2/dhis-support/dhis-support-hibernate/src/main/java/org/hisp/dhis/hibernate/HibernateGenericStore.java' --- dhis-2/dhis-support/dhis-support-hibernate/src/main/java/org/hisp/dhis/hibernate/HibernateGenericStore.java 2015-01-21 09:11:18 +0000 +++ dhis-2/dhis-support/dhis-support-hibernate/src/main/java/org/hisp/dhis/hibernate/HibernateGenericStore.java 2015-02-17 05:01:28 +0000 @@ -54,6 +54,7 @@ import org.hisp.dhis.hibernate.exception.ReadAccessDeniedException; import org.hisp.dhis.hibernate.exception.UpdateAccessDeniedException; import org.hisp.dhis.interpretation.Interpretation; +import org.hisp.dhis.query.Order; import org.hisp.dhis.user.CurrentUserService; import org.hisp.dhis.user.User; import org.springframework.beans.factory.annotation.Autowired; @@ -437,6 +438,23 @@ @Override @SuppressWarnings( "unchecked" ) + public final List getAll( Order order ) + { + Criteria criteria = getSharingCriteria(); + org.hibernate.criterion.Order criteriaOrder = getHibernateOrder( order ); + + if ( criteriaOrder == null ) + { + return criteria.list(); + } + + return criteria + .addOrder( criteriaOrder ) + .list(); + } + + @Override + @SuppressWarnings( "unchecked" ) public final List getAll( int first, int max ) { return getSharingCriteria() @@ -446,6 +464,25 @@ } @Override + @SuppressWarnings( "unchecked" ) + public List getAll( int first, int max, Order order ) + { + Criteria criteria = getSharingCriteria(); + org.hibernate.criterion.Order criteriaOrder = getHibernateOrder( order ); + + if ( criteriaOrder == null ) + { + return criteria.list(); + } + + return criteria + .addOrder( criteriaOrder ) + .setFirstResult( first ) + .setMaxResults( max ) + .list(); + } + + @Override public int getCount() { return ((Number) getSharingCriteria() @@ -552,4 +589,30 @@ return true; } + + protected org.hibernate.criterion.Order getHibernateOrder( Order order ) + { + if ( order.getProperty() == null || !order.getProperty().isPersisted() ) + { + return null; + } + + org.hibernate.criterion.Order criteriaOrder; + + if ( order.isAscending() ) + { + criteriaOrder = org.hibernate.criterion.Order.asc( order.getProperty().getFieldName() ); + } + else + { + criteriaOrder = org.hibernate.criterion.Order.desc( order.getProperty().getFieldName() ); + } + + if ( order.isIgnoreCase() ) + { + criteriaOrder.ignoreCase(); + } + + return criteriaOrder; + } }