dhis2-devs team mailing list archive
-
dhis2-devs team
-
Mailing list archive
-
Message #28029
[Branch ~dhis2-devs-core/dhis2/trunk] Rev 13968: rewrote logic for parsing of jacksonClassMap and filter queries for web-api
------------------------------------------------------------
revno: 13968
committer: Morten Olav Hansen <mortenoh@xxxxxxxxx>
branch nick: dhis2
timestamp: Mon 2014-02-10 11:59:03 +0700
message:
rewrote logic for parsing of jacksonClassMap and filter queries for web-api
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-06 08:24:34 +0000
+++ dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/ReflectionUtils.java 2014-02-10 04:59:03 +0000
@@ -28,6 +28,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.google.common.collect.Maps;
@@ -524,22 +525,90 @@
return fieldName;
}
- private static Map<Class<?>, Map<String, Method>> classMapCache = Maps.newHashMap();
-
- public static Map<String, Method> getJacksonClassMap( Class<?> clazz )
- {
- return getJacksonClassMap( clazz, true );
- }
-
- public static Map<String, Method> getJacksonClassMap( Class<?> clazz, boolean deep )
- {
+ private static Map<Class<?>, Map<String, MethodDescriptor>> classMapCache = Maps.newHashMap();
+
+ public static class MethodDescriptor
+ {
+ private Method method;
+
+ private boolean collection;
+
+ private boolean identifiableObject;
+
+ private Map<String, MethodDescriptor> objects;
+
+ private MethodDescriptor( Method method )
+ {
+ this.method = method;
+ }
+
+ @JsonIgnore
+ public Method getMethod()
+ {
+ return method;
+ }
+
+ public void setMethod( Method method )
+ {
+ this.method = method;
+ }
+
+ @JsonProperty
+ public boolean isCollection()
+ {
+ return collection;
+ }
+
+ public void setCollection( boolean collection )
+ {
+ this.collection = collection;
+ }
+
+ @JsonProperty
+ public boolean isIdentifiableObject()
+ {
+ return identifiableObject;
+ }
+
+ public void setIdentifiableObject( boolean identifiableObject )
+ {
+ this.identifiableObject = identifiableObject;
+ }
+
+ @JsonProperty
+ public Map<String, MethodDescriptor> getObjects()
+ {
+ return objects;
+ }
+
+ public void setObjects( Map<String, MethodDescriptor> objects )
+ {
+ this.objects = objects;
+ }
+ }
+
+ public static Map<String, MethodDescriptor> getJacksonClassMap( Class<?> clazz )
+ {
+ return getJacksonClassMap( clazz, 2 );
+ }
+
+ public static Map<String, MethodDescriptor> getJacksonClassMap( Class<?> clazz, int level )
+ {
+ // this short-circuits the level stuff for now, need to fix this properly
if ( classMapCache.containsKey( clazz ) )
{
return classMapCache.get( clazz );
}
- Map<String, Method> output = Maps.newLinkedHashMap();
-
+ boolean deep = false;
+ level--;
+
+ if ( level > 0 )
+ {
+ deep = true;
+ }
+
+ Map<String, MethodDescriptor> output = Maps.newLinkedHashMap();
List<Method> allMethods = getAllMethods( clazz );
for ( Method method : allMethods )
@@ -547,6 +616,7 @@
if ( method.isAnnotationPresent( JsonProperty.class ) )
{
JsonProperty jsonProperty = method.getAnnotation( JsonProperty.class );
+ MethodDescriptor descriptor = new MethodDescriptor( method );
String name = jsonProperty.value();
@@ -567,25 +637,23 @@
}
name = StringUtils.uncapitalize( name );
- output.put( name, method );
- }
- else
- {
- output.put( name, method );
- }
+ }
+
+ output.put( name, descriptor );
Class<?> returnType = method.getReturnType();
- if ( deep && IdentifiableObject.class.isAssignableFrom( returnType ) )
+ if ( IdentifiableObject.class.isAssignableFrom( returnType ) )
{
- Map<String, Method> classMap = getJacksonClassMap( returnType, false );
+ descriptor.setIdentifiableObject( true );
- for ( String key : classMap.keySet() )
+ if ( deep )
{
- output.put( name + "." + key, classMap.get( key ) );
+ Map<String, MethodDescriptor> classMap = getJacksonClassMap( returnType, level );
+ descriptor.setObjects( classMap );
}
}
- else if ( deep && Collection.class.isAssignableFrom( returnType ) )
+ else if ( Collection.class.isAssignableFrom( returnType ) )
{
Type type = method.getGenericReturnType();
@@ -596,11 +664,13 @@
if ( IdentifiableObject.class.isAssignableFrom( klass ) )
{
- Map<String, Method> classMap = getJacksonClassMap( klass, false );
+ descriptor.setCollection( true );
+ descriptor.setIdentifiableObject( true );
- for ( String key : classMap.keySet() )
+ if ( deep )
{
- output.put( name + "." + key, classMap.get( key ) );
+ Map<String, MethodDescriptor> classMap = getJacksonClassMap( klass, 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-06 06:37:09 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/AbstractCrudController.java 2014-02-10 04:59:03 +0000
@@ -85,12 +85,13 @@
//--------------------------------------------------------------------------
@RequestMapping( value = "/filtered", method = RequestMethod.GET )
- public void getJacksonClassMap( @RequestParam( required = false ) String fields,
+ public void getJacksonClassMap(
+ @RequestParam( required = false ) String include,
@RequestParam Map<String, String> parameters, HttpServletResponse response ) throws IOException
{
- if ( fields == null )
+ if ( include == null )
{
- JacksonUtils.toJson( response.getOutputStream(), ReflectionUtils.getJacksonClassMap( getEntityClass() ).keySet() );
+ JacksonUtils.toJson( response.getOutputStream(), ReflectionUtils.getJacksonClassMap( getEntityClass() ) );
return;
}
@@ -103,7 +104,7 @@
postProcessEntities( entityList );
postProcessEntities( entityList, options, parameters );
- List<Object> objects = WebUtils.filterFields( entityList, fields );
+ // List<Object> objects = WebUtils.filterFields( entityList, include );
Map<String, Object> output = Maps.newLinkedHashMap();
if ( options.hasPaging() )
@@ -111,7 +112,7 @@
output.put( "pager", metaData.getPager() );
}
- output.put( "objects", objects );
+ output.put( "objects", WebUtils.parseFieldExpression( include ) );
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-07 06:32:38 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/utils/WebUtils.java 2014-02-10 04:59:03 +0000
@@ -41,7 +41,6 @@
import org.hisp.dhis.user.UserCredentials;
import java.lang.reflect.Field;
-import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -186,111 +185,32 @@
}
}
- public static <T extends IdentifiableObject> List<Object> filterFields( List<T> entityList, String fields )
+ @SuppressWarnings( "unchecked" )
+ private static void putInMap( Map<String, Object> map, String path )
{
- List<Object> objects = Lists.newArrayList();
-
- if ( entityList.isEmpty() || fields == null )
- {
- return objects;
- }
-
- Map<String, Method> classMap = ReflectionUtils.getJacksonClassMap( entityList.get( 0 ).getClass() );
- List<String> parsedFields = parseFieldExpression( fields );
-
- for ( T object : entityList )
- {
- Map<String, Object> objMap = Maps.newLinkedHashMap();
-
- for ( String field : parsedFields )
+ for ( String p : path.split( "\\." ) )
+ {
+ if ( map.get( p ) == null )
{
- if ( classMap.containsKey( field ) )
- {
- Object o = ReflectionUtils.invokeMethod( object, classMap.get( field ) );
-
- if ( o == null )
- {
- continue;
- }
-
- if ( !ReflectionUtils.isCollection( o ) )
- {
- if ( IdentifiableObject.class.isInstance( o ) )
- {
- objMap.put( field, getIdentifiableObjectProperties( (IdentifiableObject) o ) );
- }
- else
- {
- objMap.put( field, o );
- }
- }
- else
- {
- objMap.put( field, getIdentifiableObjectCollectionProperties( o ) );
- }
- }
+ map.put( p, Maps.newHashMap() );
}
- objects.add( objMap );
- }
-
- return objects;
- }
-
- @SuppressWarnings( "unchecked" )
- private static Object getIdentifiableObjectCollectionProperties( Object o )
- {
- List<Map<String, Object>> idPropertiesList = Lists.newArrayList();
- Collection<IdentifiableObject> identifiableObjects;
-
- try
- {
- identifiableObjects = (Collection<IdentifiableObject>) o;
- }
- catch ( ClassCastException ex )
- {
- return o;
- }
-
- for ( IdentifiableObject identifiableObject : identifiableObjects )
- {
- Map<String, Object> idProps = getIdentifiableObjectProperties( identifiableObject );
- idPropertiesList.add( idProps );
- }
-
- return idPropertiesList;
- }
-
- private static Map<String, Object> getIdentifiableObjectProperties( IdentifiableObject identifiableObject )
- {
- Map<String, Object> idProps = Maps.newLinkedHashMap();
-
- idProps.put( "id", identifiableObject.getUid() );
- idProps.put( "name", identifiableObject.getDisplayName() );
-
- if ( identifiableObject.getCode() != null )
- {
- idProps.put( "code", identifiableObject.getCode() );
- }
-
- idProps.put( "created", identifiableObject.getCreated() );
- idProps.put( "lastUpdated", identifiableObject.getLastUpdated() );
-
- return idProps;
- }
-
- private static List<String> parseFieldExpression( String fields )
- {
- List<String> splitFields = Lists.newArrayList();
+ map = (Map<String, Object>) map.get( p );
+ }
+ }
+
+ public static Map<String, Object> parseFieldExpression( String fields )
+ {
+ List<String> prefixList = Lists.newArrayList();
+ Map<String, Object> parsed = Maps.newHashMap();
StringBuilder builder = new StringBuilder();
- ArrayList<String> prefixList = Lists.newArrayList();
for ( String c : fields.split( "" ) )
{
if ( c.equals( "," ) )
{
- splitFields.add( joinedWithPrefix( builder, prefixList ) );
+ putInMap( parsed, joinedWithPrefix( builder, prefixList ) );
builder = new StringBuilder();
continue;
}
@@ -306,7 +226,7 @@
{
if ( !builder.toString().isEmpty() )
{
- splitFields.add( joinedWithPrefix( builder, prefixList ) );
+ putInMap( parsed, joinedWithPrefix( builder, prefixList ) );
}
prefixList.remove( prefixList.size() - 1 );
@@ -322,10 +242,10 @@
if ( !builder.toString().isEmpty() )
{
- splitFields.add( joinedWithPrefix( builder, prefixList ) );
+ putInMap( parsed, joinedWithPrefix( builder, prefixList ) );
}
- return splitFields;
+ return parsed;
}
private static String joinedWithPrefix( StringBuilder builder, List<String> prefixList )