dhis2-devs team mailing list archive
-
dhis2-devs team
-
Mailing list archive
-
Message #30566
[Branch ~dhis2-devs-core/dhis2/trunk] Rev 15526: rewrote filter functionality to use node rendrer system, only supports json for now (but xml is c...
------------------------------------------------------------
revno: 15526
committer: Morten Olav Hansen <mortenoh@xxxxxxxxx>
branch nick: dhis2
timestamp: Tue 2014-06-03 00:47:30 +0200
message:
rewrote filter functionality to use node rendrer system, only supports json for now (but xml is coming soon)
modified:
dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/AbstractNode.java
dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/exception/InvalidTypeException.java
dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/serializers/JacksonJsonNodeSerializer.java
dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/serializers/StAXNodeSerializer.java
dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/schema/DefaultSchemaService.java
dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/filter/DefaultFilterService.java
dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/filter/FilterService.java
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/webapi/controller/AbstractCrudController.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/node/AbstractNode.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/AbstractNode.java 2014-06-01 14:30:40 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/AbstractNode.java 2014-06-02 22:47:30 +0000
@@ -69,6 +69,11 @@
@Override
public <T extends Node> T addNode( T node ) throws InvalidTypeException
{
+ if ( node == null )
+ {
+ return null;
+ }
+
nodes.add( node );
return node;
}
=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/exception/InvalidTypeException.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/exception/InvalidTypeException.java 2014-05-31 23:48:24 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/exception/InvalidTypeException.java 2014-06-02 22:47:30 +0000
@@ -31,7 +31,7 @@
/**
* @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
*/
-public class InvalidTypeException extends Exception
+public class InvalidTypeException extends RuntimeException
{
public InvalidTypeException( String message )
{
=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/serializers/JacksonJsonNodeSerializer.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/serializers/JacksonJsonNodeSerializer.java 2014-06-01 12:21:14 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/serializers/JacksonJsonNodeSerializer.java 2014-06-02 22:47:30 +0000
@@ -28,8 +28,10 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
*/
-import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
import org.hisp.dhis.node.Node;
import org.hisp.dhis.node.NodeSerializer;
import org.hisp.dhis.node.types.CollectionNode;
@@ -49,7 +51,7 @@
{
public static final String CONTENT_TYPE = "application/json";
- private final JsonFactory jsonFactory = new JsonFactory();
+ private final ObjectMapper objectMapper = new ObjectMapper();
@Override
public String contentType()
@@ -59,13 +61,17 @@
public JacksonJsonNodeSerializer()
{
-
+ objectMapper.setSerializationInclusion( JsonInclude.Include.NON_NULL );
+ objectMapper.configure( SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false );
+ objectMapper.configure( SerializationFeature.WRITE_EMPTY_JSON_ARRAYS, false );
+ objectMapper.configure( SerializationFeature.WRAP_EXCEPTIONS, true );
+ objectMapper.getFactory().enable( JsonGenerator.Feature.QUOTE_FIELD_NAMES );
}
@Override
public void serialize( RootNode rootNode, OutputStream outputStream ) throws IOException
{
- JsonGenerator generator = jsonFactory.createGenerator( outputStream );
+ JsonGenerator generator = objectMapper.getFactory().createGenerator( outputStream );
renderRootNode( rootNode, generator );
generator.flush();
@@ -86,6 +92,11 @@
private void renderSimpleNode( SimpleNode simpleNode, JsonGenerator generator, boolean writeKey ) throws IOException
{
+ if ( simpleNode.getValue() == null ) // add hint for this, exclude if null
+ {
+ return;
+ }
+
if ( writeKey )
{
generator.writeObjectField( simpleNode.getName(), simpleNode.getValue() );
=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/serializers/StAXNodeSerializer.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/serializers/StAXNodeSerializer.java 2014-06-01 12:21:14 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/serializers/StAXNodeSerializer.java 2014-06-02 22:47:30 +0000
@@ -94,6 +94,11 @@
private void renderSimpleNode( SimpleNode simpleNode, XMLStreamWriter writer ) throws XMLStreamException
{
+ if ( simpleNode.getValue() == null ) // add hint for this, exclude if null
+ {
+ return;
+ }
+
String value = String.format( "%s", simpleNode.getValue() );
writeStartElement( simpleNode, writer );
@@ -103,6 +108,11 @@
private void renderSimpleNodeAttribute( SimpleNode simpleNode, XMLStreamWriter writer ) throws XMLStreamException
{
+ if ( simpleNode.getValue() == null ) // add hint for this, exclude if null
+ {
+ return;
+ }
+
String value = String.format( "%s", simpleNode.getValue() );
if ( simpleNode.haveHint( NodeHint.Type.XML_NAMESPACE ) )
=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/schema/DefaultSchemaService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/schema/DefaultSchemaService.java 2014-06-02 21:00:27 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/schema/DefaultSchemaService.java 2014-06-02 22:47:30 +0000
@@ -30,7 +30,7 @@
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
-import javassist.util.proxy.ProxyFactory;
+import org.hisp.dhis.system.util.ReflectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.OrderComparator;
@@ -80,10 +80,7 @@
return null;
}
- if ( ProxyFactory.isProxyClass( klass ) )
- {
- klass = klass.getSuperclass();
- }
+ klass = ReflectionUtils.getRealClass( klass );
if ( classSchemaMap.containsKey( klass ) )
{
@@ -108,6 +105,8 @@
return schema;
}
+ klass = ReflectionUtils.getRealClass( klass );
+
schema = new Schema( klass, klass.getName(), klass.getName() );
schema.setPropertyMap( propertyIntrospectorService.getPropertiesMap( schema.getKlass() ) );
=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/filter/DefaultFilterService.java'
--- dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/filter/DefaultFilterService.java 2014-06-02 21:35:16 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/filter/DefaultFilterService.java 2014-06-02 22:47:30 +0000
@@ -32,6 +32,9 @@
import com.google.common.collect.Maps;
import org.hisp.dhis.common.IdentifiableObject;
import org.hisp.dhis.dxf2.filter.ops.Op;
+import org.hisp.dhis.node.types.CollectionNode;
+import org.hisp.dhis.node.types.ComplexNode;
+import org.hisp.dhis.node.types.SimpleNode;
import org.hisp.dhis.schema.Property;
import org.hisp.dhis.schema.Schema;
import org.hisp.dhis.schema.SchemaService;
@@ -80,13 +83,15 @@
}
@Override
- public <T extends IdentifiableObject> List<Object> filterProperties( List<T> objects, String include, String exclude )
+ public <T extends IdentifiableObject> CollectionNode filterProperties( Class<?> klass, List<T> objects,
+ String include, String exclude )
{
- List<Object> output = Lists.newArrayList();
+ Schema rootSchema = schemaService.getDynamicSchema( klass );
+ CollectionNode collectionNode = new CollectionNode( rootSchema.getPlural() ); // replace with 'xml' collection name
if ( objects.isEmpty() )
{
- return output;
+ return collectionNode;
}
Map<String, Map> fieldMap = Maps.newHashMap();
@@ -118,22 +123,22 @@
for ( Object object : objects )
{
- output.add( buildObjectOutput( object, fieldMap ) );
+ collectionNode.addNode( buildObjectOutput( fieldMap, object ) );
}
- return output;
+ return collectionNode;
}
@SuppressWarnings( "unchecked" )
- private Map<String, Object> buildObjectOutput( Object object, Map<String, Map> fieldMap )
+ private ComplexNode buildObjectOutput( Map<String, Map> fieldMap, Object object )
{
if ( object == null )
{
return null;
}
- Map<String, Object> output = Maps.newHashMap();
Schema schema = schemaService.getDynamicSchema( object.getClass() );
+ ComplexNode complexNode = new ComplexNode( schema.getSingular() );
for ( String fieldKey : fieldMap.keySet() )
{
@@ -156,58 +161,62 @@
{
if ( !property.isIdentifiableObject() )
{
- output.put( fieldKey, returnValue );
+ complexNode.addNode( new SimpleNode( fieldKey, returnValue ) );
}
else if ( !property.isCollection() )
{
- output.put( fieldKey, getIdentifiableObjectProperties( returnValue ) );
+ complexNode.addNode( getIdentifiableObjectProperties( returnValue, IDENTIFIABLE_PROPERTIES ) );
}
else
{
- output.put( fieldKey, getIdentifiableObjectCollectionProperties( returnValue ) );
+ complexNode.addNode( getIdentifiableObjectCollectionProperties( returnValue, IDENTIFIABLE_PROPERTIES, fieldKey ) );
}
}
else
{
if ( property.isCollection() )
{
- List<Object> list = Lists.newArrayList();
- output.put( fieldKey, list );
+ CollectionNode collectionNode = complexNode.addNode( new CollectionNode( property.getXmlCollectionName() ) );
- for ( Object obj : (Collection<?>) returnValue )
+ for ( Object collectionObject : (Collection<?>) returnValue )
{
- Map<String, Object> properties = buildObjectOutput( obj, fieldValue );
+ ComplexNode node = buildObjectOutput( fieldValue, collectionObject );
- if ( !properties.isEmpty() )
+ if ( !node.getNodes().isEmpty() )
{
- list.add( properties );
+ collectionNode.addNode( node );
}
}
}
else
{
- Map<String, Object> map = buildObjectOutput( returnValue, fieldValue );
+ ComplexNode node = buildObjectOutput( fieldValue, returnValue );
- if ( !map.isEmpty() )
+ if ( !node.getNodes().isEmpty() )
{
- output.put( fieldKey, map );
+ complexNode.addNode( node );
}
}
}
}
- return output;
- }
-
- private List<Map<String, Object>> getIdentifiableObjectCollectionProperties( Object object )
- {
- return getIdentifiableObjectCollectionProperties( object, IDENTIFIABLE_PROPERTIES );
+ return complexNode;
}
@SuppressWarnings( "unchecked" )
- private List<Map<String, Object>> getIdentifiableObjectCollectionProperties( Object object, List<String> fields )
+ private CollectionNode getIdentifiableObjectCollectionProperties( Object object, List<String> fields, String collectionName )
{
- List<Map<String, Object>> output = Lists.newArrayList();
+ if ( object == null )
+ {
+ return null;
+ }
+
+ if ( !Collection.class.isInstance( object ) )
+ {
+ return null;
+ }
+
+ CollectionNode collectionNode = new CollectionNode( collectionName );
Collection<IdentifiableObject> identifiableObjects;
try
@@ -217,28 +226,33 @@
catch ( ClassCastException ex )
{
ex.printStackTrace();
- return output;
+ return collectionNode;
}
for ( IdentifiableObject identifiableObject : identifiableObjects )
{
- Map<String, Object> properties = getIdentifiableObjectProperties( identifiableObject, fields );
- output.add( properties );
- }
-
- return output;
- }
-
- private Map<String, Object> getIdentifiableObjectProperties( Object object )
- {
- return getIdentifiableObjectProperties( object, IDENTIFIABLE_PROPERTIES );
- }
-
- private Map<String, Object> getIdentifiableObjectProperties( Object object, List<String> fields )
- {
- Map<String, Object> map = Maps.newLinkedHashMap();
+ collectionNode.addNode( getIdentifiableObjectProperties( identifiableObject, fields ) );
+ }
+
+ return collectionNode;
+ }
+
+ private ComplexNode getIdentifiableObjectProperties( Object object, List<String> fields )
+ {
+ if ( object == null )
+ {
+ return null;
+ }
+
+ if ( !IdentifiableObject.class.isInstance( object ) )
+ {
+ return null;
+ }
+
Schema schema = schemaService.getDynamicSchema( object.getClass() );
+ ComplexNode complexNode = new ComplexNode( schema.getSingular() );
+
for ( String field : fields )
{
Property property = schema.getPropertyMap().get( field );
@@ -252,11 +266,11 @@
if ( o != null )
{
- map.put( field, o );
+ complexNode.addNode( new SimpleNode( field, o ) );
}
}
- return map;
+ return complexNode;
}
@SuppressWarnings( "unchecked" )
@@ -268,7 +282,6 @@
{
if ( !schema.getPropertyMap().containsKey( field ) )
{
- System.err.println( "Skipping non-existent field: " + field );
continue;
}
=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/filter/FilterService.java'
--- dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/filter/FilterService.java 2014-04-14 06:43:16 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/filter/FilterService.java 2014-06-02 22:47:30 +0000
@@ -29,6 +29,7 @@
*/
import org.hisp.dhis.common.IdentifiableObject;
+import org.hisp.dhis.node.types.CollectionNode;
import java.util.List;
@@ -54,5 +55,6 @@
* @param exclude Exclusion filter
* @return List of objects with only wanted properties
*/
- <T extends IdentifiableObject> List<Object> filterProperties( List<T> objects, String include, String exclude );
+ <T extends IdentifiableObject> CollectionNode filterProperties( Class<?> klass, List<T> objects,
+ String include, String exclude );
}
=== 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-03-26 11:32:35 +0000
+++ dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/ReflectionUtils.java 2014-06-02 22:47:30 +0000
@@ -28,6 +28,8 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+import javassist.util.proxy.ProxyFactory;
+import org.hibernate.collection.spi.PersistentCollection;
import org.hisp.dhis.system.util.functional.Function1;
import org.hisp.dhis.system.util.functional.Predicate;
import org.springframework.util.StringUtils;
@@ -497,4 +499,19 @@
throw new RuntimeException( "Unknown Collection type." );
}
}
+
+ public static Class<?> getRealClass( Class<?> klass )
+ {
+ if ( ProxyFactory.isProxyClass( klass ) )
+ {
+ klass = klass.getSuperclass();
+ }
+
+ while ( PersistentCollection.class.isAssignableFrom( klass ) )
+ {
+ klass = klass.getSuperclass();
+ }
+
+ return klass;
+ }
}
=== modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/AbstractCrudController.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/AbstractCrudController.java 2014-06-02 19:07:47 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/AbstractCrudController.java 2014-06-02 22:47:30 +0000
@@ -29,7 +29,6 @@
*/
import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
import org.hisp.dhis.acl.Access;
import org.hisp.dhis.acl.AclService;
import org.hisp.dhis.common.BaseIdentifiableObject;
@@ -46,6 +45,10 @@
import org.hisp.dhis.hibernate.exception.DeleteAccessDeniedException;
import org.hisp.dhis.hibernate.exception.UpdateAccessDeniedException;
import org.hisp.dhis.importexport.ImportStrategy;
+import org.hisp.dhis.node.NodeService;
+import org.hisp.dhis.node.types.ComplexNode;
+import org.hisp.dhis.node.types.RootNode;
+import org.hisp.dhis.node.types.SimpleNode;
import org.hisp.dhis.schema.Schema;
import org.hisp.dhis.schema.SchemaService;
import org.hisp.dhis.system.util.ReflectionUtils;
@@ -106,6 +109,9 @@
@Autowired
protected ImportService importService;
+ @Autowired
+ protected NodeService nodeService;
+
//--------------------------------------------------------------------------
// GET
//--------------------------------------------------------------------------
@@ -204,24 +210,21 @@
// enable property filter
if ( include != null || exclude != null )
{
- List<Object> objects = filterService.filterProperties( entityList, include, exclude );
- Map<String, Object> output = Maps.newLinkedHashMap();
+ RootNode rootNode = new RootNode( "metadata" );
if ( hasPaging )
{
- output.put( "pager", metaData.getPager() );
- }
-
- if ( schema != null )
- {
- output.put( schema.getPlural(), objects );
- }
- else
- {
- output.put( "objects", objects );
- }
-
- renderService.toJson( response.getOutputStream(), output );
+ ComplexNode pagerNode = rootNode.addNode( new ComplexNode( "pager" ) );
+ pagerNode.addNode( new SimpleNode( "page", metaData.getPager().getPage() ) );
+ pagerNode.addNode( new SimpleNode( "pageCount", metaData.getPager().getPageCount() ) );
+ pagerNode.addNode( new SimpleNode( "total", metaData.getPager().getTotal() ) );
+ pagerNode.addNode( new SimpleNode( "nextPage", metaData.getPager().getNextPage() ) );
+ pagerNode.addNode( new SimpleNode( "prevPage", metaData.getPager().getPrevPage() ) );
+ }
+
+ rootNode.addNode( filterService.filterProperties( getEntityClass(), entityList, include, exclude ) );
+
+ nodeService.serialize( rootNode, "application/json", response.getOutputStream() );
}
else
{