dhis2-devs team mailing list archive
-
dhis2-devs team
-
Mailing list archive
-
Message #30937
[Branch ~dhis2-devs-core/dhis2/trunk] Rev 15727: change default for serializer to include all objects (even null objects), add new class for inclu...
------------------------------------------------------------
revno: 15727
committer: Morten Olav Hansen <mortenoh@xxxxxxxxx>
branch nick: dhis2
timestamp: Tue 2014-06-17 16:06:57 +0200
message:
change default for serializer to include all objects (even null objects), add new class for inclusion strategy (not in use yet)
added:
dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/config/
dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/config/Config.java
dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/config/InclusionStrategy.java
dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/config/Inclusions.java
modified:
dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/serializers/Jackson2JsonNodeSerializer.java
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/types/RootNode.java
dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/filter/DefaultFilterService.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
=== added directory 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/config'
=== added file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/config/Config.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/config/Config.java 1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/config/Config.java 2014-06-17 14:06:57 +0000
@@ -0,0 +1,56 @@
+package org.hisp.dhis.node.config;
+
+/*
+ * Copyright (c) 2004-2014, 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
+ */
+
+/**
+ * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
+ */
+public class Config
+{
+ /**
+ * Inclusion strategy to use. There are a few already defined inclusions in the Inclusions enum.
+ *
+ * @see org.hisp.dhis.node.config.Inclusions
+ */
+ private InclusionStrategy inclusionStrategy = Inclusions.ALWAYS;
+
+ public Config()
+ {
+ }
+
+ public InclusionStrategy getInclusionStrategy()
+ {
+ return inclusionStrategy;
+ }
+
+ public void setInclusionStrategy( InclusionStrategy inclusionStrategy )
+ {
+ this.inclusionStrategy = inclusionStrategy;
+ }
+}
=== added file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/config/InclusionStrategy.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/config/InclusionStrategy.java 1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/config/InclusionStrategy.java 2014-06-17 14:06:57 +0000
@@ -0,0 +1,37 @@
+package org.hisp.dhis.node.config;
+
+/*
+ * Copyright (c) 2004-2014, 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
+ */
+
+/**
+ * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
+ */
+public interface InclusionStrategy
+{
+ <T> boolean include( T object );
+}
=== added file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/config/Inclusions.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/config/Inclusions.java 1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/config/Inclusions.java 2014-06-17 14:06:57 +0000
@@ -0,0 +1,43 @@
+package org.hisp.dhis.node.config;
+
+/*
+ * Copyright (c) 2004-2014, 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
+ */
+
+/**
+ * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
+ */
+public enum Inclusions implements InclusionStrategy
+{
+ ALWAYS;
+
+ @Override
+ public <T> boolean include( T object )
+ {
+ return true;
+ }
+}
=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/serializers/Jackson2JsonNodeSerializer.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/serializers/Jackson2JsonNodeSerializer.java 2014-06-13 06:47:27 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/serializers/Jackson2JsonNodeSerializer.java 2014-06-17 14:06:57 +0000
@@ -28,7 +28,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
*/
-import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
@@ -49,7 +48,7 @@
* @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
*/
@Component
-@Scope( value = "prototype", proxyMode = ScopedProxyMode.INTERFACES )
+@Scope(value = "prototype", proxyMode = ScopedProxyMode.INTERFACES)
public class Jackson2JsonNodeSerializer extends AbstractNodeSerializer
{
public static final String CONTENT_TYPE = "application/json";
@@ -58,14 +57,13 @@
static
{
- 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.WRITE_EMPTY_JSON_ARRAYS, true );
objectMapper.configure( SerializationFeature.WRAP_EXCEPTIONS, true );
objectMapper.getFactory().enable( JsonGenerator.Feature.QUOTE_FIELD_NAMES );
}
- private JsonGenerator generator;
+ private JsonGenerator generator = null;
@Override
public List<String> contentTypes()
@@ -86,12 +84,6 @@
}
@Override
- protected void endSerialize( RootNode rootNode, OutputStream outputStream ) throws Exception
- {
- generator = null;
- }
-
- @Override
protected void startWriteRootNode( RootNode rootNode ) throws Exception
{
//generator.writeRaw( "callback(" );
@@ -108,11 +100,6 @@
@Override
protected void startWriteSimpleNode( SimpleNode simpleNode ) throws Exception
{
- if ( simpleNode.getValue() == null ) // add hint for this, exclude if null
- {
- return;
- }
-
if ( simpleNode.getParent().isCollection() )
{
generator.writeObject( 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-08 11:06:30 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/serializers/StAXNodeSerializer.java 2014-06-17 14:06:57 +0000
@@ -50,20 +50,20 @@
* @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
*/
@Component
-@Scope( value = "prototype", proxyMode = ScopedProxyMode.INTERFACES )
+@Scope(value = "prototype", proxyMode = ScopedProxyMode.INTERFACES)
public class StAXNodeSerializer extends AbstractNodeSerializer
{
public static final String CONTENT_TYPE = "application/xml";
private static final XMLOutputFactory xmlFactory = XMLOutputFactory.newInstance();
- private XMLStreamWriter writer;
-
static
{
xmlFactory.setProperty( "javax.xml.stream.isRepairingNamespaces", true );
}
+ private XMLStreamWriter writer;
+
@Override
public List<String> contentTypes()
{
@@ -106,11 +106,6 @@
@Override
protected void startWriteSimpleNode( SimpleNode simpleNode ) throws Exception
{
- if ( simpleNode.getValue() == null ) // TODO include null or not?
- {
- return;
- }
-
String value = String.format( "%s", simpleNode.getValue() );
if ( simpleNode.isAttribute() )
@@ -134,7 +129,7 @@
@Override
protected void endWriteSimpleNode( SimpleNode simpleNode ) throws Exception
{
- if ( !simpleNode.isAttribute() && simpleNode.getValue() != null )
+ if ( !simpleNode.isAttribute() )
{
writer.writeEndElement();
}
=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/types/RootNode.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/types/RootNode.java 2014-06-13 06:47:27 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/types/RootNode.java 2014-06-17 14:06:57 +0000
@@ -29,6 +29,7 @@
*/
import org.hisp.dhis.node.Node;
+import org.hisp.dhis.node.config.Config;
/**
* @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
@@ -37,6 +38,8 @@
{
private String defaultNamespace;
+ private final Config config = new Config();
+
public RootNode( String name )
{
super( name );
@@ -59,4 +62,9 @@
{
this.defaultNamespace = defaultNamespace;
}
+
+ public Config getConfig()
+ {
+ return config;
+ }
}
=== 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-11 09:59:34 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/filter/DefaultFilterService.java 2014-06-17 14:06:57 +0000
@@ -92,11 +92,6 @@
public <T extends IdentifiableObject> CollectionNode fieldFilter( Class<?> klass, List<T> objects,
List<String> fieldList )
{
- if ( objects.isEmpty() )
- {
- return null;
- }
-
String fields = fieldList == null ? "" : Joiner.on( "," ).join( fieldList );
Schema rootSchema = schemaService.getDynamicSchema( klass );
@@ -126,24 +121,25 @@
for ( Object object : objects )
{
- collectionNode.addChild( buildObjectOutput( fieldMap, object ) );
+ collectionNode.addChild( buildObjectOutput( fieldMap, klass, object ) );
}
return collectionNode;
}
- @SuppressWarnings("unchecked")
- private ComplexNode buildObjectOutput( Map<String, Map> fieldMap, Object object )
+ @SuppressWarnings( "unchecked" )
+ private ComplexNode buildObjectOutput( Map<String, Map> fieldMap, Class<?> klass, Object object )
{
- if ( object == null )
- {
- return null;
- }
+ Schema schema = schemaService.getDynamicSchema( klass );
- Schema schema = schemaService.getDynamicSchema( object.getClass() );
ComplexNode complexNode = new ComplexNode( schema.getName() );
complexNode.setNamespace( schema.getNamespace() );
+ if ( object == null )
+ {
+ return complexNode;
+ }
+
updateFields( fieldMap, schema.getKlass() );
for ( String fieldKey : fieldMap.keySet() )
@@ -157,12 +153,6 @@
Object returnValue = ReflectionUtils.invokeMethod( object, property.getGetterMethod() );
Schema propertySchema = schemaService.getDynamicSchema( property.getKlass() );
- // TODO should we include nulls?
- if ( returnValue == null )
- {
- continue;
- }
-
Map fieldValue = fieldMap.get( fieldKey );
if ( property.isCollection() )
@@ -189,7 +179,7 @@
{
for ( Object collectionObject : collection )
{
- collectionNode.addChild( getProperties( collectionObject, fields ) );
+ collectionNode.addChild( getProperties( property.getItemKlass(), collectionObject, fields ) );
}
}
else if ( !property.isSimple() )
@@ -198,7 +188,7 @@
for ( Object collectionObject : collection )
{
- ComplexNode node = buildObjectOutput( map, collectionObject );
+ ComplexNode node = buildObjectOutput( map, property.getItemKlass(), collectionObject );
if ( !node.getChildren().isEmpty() )
{
@@ -216,7 +206,7 @@
}
else if ( property.isIdentifiableObject() )
{
- complexNode.addChild( getProperties( returnValue, fields ) );
+ complexNode.addChild( getProperties( property.getKlass(), returnValue, fields ) );
}
else
{
@@ -230,7 +220,8 @@
}
else
{
- complexNode.addChild( buildObjectOutput( getFullFieldMap( propertySchema ), returnValue ) );
+ complexNode.addChild( buildObjectOutput( getFullFieldMap( propertySchema ), property.getKlass(),
+ returnValue ) );
}
}
}
@@ -243,7 +234,7 @@
for ( Object collectionObject : (Collection<?>) returnValue )
{
- ComplexNode node = buildObjectOutput( fieldValue, collectionObject );
+ ComplexNode node = buildObjectOutput( fieldValue, property.getItemKlass(), collectionObject );
if ( !node.getChildren().isEmpty() )
{
@@ -253,7 +244,7 @@
}
else
{
- ComplexNode node = buildObjectOutput( fieldValue, returnValue );
+ ComplexNode node = buildObjectOutput( fieldValue, property.getKlass(), returnValue );
if ( !node.getChildren().isEmpty() )
{
@@ -340,18 +331,18 @@
return map;
}
- private ComplexNode getProperties( Object object, List<String> fields )
+ private ComplexNode getProperties( Class<?> klass, Object object, List<String> fields )
{
- if ( object == null )
- {
- return null;
- }
-
- Schema schema = schemaService.getDynamicSchema( object.getClass() );
+ Schema schema = schemaService.getDynamicSchema( klass );
ComplexNode complexNode = new ComplexNode( schema.getSingular() );
complexNode.setNamespace( schema.getNamespace() );
+ if ( object == null )
+ {
+ return complexNode;
+ }
+
for ( String field : fields )
{
Property property = schema.getPropertyMap().get( field );
@@ -363,20 +354,17 @@
Object o = ReflectionUtils.invokeMethod( object, property.getGetterMethod() );
- if ( o != null )
- {
- SimpleNode simpleNode = new SimpleNode( field, o );
- simpleNode.setAttribute( property.isAttribute() );
- simpleNode.setNamespace( property.getNamespace() );
+ SimpleNode simpleNode = new SimpleNode( field, o );
+ simpleNode.setAttribute( property.isAttribute() );
+ simpleNode.setNamespace( property.getNamespace() );
- complexNode.addChild( simpleNode );
- }
+ complexNode.addChild( simpleNode );
}
return complexNode;
}
- @SuppressWarnings("unchecked")
+ @SuppressWarnings( "unchecked" )
private <T> boolean evaluateWithFilters( T object, Filters filters )
{
Schema schema = schemaService.getDynamicSchema( object.getClass() );
=== 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-17 10:29:40 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/AbstractCrudController.java 2014-06-17 14:06:57 +0000
@@ -46,6 +46,7 @@
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.config.Inclusions;
import org.hisp.dhis.node.types.CollectionNode;
import org.hisp.dhis.node.types.ComplexNode;
import org.hisp.dhis.node.types.RootNode;