← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 21444: wip, introspector updates to properly handle overloaded and overriden getters

 

------------------------------------------------------------
revno: 21444
committer: Morten Olav Hansen <mortenoh@xxxxxxxxx>
branch nick: dhis2
timestamp: Mon 2015-12-14 17:33:02 +0100
message:
  wip, introspector updates to properly handle overloaded and overriden getters
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnit.java
  dhis-2/dhis-api/src/test/java/org/hisp/dhis/organisationunit/OrganisationUnitTest.java
  dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultAnalyticsService.java
  dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/data/DefaultEventAnalyticsService.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/schema/Jackson2PropertyIntrospectorService.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/validation/DefaultValidationRuleService.java
  dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/organisationunit/OrganisationUnitController.java
  dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/commons/action/GetOrganisationUnitTreeAction.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/organisationunit/OrganisationUnit.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnit.java	2015-12-14 09:19:58 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnit.java	2015-12-14 16:33:02 +0000
@@ -560,7 +560,7 @@
 
     public String getAncestorNames()
     {
-        List<OrganisationUnit> units = getParents();
+        List<OrganisationUnit> units = getAncestors();
 
         StringBuilder builder = new StringBuilder();
 
@@ -581,7 +581,7 @@
     @JsonView( { DetailedView.class } )
     @JacksonXmlElementWrapper( localName = "parents", namespace = DxfNamespaces.DXF_2_0 )
     @JacksonXmlProperty( localName = "organisationUnit", namespace = DxfNamespaces.DXF_2_0 )
-    public List<OrganisationUnit> getParents()
+    public List<OrganisationUnit> getAncestors()
     {
         List<OrganisationUnit> units = new ArrayList<>();
 

=== modified file 'dhis-2/dhis-api/src/test/java/org/hisp/dhis/organisationunit/OrganisationUnitTest.java'
--- dhis-2/dhis-api/src/test/java/org/hisp/dhis/organisationunit/OrganisationUnitTest.java	2015-12-14 09:19:58 +0000
+++ dhis-2/dhis-api/src/test/java/org/hisp/dhis/organisationunit/OrganisationUnitTest.java	2015-12-14 16:33:02 +0000
@@ -104,7 +104,7 @@
         
         List<OrganisationUnit> expected = new ArrayList<>( Arrays.asList( unitA, unitB, unitC ) );
         
-        assertEquals( expected, unitD.getParents() );
+        assertEquals( expected, unitD.getAncestors() );
     }
 
     @Test

=== modified file 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultAnalyticsService.java'
--- dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultAnalyticsService.java	2015-12-14 09:19:58 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultAnalyticsService.java	2015-12-14 16:33:02 +0000
@@ -942,7 +942,7 @@
                 {
                     OrganisationUnit unit = (OrganisationUnit) object;
                     
-                    map.putAll( NameableObjectUtils.getUidDisplayPropertyMap( unit.getParents(), params.getDisplayProperty() ) );
+                    map.putAll( NameableObjectUtils.getUidDisplayPropertyMap( unit.getAncestors(), params.getDisplayProperty() ) );
                 }
             }
 

=== modified file 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/data/DefaultEventAnalyticsService.java'
--- dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/data/DefaultEventAnalyticsService.java	2015-12-14 09:19:58 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/data/DefaultEventAnalyticsService.java	2015-12-14 16:33:02 +0000
@@ -384,7 +384,7 @@
                 if ( hierarchy )
                 {
                     OrganisationUnit unit = (OrganisationUnit) object;
-                    objects.addAll( unit.getParents() );
+                    objects.addAll( unit.getAncestors() );
                 }
                 
                 map.putAll( NameableObjectUtils.getUidDisplayPropertyMap( objects, displayProperty ) );

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/schema/Jackson2PropertyIntrospectorService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/schema/Jackson2PropertyIntrospectorService.java	2015-10-19 08:29:13 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/schema/Jackson2PropertyIntrospectorService.java	2015-12-14 16:33:02 +0000
@@ -32,22 +32,32 @@
 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 com.google.common.collect.Lists;
+import com.google.common.collect.ArrayListMultimap;
 import com.google.common.collect.Maps;
+import com.google.common.collect.Multimap;
 import com.google.common.primitives.Primitives;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.hisp.dhis.common.IdentifiableObject;
 import org.hisp.dhis.common.NameableObject;
 import org.hisp.dhis.common.annotation.Description;
 import org.hisp.dhis.system.util.ReflectionUtils;
+import org.springframework.core.annotation.AnnotationUtils;
 import org.springframework.util.StringUtils;
 
 import java.lang.reflect.Method;
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import static org.springframework.util.ReflectionUtils.getUniqueDeclaredMethods;
 
 /**
  * Default PropertyIntrospectorService implementation that uses Reflection and Jackson annotations
@@ -58,6 +68,8 @@
 public class Jackson2PropertyIntrospectorService
     extends AbstractPropertyIntrospectorService
 {
+    private static final Log log = LogFactory.getLog( AbstractPropertyIntrospectorService.class );
+
     @Override
     protected Map<String, Property> scanClass( Class<?> clazz )
     {
@@ -70,7 +82,7 @@
         {
             Property property = new Property();
 
-            JacksonXmlRootElement jacksonXmlRootElement = clazz.getAnnotation( JacksonXmlRootElement.class );
+            JacksonXmlRootElement jacksonXmlRootElement = AnnotationUtils.findAnnotation( clazz, JacksonXmlRootElement.class );
 
             if ( !StringUtils.isEmpty( jacksonXmlRootElement.localName() ) )
             {
@@ -90,7 +102,13 @@
         for ( Property property : properties )
         {
             Method getterMethod = property.getGetterMethod();
-            JsonProperty jsonProperty = getterMethod.getAnnotation( JsonProperty.class );
+            JsonProperty jsonProperty = AnnotationUtils.findAnnotation( getterMethod, JsonProperty.class );
+
+            if ( jsonProperty == null )
+            {
+                System.err.println( "NO JSON PROPERTY on Property : " + property.getName() + ", method: " + getterMethod );
+                continue;
+            }
 
             String fieldName = getFieldName( getterMethod );
             property.setName( !StringUtils.isEmpty( jsonProperty.value() ) ? jsonProperty.value() : fieldName );
@@ -133,15 +151,15 @@
                 property.setSetterMethod( hibernateProperty.getSetterMethod() );
             }
 
-            if ( property.getGetterMethod().isAnnotationPresent( Description.class ) )
+            if ( AnnotationUtils.findAnnotation( property.getGetterMethod(), Description.class ) != null )
             {
-                Description description = property.getGetterMethod().getAnnotation( Description.class );
+                Description description = AnnotationUtils.findAnnotation( property.getGetterMethod(), Description.class );
                 property.setDescription( description.value() );
             }
 
-            if ( property.getGetterMethod().isAnnotationPresent( JacksonXmlProperty.class ) )
+            if ( AnnotationUtils.findAnnotation( property.getGetterMethod(), JacksonXmlProperty.class ) != null )
             {
-                JacksonXmlProperty jacksonXmlProperty = getterMethod.getAnnotation( JacksonXmlProperty.class );
+                JacksonXmlProperty jacksonXmlProperty = AnnotationUtils.findAnnotation( getterMethod, JacksonXmlProperty.class );
 
                 if ( StringUtils.isEmpty( jacksonXmlProperty.localName() ) )
                 {
@@ -202,9 +220,9 @@
 
             if ( property.isCollection() )
             {
-                if ( property.getGetterMethod().isAnnotationPresent( JacksonXmlElementWrapper.class ) )
+                if ( AnnotationUtils.findAnnotation( property.getGetterMethod(), JacksonXmlElementWrapper.class ) != null )
                 {
-                    JacksonXmlElementWrapper jacksonXmlElementWrapper = getterMethod.getAnnotation( JacksonXmlElementWrapper.class );
+                    JacksonXmlElementWrapper jacksonXmlElementWrapper = AnnotationUtils.findAnnotation( getterMethod, JacksonXmlElementWrapper.class );
                     property.setCollectionWrapping( jacksonXmlElementWrapper.useWrapping() );
 
                     // TODO what if element-wrapper have different namespace?
@@ -261,23 +279,58 @@
         return StringUtils.uncapitalize( name );
     }
 
+    private Multimap<String, Method> getMultimap( Class<?> klass )
+    {
+        Multimap<String, Method> methods = ArrayListMultimap.create();
+        Arrays.asList( getUniqueDeclaredMethods( klass ) ).forEach( method -> methods.put( method.getName(), method ) );
+        return methods;
+    }
+
     private List<Property> collectProperties( Class<?> klass )
     {
-        Map<String, Method> methodMap = ReflectionUtils.getMethodMap( klass );
-        List<Property> properties = Lists.newArrayList();
-
-        methodMap.values().stream()
-            .filter( method -> method.isAnnotationPresent( JsonProperty.class ) && method.getGenericParameterTypes().length == 0 )
-            .forEach( method -> {
-                String fieldName = getFieldName( method );
-                String setterName = "set" + StringUtils.capitalize( fieldName );
-
-                Property property = new Property( klass, method, null );
-                property.setFieldName( fieldName );
-                property.setSetterMethod( methodMap.get( setterName ) );
-
-                properties.add( property );
-            } );
+        Multimap<String, Method> multimap = getMultimap( klass );
+        List<Property> properties = new ArrayList<>();
+
+        Map<String, Method> methodMap = multimap.keySet().stream()
+            .filter( key -> {
+                List<Method> methods = multimap.get( key ).stream()
+                    .filter( method -> AnnotationUtils.findAnnotation( method, JsonProperty.class ) != null && method.getParameterTypes().length == 0 )
+                    .collect( Collectors.toList() );
+
+                if ( methods.size() > 1 )
+                {
+                    log.error( "More than one web-api exposed method with name '" + key + "' found on class '" + klass.getName()
+                        + "' please fix as this is known to cause issues with Schema / Query services." );
+
+                    log.debug( "Methods found: " + methods );
+                }
+
+                return methods.size() == 1;
+            } )
+            .collect( Collectors.toMap( Function.<String>identity(), key -> {
+                List<Method> collect = multimap.get( key ).stream()
+                    .filter( method -> AnnotationUtils.findAnnotation( method, JsonProperty.class ) != null && method.getParameterTypes().length == 0 )
+                    .collect( Collectors.toList() );
+
+                return collect.get( 0 );
+            } ) );
+
+        methodMap.keySet().forEach( key -> {
+            String fieldName = getFieldName( methodMap.get( key ) );
+            String setterName = "set" + StringUtils.capitalize( fieldName );
+
+            Property property = new Property( klass, methodMap.get( key ), null );
+            property.setFieldName( fieldName );
+
+            Iterator<Method> methodIterator = multimap.get( setterName ).iterator();
+
+            if ( methodIterator.hasNext() )
+            {
+                property.setSetterMethod( methodIterator.next() );
+            }
+
+            properties.add( property );
+        } );
 
         return properties;
     }

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/validation/DefaultValidationRuleService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/validation/DefaultValidationRuleService.java	2015-12-14 09:19:58 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/validation/DefaultValidationRuleService.java	2015-12-14 16:33:02 +0000
@@ -525,7 +525,7 @@
     {
         for ( OrganisationUnit o : user.getOrganisationUnits() )
         {
-            if ( source == o || source.getParents().contains( o ) )
+            if ( source == o || source.getAncestors().contains( o ) )
             {
                 return true;
             }

=== modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/organisationunit/OrganisationUnitController.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/organisationunit/OrganisationUnitController.java	2015-12-14 09:19:58 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/organisationunit/OrganisationUnitController.java	2015-12-14 16:33:02 +0000
@@ -159,7 +159,7 @@
         {
             options.getOptions().put( "useWrapper", "true" );
             organisationUnits.add( organisationUnit );
-            List<OrganisationUnit> ancestors = organisationUnit.getParents();
+            List<OrganisationUnit> ancestors = organisationUnit.getAncestors();
             Collections.reverse( ancestors );
             organisationUnits.addAll( ancestors );
         }

=== modified file 'dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/commons/action/GetOrganisationUnitTreeAction.java'
--- dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/commons/action/GetOrganisationUnitTreeAction.java	2015-12-14 09:19:58 +0000
+++ dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/commons/action/GetOrganisationUnitTreeAction.java	2015-12-14 16:33:02 +0000
@@ -218,7 +218,7 @@
                 organisationUnits.add( leaf );
                 organisationUnits.addAll( leaf.getChildren() );
 
-                for ( OrganisationUnit organisationUnit : leaf.getParents() )
+                for ( OrganisationUnit organisationUnit : leaf.getAncestors() )
                 {
                     organisationUnits.add( organisationUnit );
                     organisationUnits.addAll( organisationUnit.getChildren() );