=== 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-10 16:59:51 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/AbstractNode.java 2014-10-02 08:22:56 +0000 @@ -28,7 +28,6 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE */ -import com.google.common.base.Objects; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import org.hisp.dhis.node.exception.InvalidTypeException; @@ -38,6 +37,7 @@ import java.util.Collections; import java.util.List; +import java.util.Objects; /** * @author Morten Olav Hansen @@ -151,6 +151,15 @@ } @Override + public void removeChild( T child ) + { + if ( children.contains( child ) ) + { + children.remove( child ); + } + } + + @Override public void addChildren( Iterable children ) { for ( Node child : children ) @@ -192,28 +201,36 @@ } @Override - public boolean equals( Object o ) - { - if ( this == o ) return true; - if ( o == null || getClass() != o.getClass() ) return false; - - AbstractNode that = (AbstractNode) o; - - if ( name != null ? !name.equals( that.name ) : that.name != null ) return false; - - return true; - } - - @Override public int hashCode() { - return name != null ? name.hashCode() : 0; + return Objects.hash( name, nodeType, parent, namespace, comment, children ); + } + + @Override + public boolean equals( Object obj ) + { + if ( this == obj ) + { + return true; + } + if ( obj == null || getClass() != obj.getClass() ) + { + return false; + } + + final AbstractNode other = (AbstractNode) obj; + + return Objects.equals( this.name, other.name ) && + Objects.equals( this.nodeType, other.nodeType ) && + Objects.equals( this.namespace, other.namespace ) && + Objects.equals( this.comment, other.comment ) && + Objects.equals( this.children, other.children ); } @Override public String toString() { - return Objects.toStringHelper( this ) + return com.google.common.base.Objects.toStringHelper( this ) .add( "name", name ) .add( "nodeType", nodeType ) .add( "parent", (parent != null ? parent.getName() : null) ) === modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/Node.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/Node.java 2014-06-08 10:58:50 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/Node.java 2014-10-02 08:22:56 +0000 @@ -54,6 +54,7 @@ /** * Get parent node, or null if this is a top-level node. + * * @return parent or null if node does not have parent */ Node getParent(); @@ -116,6 +117,13 @@ T addChild( T child ); /** + * Remove a child from this node. + * + * @param child Child node to add + */ + void removeChild( T child ); + + /** * Adds a collection of children to this node. * * @param children Child nodes to add === modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/types/CollectionNode.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/types/CollectionNode.java 2014-06-09 12:27:37 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/types/CollectionNode.java 2014-10-02 08:22:56 +0000 @@ -28,10 +28,11 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE */ -import com.google.common.base.Objects; import org.hisp.dhis.node.AbstractNode; import org.hisp.dhis.node.NodeType; +import java.util.Objects; + /** * @author Morten Olav Hansen */ @@ -60,7 +61,7 @@ @Override public int hashCode() { - return 31 * super.hashCode() + Objects.hashCode( wrapping ); + return 31 * super.hashCode() + Objects.hash( wrapping ); } @Override @@ -70,17 +71,18 @@ { return true; } + if ( obj == null || getClass() != obj.getClass() ) { return false; } + if ( !super.equals( obj ) ) { return false; } final CollectionNode other = (CollectionNode) obj; - - return Objects.equal( this.wrapping, other.wrapping ); + return Objects.equals( this.wrapping, other.wrapping ); } } === modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/types/SimpleNode.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/types/SimpleNode.java 2014-06-19 11:25:24 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/node/types/SimpleNode.java 2014-10-02 08:22:56 +0000 @@ -28,12 +28,13 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE */ -import com.google.common.base.Objects; import org.hisp.dhis.node.AbstractNode; import org.hisp.dhis.node.Node; import org.hisp.dhis.node.NodeType; import org.hisp.dhis.node.exception.InvalidTypeException; +import java.util.Objects; + /** * @author Morten Olav Hansen */ @@ -92,7 +93,7 @@ @Override public int hashCode() { - return 31 * super.hashCode() + Objects.hashCode( value, attribute ); + return 31 * super.hashCode() + Objects.hash( value, attribute ); } @Override @@ -113,6 +114,6 @@ final SimpleNode other = (SimpleNode) obj; - return Objects.equal( this.value, other.value ) && Objects.equal( this.attribute, other.attribute ); + return Objects.equals( this.value, other.value ) && Objects.equals( this.attribute, other.attribute ); } } === 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-10-02 05:38:02 +0000 +++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/AbstractCrudController.java 2014-10-02 08:22:56 +0000 @@ -49,6 +49,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.Node; import org.hisp.dhis.node.config.InclusionStrategy; import org.hisp.dhis.node.types.CollectionNode; import org.hisp.dhis.node.types.ComplexNode; @@ -251,7 +252,9 @@ } @RequestMapping( value = "/{uid}", method = RequestMethod.GET ) - public @ResponseBody RootNode getObject( @PathVariable( "uid" ) String uid, @RequestParam Map parameters, + public @ResponseBody RootNode getObject( + @PathVariable( "uid" ) String pvUid, + @RequestParam Map parameters, HttpServletRequest request, HttpServletResponse response ) throws Exception { List fields = Lists.newArrayList( contextService.getParameterValues( "fields" ) ); @@ -262,14 +265,16 @@ fields.add( ":all" ); } - return getObjectInternal( uid, parameters, filters, fields ); + return getObjectInternal( pvUid, parameters, filters, fields ); } @RequestMapping( value = "/{uid}/{property}", method = RequestMethod.GET ) - public @ResponseBody RootNode getObjectProperty( @PathVariable( "uid" ) String uid, @PathVariable( "property" ) String property, + public @ResponseBody RootNode getObjectProperty( + @PathVariable( "uid" ) String uid, + @PathVariable( "property" ) String pvProperty, @RequestParam Map parameters, HttpServletRequest request, HttpServletResponse response ) throws Exception { - return getObjectInternal( uid, parameters, Lists.newArrayList(), Lists.newArrayList( property ) ); + return getObjectInternal( uid, parameters, Lists.newArrayList(), Lists.newArrayList( pvProperty + "[:all]" ) ); } private RootNode getObjectInternal( String uid, Map parameters, @@ -475,7 +480,42 @@ // Identifiable object collections add, delete //-------------------------------------------------------------------------- + @RequestMapping( value = "/{uid}/{property}/{itemId}", method = RequestMethod.GET ) + @SuppressWarnings( "unchecked" ) + public @ResponseBody RootNode getCollectionItem( + @PathVariable( "uid" ) String pvUid, + @PathVariable( "property" ) String pvProperty, + @PathVariable( "itemId" ) String pvItemId, + @RequestParam Map parameters, HttpServletResponse response ) throws Exception + { + RootNode rootNode = getObjectInternal( pvUid, parameters, Lists.newArrayList(), Lists.newArrayList( pvProperty + "[:all]" ) ); + + // TODO optimize this using field filter (collection filtering) + if ( !rootNode.getChildren().isEmpty() && rootNode.getChildren().get( 0 ).isCollection() ) + { + for ( Node node : rootNode.getChildren().get( 0 ).getChildren() ) + { + if ( node.isComplex() ) + { + for ( Node child : node.getChildren() ) + { + if ( child.isSimple() && child.getName().equals( "id" ) ) + { + if ( !((SimpleNode) child).getValue().equals( pvItemId ) ) + { + rootNode.getChildren().get( 0 ).removeChild( node ); + } + } + } + } + } + } + + return rootNode; + } + @RequestMapping( value = "/{uid}/{property}/{itemId}", method = { RequestMethod.POST, RequestMethod.PUT } ) + @ResponseStatus( value = HttpStatus.NO_CONTENT ) @SuppressWarnings( "unchecked" ) public void addCollectionItem( @PathVariable( "uid" ) String pvUid, @@ -533,6 +573,7 @@ } @RequestMapping( value = "/{uid}/{property}/{itemId}", method = RequestMethod.DELETE ) + @ResponseStatus( value = HttpStatus.NO_CONTENT ) @SuppressWarnings( "unchecked" ) public void deleteCollectionItem( @PathVariable( "uid" ) String pvUid,