← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 15733: split filterService into fieldFilterService and objectFilterService

 

------------------------------------------------------------
revno: 15733
committer: Morten Olav Hansen <mortenoh@xxxxxxxxx>
branch nick: dhis2
timestamp: Tue 2014-06-17 17:28:24 +0200
message:
  split filterService into fieldFilterService and objectFilterService
removed:
  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
added:
  dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/filter/DefaultFieldFilterService.java
  dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/filter/DefaultObjectFilterService.java
  dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/filter/FieldFilterService.java
  dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/filter/ObjectFilterService.java
modified:
  dhis-2/dhis-services/dhis-service-dxf2/src/main/resources/META-INF/dhis/beans.xml
  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 file 'dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/filter/DefaultFieldFilterService.java'
--- dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/filter/DefaultFieldFilterService.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/filter/DefaultFieldFilterService.java	2014-06-17 15:28:24 +0000
@@ -0,0 +1,352 @@
+package org.hisp.dhis.dxf2.filter;
+
+/*
+ * 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
+ */
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import org.hisp.dhis.common.IdentifiableObject;
+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;
+import org.hisp.dhis.system.util.ReflectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
+ */
+public class DefaultFieldFilterService implements FieldFilterService
+{
+    static final ImmutableMap<String, List<String>> FIELD_PRESETS = ImmutableMap.<String, List<String>>builder()
+        .put( "all", Lists.newArrayList( "*" ) )
+        .put( "identifiable", Lists.newArrayList( "id", "name", "code", "created", "lastUpdated", "href" ) )
+        .put( "nameable", Lists.newArrayList( "id", "name", "shortName", "description", "code", "created", "lastUpdated", "href" ) )
+        .build();
+
+    @Autowired
+    private ParserService parserService;
+
+    @Autowired
+    private SchemaService schemaService;
+
+    @Override
+    public <T extends IdentifiableObject> CollectionNode filter( Class<?> klass, List<T> objects, List<String> fieldList )
+    {
+        if ( objects == null )
+        {
+            return null;
+        }
+
+        String fields = fieldList == null ? "" : Joiner.on( "," ).join( fieldList );
+
+        Schema rootSchema = schemaService.getDynamicSchema( klass );
+
+        Map<String, Map> fieldMap = Maps.newHashMap();
+        Schema schema = schemaService.getDynamicSchema( objects.get( 0 ).getClass() );
+
+        if ( fields == null )
+        {
+            for ( Property property : schema.getProperties() )
+            {
+                fieldMap.put( property.getName(), Maps.newHashMap() );
+            }
+        }
+        else
+        {
+            fieldMap = parserService.parsePropertyFilter( fields );
+        }
+
+        CollectionNode collectionNode = new CollectionNode( rootSchema.getCollectionName() );
+        collectionNode.setNamespace( rootSchema.getNamespace() );
+
+        for ( Object object : objects )
+        {
+            collectionNode.addChild( buildComplexNode( fieldMap, klass, object ) );
+        }
+
+        return collectionNode;
+    }
+
+    @SuppressWarnings( "unchecked" )
+    private ComplexNode buildComplexNode( Map<String, Map> fieldMap, Class<?> klass, Object object )
+    {
+        Schema schema = schemaService.getDynamicSchema( klass );
+
+        ComplexNode complexNode = new ComplexNode( schema.getName() );
+        complexNode.setNamespace( schema.getNamespace() );
+
+        if ( object == null )
+        {
+            return complexNode;
+        }
+
+        updateFields( fieldMap, schema.getKlass() );
+
+        for ( String fieldKey : fieldMap.keySet() )
+        {
+            if ( !schema.getPropertyMap().containsKey( fieldKey ) )
+            {
+                continue;
+            }
+
+            Property property = schema.getPropertyMap().get( fieldKey );
+
+            Object returnValue = ReflectionUtils.invokeMethod( object, property.getGetterMethod() );
+            Schema propertySchema = schemaService.getDynamicSchema( property.getKlass() );
+
+            Map fieldValue = fieldMap.get( fieldKey );
+
+            if ( property.isCollection() )
+            {
+                updateFields( fieldValue, property.getItemKlass() );
+            }
+            else
+            {
+                updateFields( fieldValue, property.getKlass() );
+            }
+
+            if ( fieldValue.isEmpty() )
+            {
+                List<String> fields = FIELD_PRESETS.get( "identifiable" );
+
+                if ( property.isCollection() )
+                {
+                    Collection<?> collection = (Collection<?>) returnValue;
+
+                    CollectionNode collectionNode = complexNode.addChild( new CollectionNode( property.getCollectionName() ) );
+                    collectionNode.setNamespace( property.getNamespace() );
+
+                    if ( property.isIdentifiableObject() )
+                    {
+                        for ( Object collectionObject : collection )
+                        {
+                            collectionNode.addChild( getProperties( property, collectionObject, fields ) );
+                        }
+                    }
+                    else if ( !property.isSimple() )
+                    {
+                        Map<String, Map> map = getFullFieldMap( schemaService.getDynamicSchema( property.getItemKlass() ) );
+
+                        for ( Object collectionObject : collection )
+                        {
+                            ComplexNode node = buildComplexNode( map, property.getItemKlass(), collectionObject );
+
+                            if ( !node.getChildren().isEmpty() )
+                            {
+                                collectionNode.addChild( node );
+                            }
+                        }
+                    }
+                    else
+                    {
+                        for ( Object collectionObject : collection )
+                        {
+                            collectionNode.addChild( new SimpleNode( property.getName(), collectionObject ) );
+                        }
+                    }
+                }
+                else if ( property.isIdentifiableObject() )
+                {
+                    complexNode.addChild( getProperties( property, returnValue, fields ) );
+                }
+                else
+                {
+                    if ( propertySchema.getProperties().isEmpty() )
+                    {
+                        SimpleNode simpleNode = new SimpleNode( fieldKey, returnValue );
+                        simpleNode.setAttribute( property.isAttribute() );
+                        simpleNode.setNamespace( property.getNamespace() );
+
+                        complexNode.addChild( simpleNode );
+                    }
+                    else
+                    {
+                        complexNode.addChild( buildComplexNode( getFullFieldMap( propertySchema ), property.getKlass(),
+                            returnValue ) );
+                    }
+                }
+            }
+            else
+            {
+                if ( property.isCollection() )
+                {
+                    CollectionNode collectionNode = complexNode.addChild( new CollectionNode( property.getCollectionName() ) );
+                    collectionNode.setNamespace( property.getNamespace() );
+
+                    for ( Object collectionObject : (Collection<?>) returnValue )
+                    {
+                        ComplexNode node = buildComplexNode( fieldValue, property.getItemKlass(), collectionObject );
+
+                        if ( !node.getChildren().isEmpty() )
+                        {
+                            collectionNode.addChild( node );
+                        }
+                    }
+                }
+                else
+                {
+                    ComplexNode node = buildComplexNode( fieldValue, property.getKlass(), returnValue );
+
+                    if ( !node.getChildren().isEmpty() )
+                    {
+                        complexNode.addChild( node );
+                    }
+                }
+            }
+        }
+
+        return complexNode;
+    }
+
+    private void updateFields( Map<String, Map> fieldMap, Class<?> klass )
+    {
+        // we need two run this (at least) two times, since some of the presets might contain other presets
+        _updateFields( fieldMap, klass, true );
+        _updateFields( fieldMap, klass, false );
+    }
+
+    private void _updateFields( Map<String, Map> fieldMap, Class<?> klass, boolean expandOnly )
+    {
+        Schema schema = schemaService.getDynamicSchema( klass );
+        List<String> cleanupFields = Lists.newArrayList();
+
+        for ( String fieldKey : Sets.newHashSet( fieldMap.keySet() ) )
+        {
+            if ( "*".equals( fieldKey ) )
+            {
+                for ( String mapKey : schema.getPropertyMap().keySet() )
+                {
+                    if ( !fieldMap.containsKey( mapKey ) )
+                    {
+                        fieldMap.put( mapKey, Maps.newHashMap() );
+                    }
+                }
+
+                cleanupFields.add( fieldKey );
+            }
+            else if ( fieldKey.startsWith( ":" ) )
+            {
+                List<String> fields = FIELD_PRESETS.get( fieldKey.substring( 1 ) );
+
+                if ( fields == null )
+                {
+                    continue;
+                }
+
+                for ( String field : fields )
+                {
+                    if ( !fieldMap.containsKey( field ) )
+                    {
+                        fieldMap.put( field, Maps.newHashMap() );
+                    }
+                }
+
+                cleanupFields.add( fieldKey );
+            }
+            else if ( fieldKey.startsWith( "!" ) && !expandOnly )
+            {
+                cleanupFields.add( fieldKey );
+            }
+        }
+
+        for ( String field : cleanupFields )
+        {
+            fieldMap.remove( field );
+
+            if ( !expandOnly )
+            {
+                fieldMap.remove( field.substring( 1 ) );
+            }
+        }
+    }
+
+    private Map<String, Map> getFullFieldMap( Schema schema )
+    {
+        Map<String, Map> map = Maps.newHashMap();
+
+        for ( String mapKey : schema.getPropertyMap().keySet() )
+        {
+            map.put( mapKey, Maps.newHashMap() );
+        }
+
+        return map;
+    }
+
+    private ComplexNode getProperties( Property currentProperty, Object object, List<String> fields )
+    {
+        if ( object == null )
+        {
+            return null;
+        }
+
+        ComplexNode complexNode = new ComplexNode( currentProperty.getName() );
+        complexNode.setNamespace( currentProperty.getNamespace() );
+
+        Schema schema;
+
+        if ( currentProperty.isCollection() )
+        {
+            schema = schemaService.getDynamicSchema( currentProperty.getItemKlass() );
+
+        }
+        else
+        {
+            schema = schemaService.getDynamicSchema( currentProperty.getKlass() );
+        }
+
+        for ( String field : fields )
+        {
+            Property property = schema.getPropertyMap().get( field );
+
+            if ( property == null )
+            {
+                continue;
+            }
+
+            Object returnValue = ReflectionUtils.invokeMethod( object, property.getGetterMethod() );
+
+            SimpleNode simpleNode = new SimpleNode( field, returnValue );
+            simpleNode.setAttribute( property.isAttribute() );
+            simpleNode.setNamespace( property.getNamespace() );
+
+            complexNode.addChild( simpleNode );
+        }
+
+        return complexNode;
+    }
+}

=== removed 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-17 15:16:25 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/filter/DefaultFilterService.java	1970-01-01 00:00:00 +0000
@@ -1,489 +0,0 @@
-package org.hisp.dhis.dxf2.filter;
-
-/*
- * 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.
- */
-
-import com.google.common.base.Joiner;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-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;
-import org.hisp.dhis.system.util.ReflectionUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-/**
- * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
- */
-public class DefaultFilterService implements FilterService
-{
-    static final ImmutableMap<String, List<String>> FIELD_PRESETS = ImmutableMap.<String, List<String>>builder()
-        .put( "all", Lists.newArrayList( "*" ) )
-        .put( "identifiable", Lists.newArrayList( "id", "name", "code", "created", "lastUpdated", "href" ) )
-        .put( "nameable", Lists.newArrayList( "id", "name", "shortName", "description", "code", "created", "lastUpdated", "href" ) )
-        .build();
-
-    @Autowired
-    private ParserService parserService;
-
-    @Autowired
-    private SchemaService schemaService;
-
-    @Override
-    public <T extends IdentifiableObject> List<T> objectFilter( List<T> objects, List<String> filters )
-    {
-        if ( objects == null || objects.isEmpty() )
-        {
-            return Lists.newArrayList();
-        }
-
-        Filters parsed = parserService.parseObjectFilter( filters );
-
-        List<T> list = Lists.newArrayList();
-
-        for ( T object : objects )
-        {
-            if ( evaluateWithFilters( object, parsed ) )
-            {
-                list.add( object );
-            }
-        }
-
-        return list;
-    }
-
-    @Override
-    public <T extends IdentifiableObject> CollectionNode fieldFilter( Class<?> klass, List<T> objects,
-        List<String> fieldList )
-    {
-        if ( objects == null )
-        {
-            return null;
-        }
-
-        String fields = fieldList == null ? "" : Joiner.on( "," ).join( fieldList );
-
-        Schema rootSchema = schemaService.getDynamicSchema( klass );
-
-        Map<String, Map> fieldMap = Maps.newHashMap();
-        Schema schema = schemaService.getDynamicSchema( objects.get( 0 ).getClass() );
-
-        if ( fields == null )
-        {
-            for ( Property property : schema.getProperties() )
-            {
-                fieldMap.put( property.getName(), Maps.newHashMap() );
-            }
-        }
-        else
-        {
-            fieldMap = parserService.parsePropertyFilter( fields );
-        }
-
-        CollectionNode collectionNode = new CollectionNode( rootSchema.getCollectionName() );
-        collectionNode.setNamespace( rootSchema.getNamespace() );
-
-        for ( Object object : objects )
-        {
-            collectionNode.addChild( buildComplexNode( fieldMap, klass, object ) );
-        }
-
-        return collectionNode;
-    }
-
-    @SuppressWarnings( "unchecked" )
-    private ComplexNode buildComplexNode( Map<String, Map> fieldMap, Class<?> klass, Object object )
-    {
-        Schema schema = schemaService.getDynamicSchema( klass );
-
-        ComplexNode complexNode = new ComplexNode( schema.getName() );
-        complexNode.setNamespace( schema.getNamespace() );
-
-        if ( object == null )
-        {
-            return complexNode;
-        }
-
-        updateFields( fieldMap, schema.getKlass() );
-
-        for ( String fieldKey : fieldMap.keySet() )
-        {
-            if ( !schema.getPropertyMap().containsKey( fieldKey ) )
-            {
-                continue;
-            }
-
-            Property property = schema.getPropertyMap().get( fieldKey );
-
-            Object returnValue = ReflectionUtils.invokeMethod( object, property.getGetterMethod() );
-            Schema propertySchema = schemaService.getDynamicSchema( property.getKlass() );
-
-            Map fieldValue = fieldMap.get( fieldKey );
-
-            if ( property.isCollection() )
-            {
-                updateFields( fieldValue, property.getItemKlass() );
-            }
-            else
-            {
-                updateFields( fieldValue, property.getKlass() );
-            }
-
-            if ( fieldValue.isEmpty() )
-            {
-                List<String> fields = FIELD_PRESETS.get( "identifiable" );
-
-                if ( property.isCollection() )
-                {
-                    Collection<?> collection = (Collection<?>) returnValue;
-
-                    CollectionNode collectionNode = complexNode.addChild( new CollectionNode( property.getCollectionName() ) );
-                    collectionNode.setNamespace( property.getNamespace() );
-
-                    if ( property.isIdentifiableObject() )
-                    {
-                        for ( Object collectionObject : collection )
-                        {
-                            collectionNode.addChild( getProperties( property, collectionObject, fields ) );
-                        }
-                    }
-                    else if ( !property.isSimple() )
-                    {
-                        Map<String, Map> map = getFullFieldMap( schemaService.getDynamicSchema( property.getItemKlass() ) );
-
-                        for ( Object collectionObject : collection )
-                        {
-                            ComplexNode node = buildComplexNode( map, property.getItemKlass(), collectionObject );
-
-                            if ( !node.getChildren().isEmpty() )
-                            {
-                                collectionNode.addChild( node );
-                            }
-                        }
-                    }
-                    else
-                    {
-                        for ( Object collectionObject : collection )
-                        {
-                            collectionNode.addChild( new SimpleNode( property.getName(), collectionObject ) );
-                        }
-                    }
-                }
-                else if ( property.isIdentifiableObject() )
-                {
-                    complexNode.addChild( getProperties( property, returnValue, fields ) );
-                }
-                else
-                {
-                    if ( propertySchema.getProperties().isEmpty() )
-                    {
-                        SimpleNode simpleNode = new SimpleNode( fieldKey, returnValue );
-                        simpleNode.setAttribute( property.isAttribute() );
-                        simpleNode.setNamespace( property.getNamespace() );
-
-                        complexNode.addChild( simpleNode );
-                    }
-                    else
-                    {
-                        complexNode.addChild( buildComplexNode( getFullFieldMap( propertySchema ), property.getKlass(),
-                            returnValue ) );
-                    }
-                }
-            }
-            else
-            {
-                if ( property.isCollection() )
-                {
-                    CollectionNode collectionNode = complexNode.addChild( new CollectionNode( property.getCollectionName() ) );
-                    collectionNode.setNamespace( property.getNamespace() );
-
-                    for ( Object collectionObject : (Collection<?>) returnValue )
-                    {
-                        ComplexNode node = buildComplexNode( fieldValue, property.getItemKlass(), collectionObject );
-
-                        if ( !node.getChildren().isEmpty() )
-                        {
-                            collectionNode.addChild( node );
-                        }
-                    }
-                }
-                else
-                {
-                    ComplexNode node = buildComplexNode( fieldValue, property.getKlass(), returnValue );
-
-                    if ( !node.getChildren().isEmpty() )
-                    {
-                        complexNode.addChild( node );
-                    }
-                }
-            }
-        }
-
-        return complexNode;
-    }
-
-    private void updateFields( Map<String, Map> fieldMap, Class<?> klass )
-    {
-        // we need two run this (at least) two times, since some of the presets might contain other presets
-        _updateFields( fieldMap, klass, true );
-        _updateFields( fieldMap, klass, false );
-    }
-
-    private void _updateFields( Map<String, Map> fieldMap, Class<?> klass, boolean expandOnly )
-    {
-        Schema schema = schemaService.getDynamicSchema( klass );
-        List<String> cleanupFields = Lists.newArrayList();
-
-        for ( String fieldKey : Sets.newHashSet( fieldMap.keySet() ) )
-        {
-            if ( "*".equals( fieldKey ) )
-            {
-                for ( String mapKey : schema.getPropertyMap().keySet() )
-                {
-                    if ( !fieldMap.containsKey( mapKey ) )
-                    {
-                        fieldMap.put( mapKey, Maps.newHashMap() );
-                    }
-                }
-
-                cleanupFields.add( fieldKey );
-            }
-            else if ( fieldKey.startsWith( ":" ) )
-            {
-                List<String> fields = FIELD_PRESETS.get( fieldKey.substring( 1 ) );
-
-                if ( fields == null )
-                {
-                    continue;
-                }
-
-                for ( String field : fields )
-                {
-                    if ( !fieldMap.containsKey( field ) )
-                    {
-                        fieldMap.put( field, Maps.newHashMap() );
-                    }
-                }
-
-                cleanupFields.add( fieldKey );
-            }
-            else if ( fieldKey.startsWith( "!" ) && !expandOnly )
-            {
-                cleanupFields.add( fieldKey );
-            }
-        }
-
-        for ( String field : cleanupFields )
-        {
-            fieldMap.remove( field );
-
-            if ( !expandOnly )
-            {
-                fieldMap.remove( field.substring( 1 ) );
-            }
-        }
-    }
-
-    private Map<String, Map> getFullFieldMap( Schema schema )
-    {
-        Map<String, Map> map = Maps.newHashMap();
-
-        for ( String mapKey : schema.getPropertyMap().keySet() )
-        {
-            map.put( mapKey, Maps.newHashMap() );
-        }
-
-        return map;
-    }
-
-    private ComplexNode getProperties( Property currentProperty, Object object, List<String> fields )
-    {
-        if ( object == null )
-        {
-            return null;
-        }
-
-        ComplexNode complexNode = new ComplexNode( currentProperty.getName() );
-        complexNode.setNamespace( currentProperty.getNamespace() );
-
-        Schema schema;
-
-        if ( currentProperty.isCollection() )
-        {
-            schema = schemaService.getDynamicSchema( currentProperty.getItemKlass() );
-
-        }
-        else
-        {
-            schema = schemaService.getDynamicSchema( currentProperty.getKlass() );
-        }
-
-        for ( String field : fields )
-        {
-            Property property = schema.getPropertyMap().get( field );
-
-            if ( property == null )
-            {
-                continue;
-            }
-
-            Object returnValue = ReflectionUtils.invokeMethod( object, property.getGetterMethod() );
-
-            SimpleNode simpleNode = new SimpleNode( field, returnValue );
-            simpleNode.setAttribute( property.isAttribute() );
-            simpleNode.setNamespace( property.getNamespace() );
-
-            complexNode.addChild( simpleNode );
-        }
-
-        return complexNode;
-    }
-
-    @SuppressWarnings( "unchecked" )
-    private <T> boolean evaluateWithFilters( T object, Filters filters )
-    {
-        Schema schema = schemaService.getDynamicSchema( object.getClass() );
-
-        for ( String field : filters.getFilters().keySet() )
-        {
-            if ( !schema.getPropertyMap().containsKey( field ) )
-            {
-                continue;
-            }
-
-            Property descriptor = schema.getPropertyMap().get( field );
-
-            if ( descriptor == null )
-            {
-                continue;
-            }
-
-            Object value = ReflectionUtils.invokeMethod( object, descriptor.getGetterMethod() );
-
-            Object filter = filters.getFilters().get( field );
-
-            if ( FilterOps.class.isInstance( filter ) )
-            {
-                if ( evaluateFilterOps( value, (FilterOps) filter ) )
-                {
-                    return false;
-                }
-            }
-            else
-            {
-                Map<String, Object> map = (Map<String, Object>) filters.getFilters().get( field );
-                Filters f = new Filters();
-                f.setFilters( map );
-
-                if ( map.containsKey( "__self__" ) )
-                {
-                    if ( evaluateFilterOps( value, (FilterOps) map.get( "__self__" ) ) )
-                    {
-                        return false;
-                    }
-
-                    map.remove( "__self__" );
-                }
-
-                if ( !descriptor.isCollection() )
-                {
-                    if ( !evaluateWithFilters( value, f ) )
-                    {
-                        return false;
-                    }
-                }
-                else
-                {
-                    Collection<?> objectCollection = (Collection<?>) value;
-
-                    if ( objectCollection.isEmpty() )
-                    {
-                        return false;
-                    }
-
-                    boolean include = false;
-
-                    for ( Object idObject : objectCollection )
-                    {
-                        if ( evaluateWithFilters( idObject, f ) )
-                        {
-                            include = true;
-                        }
-                    }
-
-                    if ( !include )
-                    {
-                        return false;
-                    }
-                }
-            }
-        }
-
-        return true;
-    }
-
-    private boolean evaluateFilterOps( Object value, FilterOps filterOps )
-    {
-        // filter through every operator treating multiple of same operator as OR
-        for ( String operator : filterOps.getFilters().keySet() )
-        {
-            boolean include = false;
-
-            List<Op> ops = filterOps.getFilters().get( operator );
-
-            for ( Op op : ops )
-            {
-                switch ( op.evaluate( value ) )
-                {
-                    case INCLUDE:
-                    {
-                        include = true;
-                    }
-                }
-            }
-
-            if ( !include )
-            {
-                return true;
-            }
-        }
-
-        return false;
-    }
-}

=== added file 'dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/filter/DefaultObjectFilterService.java'
--- dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/filter/DefaultObjectFilterService.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/filter/DefaultObjectFilterService.java	2014-06-17 15:28:24 +0000
@@ -0,0 +1,189 @@
+package org.hisp.dhis.dxf2.filter;
+
+/*
+ * 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.
+ */
+
+import com.google.common.collect.Lists;
+import org.hisp.dhis.common.IdentifiableObject;
+import org.hisp.dhis.dxf2.filter.ops.Op;
+import org.hisp.dhis.schema.Property;
+import org.hisp.dhis.schema.Schema;
+import org.hisp.dhis.schema.SchemaService;
+import org.hisp.dhis.system.util.ReflectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
+ */
+public class DefaultObjectFilterService implements ObjectFilterService
+{
+    @Autowired
+    private ParserService parserService;
+
+    @Autowired
+    private SchemaService schemaService;
+
+    @Override
+    public <T extends IdentifiableObject> List<T> filter( List<T> objects, List<String> filters )
+    {
+        if ( objects == null || objects.isEmpty() )
+        {
+            return Lists.newArrayList();
+        }
+
+        Filters parsed = parserService.parseObjectFilter( filters );
+
+        List<T> list = Lists.newArrayList();
+
+        for ( T object : objects )
+        {
+            if ( evaluateWithFilters( object, parsed ) )
+            {
+                list.add( object );
+            }
+        }
+
+        return list;
+    }
+
+    @SuppressWarnings( "unchecked" )
+    private <T> boolean evaluateWithFilters( T object, Filters filters )
+    {
+        Schema schema = schemaService.getDynamicSchema( object.getClass() );
+
+        for ( String field : filters.getFilters().keySet() )
+        {
+            if ( !schema.getPropertyMap().containsKey( field ) )
+            {
+                continue;
+            }
+
+            Property descriptor = schema.getPropertyMap().get( field );
+
+            if ( descriptor == null )
+            {
+                continue;
+            }
+
+            Object value = ReflectionUtils.invokeMethod( object, descriptor.getGetterMethod() );
+
+            Object filter = filters.getFilters().get( field );
+
+            if ( FilterOps.class.isInstance( filter ) )
+            {
+                if ( evaluateFilterOps( value, (FilterOps) filter ) )
+                {
+                    return false;
+                }
+            }
+            else
+            {
+                Map<String, Object> map = (Map<String, Object>) filters.getFilters().get( field );
+                Filters f = new Filters();
+                f.setFilters( map );
+
+                if ( map.containsKey( "__self__" ) )
+                {
+                    if ( evaluateFilterOps( value, (FilterOps) map.get( "__self__" ) ) )
+                    {
+                        return false;
+                    }
+
+                    map.remove( "__self__" );
+                }
+
+                if ( !descriptor.isCollection() )
+                {
+                    if ( !evaluateWithFilters( value, f ) )
+                    {
+                        return false;
+                    }
+                }
+                else
+                {
+                    Collection<?> objectCollection = (Collection<?>) value;
+
+                    if ( objectCollection.isEmpty() )
+                    {
+                        return false;
+                    }
+
+                    boolean include = false;
+
+                    for ( Object idObject : objectCollection )
+                    {
+                        if ( evaluateWithFilters( idObject, f ) )
+                        {
+                            include = true;
+                        }
+                    }
+
+                    if ( !include )
+                    {
+                        return false;
+                    }
+                }
+            }
+        }
+
+        return true;
+    }
+
+    private boolean evaluateFilterOps( Object value, FilterOps filterOps )
+    {
+        // filter through every operator treating multiple of same operator as OR
+        for ( String operator : filterOps.getFilters().keySet() )
+        {
+            boolean include = false;
+
+            List<Op> ops = filterOps.getFilters().get( operator );
+
+            for ( Op op : ops )
+            {
+                switch ( op.evaluate( value ) )
+                {
+                    case INCLUDE:
+                    {
+                        include = true;
+                    }
+                }
+            }
+
+            if ( !include )
+            {
+                return true;
+            }
+        }
+
+        return false;
+    }
+}

=== added file 'dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/filter/FieldFilterService.java'
--- dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/filter/FieldFilterService.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/filter/FieldFilterService.java	2014-06-17 15:28:24 +0000
@@ -0,0 +1,49 @@
+package org.hisp.dhis.dxf2.filter;
+
+/*
+ * 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
+ */
+
+import org.hisp.dhis.common.IdentifiableObject;
+import org.hisp.dhis.node.types.CollectionNode;
+
+import java.util.List;
+
+/**
+ * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
+ */
+public interface FieldFilterService
+{
+    /**
+     * Perform inclusion/exclusion on a list of objects.
+     *
+     * @param objects   List to filter
+     * @param fieldList Field filter
+     * @return List of objects with only wanted properties
+     */
+    <T extends IdentifiableObject> CollectionNode filter( Class<?> klass, List<T> objects, List<String> fieldList );
+}

=== removed 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-06-17 15:16:25 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/filter/FilterService.java	1970-01-01 00:00:00 +0000
@@ -1,58 +0,0 @@
-package org.hisp.dhis.dxf2.filter;
-
-/*
- * 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.
- */
-
-import org.hisp.dhis.common.IdentifiableObject;
-import org.hisp.dhis.node.types.CollectionNode;
-
-import java.util.List;
-
-/**
- * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
- */
-public interface FilterService
-{
-    /**
-     * Filter a list of objects based on un-parsed filter string.
-     *
-     * @param objects List to filter
-     * @param filters Filter string
-     * @return Filtered object list
-     */
-    <T extends IdentifiableObject> List<T> objectFilter( List<T> objects, List<String> filters );
-
-    /**
-     * Perform inclusion/exclusion on a list of objects.
-     *
-     * @param objects   List to filter
-     * @param fieldList Field filter
-     * @return List of objects with only wanted properties
-     */
-    <T extends IdentifiableObject> CollectionNode fieldFilter( Class<?> klass, List<T> objects, List<String> fieldList );
-}

=== added file 'dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/filter/ObjectFilterService.java'
--- dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/filter/ObjectFilterService.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/filter/ObjectFilterService.java	2014-06-17 15:28:24 +0000
@@ -0,0 +1,49 @@
+package org.hisp.dhis.dxf2.filter;
+
+/*
+ * 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.
+ */
+
+import org.hisp.dhis.common.IdentifiableObject;
+
+import java.util.List;
+
+/**
+ * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
+ */
+public interface ObjectFilterService
+{
+    /**
+     * Filter a list of objects based on un-parsed filter string.
+     * In-memory filter
+     *
+     * @param objects List to filter
+     * @param filters Filter string
+     * @return Filtered object list
+     */
+    <T extends IdentifiableObject> List<T> filter( List<T> objects, List<String> filters );
+}

=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/main/resources/META-INF/dhis/beans.xml'
--- dhis-2/dhis-services/dhis-service-dxf2/src/main/resources/META-INF/dhis/beans.xml	2014-05-28 19:02:46 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/main/resources/META-INF/dhis/beans.xml	2014-06-17 15:28:24 +0000
@@ -5,7 +5,9 @@
 
   <bean id="org.hisp.dhis.dxf2.render.RenderService" class="org.hisp.dhis.dxf2.render.DefaultRenderService" />
 
-  <bean id="org.hisp.dhis.dxf2.filter.FilterService" class="org.hisp.dhis.dxf2.filter.DefaultFilterService" />
+  <bean id="org.hisp.dhis.dxf2.filter.ObjectFilterService" class="org.hisp.dhis.dxf2.filter.DefaultObjectFilterService" />
+
+  <bean id="org.hisp.dhis.dxf2.filter.FieldFilterService" class="org.hisp.dhis.dxf2.filter.DefaultFieldFilterService" />
 
   <bean id="org.hisp.dhis.dxf2.filter.ParserService" class="org.hisp.dhis.dxf2.filter.DefaultParserService" />
 

=== 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 14:37:19 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/AbstractCrudController.java	2014-06-17 15:28:24 +0000
@@ -38,7 +38,8 @@
 import org.hisp.dhis.common.IdentifiableObjectManager;
 import org.hisp.dhis.common.Pager;
 import org.hisp.dhis.common.PagerUtils;
-import org.hisp.dhis.dxf2.filter.FilterService;
+import org.hisp.dhis.dxf2.filter.FieldFilterService;
+import org.hisp.dhis.dxf2.filter.ObjectFilterService;
 import org.hisp.dhis.dxf2.metadata.ImportService;
 import org.hisp.dhis.dxf2.metadata.ImportTypeSummary;
 import org.hisp.dhis.dxf2.render.RenderService;
@@ -95,7 +96,10 @@
     protected CurrentUserService currentUserService;
 
     @Autowired
-    protected FilterService filterService;
+    protected ObjectFilterService objectFilterService;
+
+    @Autowired
+    protected FieldFilterService fieldFilterService;
 
     @Autowired
     protected AclService aclService;
@@ -119,7 +123,7 @@
     // GET
     //--------------------------------------------------------------------------
 
-    @RequestMapping(method = RequestMethod.GET)
+    @RequestMapping( method = RequestMethod.GET )
     public @ResponseBody RootNode getObjectList(
         @RequestParam Map<String, String> parameters, HttpServletResponse response, HttpServletRequest request )
     {
@@ -154,7 +158,7 @@
         // enable object filter
         if ( !filters.isEmpty() )
         {
-            entityList = filterService.objectFilter( entityList, filters );
+            entityList = objectFilterService.filter( entityList, filters );
 
             if ( hasPaging )
             {
@@ -187,20 +191,20 @@
             pagerNode.addChild( new SimpleNode( "prevPage", pager.getPrevPage() ) );
         }
 
-        rootNode.addChild( filterService.fieldFilter( getEntityClass(), entityList, fields ) );
+        rootNode.addChild( fieldFilterService.filter( getEntityClass(), entityList, fields ) );
 
         return rootNode;
     }
 
-    @RequestMapping(value = "/{uid}/{property}", method = RequestMethod.GET)
-    public @ResponseBody RootNode getObjectProperty( @PathVariable("uid") String uid, @PathVariable("property") String property,
+    @RequestMapping( value = "/{uid}/{property}", method = RequestMethod.GET )
+    public @ResponseBody RootNode getObjectProperty( @PathVariable( "uid" ) String uid, @PathVariable( "property" ) String property,
         @RequestParam Map<String, String> parameters, HttpServletRequest request, HttpServletResponse response ) throws Exception
     {
         return getObjectInternal( uid, parameters, Lists.<String>newArrayList(), Lists.newArrayList( property ) );
     }
 
-    @RequestMapping(value = "/{uid}", method = RequestMethod.GET)
-    public @ResponseBody RootNode getObject( @PathVariable("uid") String uid, @RequestParam Map<String, String> parameters,
+    @RequestMapping( value = "/{uid}", method = RequestMethod.GET )
+    public @ResponseBody RootNode getObject( @PathVariable( "uid" ) String uid, @RequestParam Map<String, String> parameters,
         HttpServletRequest request, HttpServletResponse response ) throws Exception
     {
         List<String> fields = Lists.newArrayList( contextService.getParameterValues( "fields" ) );
@@ -225,7 +229,7 @@
             throw new NotFoundException( uid );
         }
 
-        entities = filterService.objectFilter( entities, filters );
+        entities = objectFilterService.filter( entities, filters );
 
         if ( options.hasLinks() )
         {
@@ -243,7 +247,7 @@
             postProcessEntity( entity, options, parameters );
         }
 
-        CollectionNode collectionNode = filterService.fieldFilter( getEntityClass(), entities, fields );
+        CollectionNode collectionNode = fieldFilterService.filter( getEntityClass(), entities, fields );
 
         if ( options.booleanTrue( "useWrapper" ) || entities.size() > 1 )
         {
@@ -268,7 +272,7 @@
     // POST
     //--------------------------------------------------------------------------
 
-    @RequestMapping(method = RequestMethod.POST, consumes = { "application/xml", "text/xml" })
+    @RequestMapping( method = RequestMethod.POST, consumes = { "application/xml", "text/xml" } )
     public void postXmlObject( HttpServletResponse response, HttpServletRequest request, InputStream input ) throws Exception
     {
         if ( !aclService.canCreate( currentUserService.getCurrentUser(), getEntityClass() ) )
@@ -281,7 +285,7 @@
         renderService.toXml( response.getOutputStream(), summary );
     }
 
-    @RequestMapping(method = RequestMethod.POST, consumes = "application/json")
+    @RequestMapping( method = RequestMethod.POST, consumes = "application/json" )
     public void postJsonObject( HttpServletResponse response, HttpServletRequest request, InputStream input ) throws Exception
     {
         if ( !aclService.canCreate( currentUserService.getCurrentUser(), getEntityClass() ) )
@@ -298,9 +302,9 @@
     // PUT
     //--------------------------------------------------------------------------
 
-    @RequestMapping(value = "/{uid}", method = RequestMethod.PUT, consumes = { MediaType.APPLICATION_XML_VALUE, MediaType.TEXT_XML_VALUE })
-    @ResponseStatus(value = HttpStatus.NO_CONTENT)
-    public void putXmlObject( HttpServletResponse response, HttpServletRequest request, @PathVariable("uid") String uid, InputStream
+    @RequestMapping( value = "/{uid}", method = RequestMethod.PUT, consumes = { MediaType.APPLICATION_XML_VALUE, MediaType.TEXT_XML_VALUE } )
+    @ResponseStatus( value = HttpStatus.NO_CONTENT )
+    public void putXmlObject( HttpServletResponse response, HttpServletRequest request, @PathVariable( "uid" ) String uid, InputStream
         input ) throws Exception
     {
         List<T> objects = getEntity( uid );
@@ -323,9 +327,9 @@
         renderService.toXml( response.getOutputStream(), summary );
     }
 
-    @RequestMapping(value = "/{uid}", method = RequestMethod.PUT, consumes = MediaType.APPLICATION_JSON_VALUE)
-    @ResponseStatus(value = HttpStatus.NO_CONTENT)
-    public void putJsonObject( HttpServletResponse response, HttpServletRequest request, @PathVariable("uid") String uid, InputStream
+    @RequestMapping( value = "/{uid}", method = RequestMethod.PUT, consumes = MediaType.APPLICATION_JSON_VALUE )
+    @ResponseStatus( value = HttpStatus.NO_CONTENT )
+    public void putJsonObject( HttpServletResponse response, HttpServletRequest request, @PathVariable( "uid" ) String uid, InputStream
         input ) throws Exception
     {
         List<T> objects = getEntity( uid );
@@ -352,9 +356,9 @@
     // DELETE
     //--------------------------------------------------------------------------
 
-    @RequestMapping(value = "/{uid}", method = RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_VALUE)
-    @ResponseStatus(value = HttpStatus.NO_CONTENT)
-    public void deleteObject( HttpServletResponse response, HttpServletRequest request, @PathVariable("uid") String uid ) throws
+    @RequestMapping( value = "/{uid}", method = RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_VALUE )
+    @ResponseStatus( value = HttpStatus.NO_CONTENT )
+    public void deleteObject( HttpServletResponse response, HttpServletRequest request, @PathVariable( "uid" ) String uid ) throws
         Exception
     {
         List<T> objects = getEntity( uid );
@@ -504,7 +508,7 @@
 
     private String entitySimpleName;
 
-    @SuppressWarnings("unchecked")
+    @SuppressWarnings( "unchecked" )
     protected Class<T> getEntityClass()
     {
         if ( entityClass == null )
@@ -536,7 +540,7 @@
         return entitySimpleName;
     }
 
-    @SuppressWarnings("unchecked")
+    @SuppressWarnings( "unchecked" )
     protected T getEntityInstance()
     {
         try