------------------------------------------------------------
revno: 17837
committer: Morten Olav Hansen <[email protected]>
branch nick: dhis2
timestamp: Tue 2014-12-30 15:09:22 +0100
message:
support partial updates on /api/type/id/property, only simple properties are
supported (string, int, bool, etc), will be expanded in 2.19 to support
references (needs components from dxf2 importer which will be extracted), also
adds utility methods in AbstractCrudController for checking for json/xml
paylods, also utility method to deserialize from correct ct.
modified:
dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/schema/Jackson2PropertyIntrospectorService.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-services/dhis-service-core/src/main/java/org/hisp/dhis/schema/Jackson2PropertyIntrospectorService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/schema/Jackson2PropertyIntrospectorService.java 2014-12-22 13:52:51 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/schema/Jackson2PropertyIntrospectorService.java 2014-12-30 14:09:22 +0000
@@ -94,7 +94,16 @@
String fieldName = getFieldName( method );
property.setName( !StringUtils.isEmpty( jsonProperty.value() ) ? jsonProperty.value() : fieldName );
- property.setReadable( true );
+
+ if ( property.getGetterMethod() != null )
+ {
+ property.setReadable( true );
+ }
+
+ if ( property.getSetterMethod() != null )
+ {
+ property.setWritable( true );
+ }
if ( classFieldNames.contains( fieldName ) )
{
=== 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-12-26 12:27:14 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/AbstractCrudController.java 2014-12-30 14:09:22 +0000
@@ -66,6 +66,7 @@
import org.hisp.dhis.webapi.webdomain.WebOptions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
+import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@@ -74,6 +75,7 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
@@ -195,7 +197,7 @@
else
{
// Get full list when using filters other than name / objects without persisted name
-
+
if ( !filters.isEmpty() )
{
if ( options.hasPaging() )
@@ -271,11 +273,67 @@
@RequestMapping( value = "/{uid}/{property}", method = RequestMethod.GET )
public @ResponseBody RootNode getObjectProperty(
- @PathVariable( "uid" ) String uid,
- @PathVariable( "property" ) String pvProperty,
- @RequestParam Map<String, String> parameters, HttpServletRequest request, HttpServletResponse response ) throws Exception
- {
- return getObjectInternal( uid, parameters, Lists.<String>newArrayList(), Lists.newArrayList( pvProperty + "[:all]" ) );
+ @PathVariable( "uid" ) String pvUid,
+ @PathVariable( "property" ) String pvProperty,
+ @RequestParam Map<String, String> parameters, HttpServletRequest request, HttpServletResponse response ) throws Exception
+ {
+ return getObjectInternal( pvUid, parameters, Lists.<String>newArrayList(), Lists.newArrayList( pvProperty + "[:all]" ) );
+ }
+
+ @RequestMapping( value = "/{uid}/{property}", method = { RequestMethod.PUT, RequestMethod.PATCH } )
+ public void updateObjectProperty(
+ @PathVariable( "uid" ) String pvUid,
+ @PathVariable( "property" ) String pvProperty,
+ @RequestParam Map<String, String> parameters, HttpServletRequest request, HttpServletResponse response ) throws Exception
+ {
+ WebOptions options = new WebOptions( parameters );
+ List<T> entities = getEntity( pvUid, options );
+
+ if ( entities.isEmpty() )
+ {
+ ContextUtils.notFoundResponse( response, getEntityName() + " does not exist: " + pvUid );
+ return;
+ }
+
+ if ( !getSchema().getPropertyMap().containsKey( pvProperty ) )
+ {
+ ContextUtils.notFoundResponse( response, "Property " + pvProperty + " does not exist on " + getEntityName() );
+ return;
+ }
+
+ Property property = getSchema().getProperty( pvProperty );
+ T persistedObject = entities.get( 0 );
+
+ if ( !aclService.canUpdate( currentUserService.getCurrentUser(), persistedObject ) )
+ {
+ throw new UpdateAccessDeniedException( "You don't have the proper permissions to update this object." );
+ }
+
+ if ( !property.isWritable() )
+ {
+ throw new UpdateAccessDeniedException( "This property is read-only." );
+ }
+
+ if ( !property.isSimple() )
+ {
+ // TODO we need to split out the reference scanner from the importer for this to work with idObjects
+ throw new UpdateAccessDeniedException( "Only simple properties are currently supported for update." );
+ }
+
+ T object = deserialize( request );
+
+ if ( object == null )
+ {
+ ContextUtils.badRequestResponse( response, "Unknown payload format." );
+ return;
+ }
+
+ Object value = property.getGetterMethod().invoke( object );
+
+ property.getSetterMethod().invoke( persistedObject, value );
+
+ response.setStatus( HttpServletResponse.SC_NO_CONTENT );
+ manager.update( persistedObject );
}
private RootNode getObjectInternal( String uid, Map<String, String> parameters,
@@ -816,6 +874,50 @@
return InclusionStrategy.Include.NON_NULL;
}
+ /**
+ * Deserializes a payload from the request, handles JSON/XML payloads
+ *
+ * @param request HttpServletRequest from current session
+ * @return Parsed entity or null if invalid type
+ */
+ protected T deserialize( HttpServletRequest request ) throws IOException
+ {
+ if ( isJson( request ) )
+ {
+ return renderService.fromJson( request.getInputStream(), getEntityClass() );
+ }
+ else if ( isXml( request ) )
+ {
+ return renderService.fromXml( request.getInputStream(), getEntityClass() );
+ }
+
+ return null;
+ }
+
+ /**
+ * Are we receiving JSON data?
+ *
+ * @param request HttpServletRequest from current session
+ * @return true if JSON compatible
+ */
+ protected boolean isJson( HttpServletRequest request )
+ {
+ String contentType = request.getContentType();
+ return !StringUtils.isEmpty( contentType ) && MediaType.parseMediaType( contentType ).isCompatibleWith( MediaType.APPLICATION_JSON );
+ }
+
+ /**
+ * Are we receiving XML data?
+ *
+ * @param request HttpServletRequest from current session
+ * @return true if XML compatible
+ */
+ protected boolean isXml( HttpServletRequest request )
+ {
+ String contentType = request.getContentType();
+ return !StringUtils.isEmpty( contentType ) && MediaType.parseMediaType( contentType ).isCompatibleWith( MediaType.APPLICATION_XML );
+ }
+
//--------------------------------------------------------------------------
// Reflection helpers
//--------------------------------------------------------------------------
_______________________________________________
Mailing list: https://launchpad.net/~dhis2-devs
Post to : [email protected]
Unsubscribe : https://launchpad.net/~dhis2-devs
More help : https://help.launchpad.net/ListHelp