← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 13973: web-api filtering, wip

 

------------------------------------------------------------
revno: 13973
committer: Morten Olav Hansen <mortenoh@xxxxxxxxx>
branch nick: dhis2
timestamp: Mon 2014-02-10 15:47:17 +0700
message:
  web-api filtering, wip
modified:
  dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/ReflectionUtils.java
  dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/AbstractCrudController.java
  dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/utils/WebUtils.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-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	2014-02-10 04:59:03 +0000
+++ dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/ReflectionUtils.java	2014-02-10 08:47:17 +0000
@@ -585,6 +585,15 @@
         {
             this.objects = objects;
         }
+
+        @Override public String toString()
+        {
+            return "MethodDescriptor{" +
+                "method=" + method +
+                ", collection=" + collection +
+                ", identifiableObject=" + identifiableObject +
+                '}';
+        }
     }
 
     public static Map<String, MethodDescriptor> getJacksonClassMap( Class<?> clazz )
@@ -669,7 +678,7 @@
 
                             if ( deep )
                             {
-                                Map<String, MethodDescriptor> classMap = getJacksonClassMap( klass, level );
+                                Map<String, MethodDescriptor> classMap = getJacksonClassMap( returnType, level );
                                 descriptor.setObjects( classMap );
                             }
                         }

=== modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/AbstractCrudController.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/AbstractCrudController.java	2014-02-10 04:59:03 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/AbstractCrudController.java	2014-02-10 08:47:17 +0000
@@ -87,9 +87,10 @@
     @RequestMapping( value = "/filtered", method = RequestMethod.GET )
     public void getJacksonClassMap(
         @RequestParam( required = false ) String include,
+        @RequestParam( required = false ) String exclude,
         @RequestParam Map<String, String> parameters, HttpServletResponse response ) throws IOException
     {
-        if ( include == null )
+        if ( include == null && exclude == null )
         {
             JacksonUtils.toJson( response.getOutputStream(), ReflectionUtils.getJacksonClassMap( getEntityClass() ) );
             return;
@@ -104,7 +105,7 @@
         postProcessEntities( entityList );
         postProcessEntities( entityList, options, parameters );
 
-        // List<Object> objects = WebUtils.filterFields( entityList, include );
+        List<Object> objects = WebUtils.filterFields( entityList, include );
         Map<String, Object> output = Maps.newLinkedHashMap();
 
         if ( options.hasPaging() )
@@ -112,7 +113,7 @@
             output.put( "pager", metaData.getPager() );
         }
 
-        output.put( "objects", WebUtils.parseFieldExpression( include ) );
+        output.put( "objects", objects );
 
         JacksonUtils.toJson( response.getOutputStream(), output );
     }

=== modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/utils/WebUtils.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/utils/WebUtils.java	2014-02-10 04:59:03 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/utils/WebUtils.java	2014-02-10 08:47:17 +0000
@@ -186,7 +186,7 @@
     }
 
     @SuppressWarnings( "unchecked" )
-    private static void putInMap( Map<String, Object> map, String path )
+    private static void putInMap( Map<String, Map> map, String path )
     {
         for ( String p : path.split( "\\." ) )
         {
@@ -195,14 +195,14 @@
                 map.put( p, Maps.newHashMap() );
             }
 
-            map = (Map<String, Object>) map.get( p );
+            map = (Map<String, Map>) map.get( p );
         }
     }
 
-    public static Map<String, Object> parseFieldExpression( String fields )
+    public static Map<String, Map> parseFieldExpression( String fields )
     {
         List<String> prefixList = Lists.newArrayList();
-        Map<String, Object> parsed = Maps.newHashMap();
+        Map<String, Map> parsed = Maps.newHashMap();
 
         StringBuilder builder = new StringBuilder();
 
@@ -254,4 +254,125 @@
         output = output.isEmpty() ? builder.toString() : (output + "." + builder.toString());
         return output;
     }
+
+    public static <T extends IdentifiableObject> List<Object> filterFields( List<T> objects, String fields )
+    {
+        List<Object> output = Lists.newArrayList();
+
+        if ( objects.isEmpty() || fields == null )
+        {
+            return output;
+        }
+
+        Map<String, Map> fieldMap = parseFieldExpression( fields );
+
+        for ( Object object : objects )
+        {
+            output.add( buildObjectOutput( object, fieldMap ) );
+        }
+
+        return output;
+    }
+
+    @SuppressWarnings( "unchecked" )
+    private static Map<String, Object> buildObjectOutput( Object object, Map<String, Map> fieldMap )
+    {
+        Map<String, Object> output = Maps.newHashMap();
+        Map<String, ReflectionUtils.MethodDescriptor> classMap = ReflectionUtils.getJacksonClassMap( object.getClass() );
+
+        for ( String key : fieldMap.keySet() )
+        {
+            if ( !classMap.containsKey( key ) )
+            {
+                continue;
+            }
+
+            Map value = fieldMap.get( key );
+            ReflectionUtils.MethodDescriptor descriptor = classMap.get( key );
+
+            if ( value.isEmpty() )
+            {
+                if ( !descriptor.isCollection() && !descriptor.isIdentifiableObject() )
+                {
+                    Object returned = ReflectionUtils.invokeMethod( object, descriptor.getMethod() );
+                    output.put( key, returned );
+                }
+                else if ( descriptor.isIdentifiableObject() && !descriptor.isCollection() )
+                {
+                    Object returned = getIdentifiableObjectProperties( object );
+                    output.put( key, returned );
+                }
+                else if ( descriptor.isCollection() && descriptor.isIdentifiableObject() )
+                {
+                    Object returned = ReflectionUtils.invokeMethod( object, descriptor.getMethod() );
+                    returned = getIdentifiableObjectCollectionProperties( returned );
+                    output.put( key, returned );
+                }
+            }
+        }
+
+        return output;
+    }
+
+    private static Object getIdentifiableObjectCollectionProperties( Object object )
+    {
+        List<String> fields = Lists.newArrayList( "id", "name", "code", "created", "lastUpdated" );
+        return getIdentifiableObjectCollectionProperties( object, fields );
+    }
+
+    @SuppressWarnings( "unchecked" )
+    private static Object getIdentifiableObjectCollectionProperties( Object object, List<String> fields )
+    {
+        List<Map<String, Object>> idPropertiesList = Lists.newArrayList();
+        Collection<IdentifiableObject> identifiableObjects;
+
+        try
+        {
+            identifiableObjects = (Collection<IdentifiableObject>) object;
+        }
+        catch ( ClassCastException ex )
+        {
+            ex.printStackTrace();
+            return idPropertiesList;
+        }
+
+        for ( IdentifiableObject identifiableObject : identifiableObjects )
+        {
+            Map<String, Object> properties = getIdentifiableObjectProperties( identifiableObject, fields );
+            idPropertiesList.add( properties );
+        }
+
+        return idPropertiesList;
+    }
+
+    private static Map<String, Object> getIdentifiableObjectProperties( Object object )
+    {
+        List<String> fields = Lists.newArrayList( "id", "name", "code", "created", "lastUpdated" );
+        return getIdentifiableObjectProperties( object, fields );
+    }
+
+    private static Map<String, Object> getIdentifiableObjectProperties( Object object, List<String> fields )
+    {
+        Map<String, Object> idProps = Maps.newLinkedHashMap();
+        Map<String, ReflectionUtils.MethodDescriptor> classMap = ReflectionUtils.getJacksonClassMap( object.getClass() );
+
+        for ( String field : fields )
+        {
+            ReflectionUtils.MethodDescriptor descriptor = classMap.get( field );
+
+            if ( descriptor == null )
+            {
+                continue;
+            }
+
+            Object o = ReflectionUtils.invokeMethod( object, descriptor.getMethod() );
+
+            if ( o != null )
+            {
+                idProps.put( field, o );
+            }
+        }
+
+        return idProps;
+    }
 }