wip add audit for datatables

This commit is contained in:
John Woodlock
2012-12-30 18:36:26 +00:00
parent fbfcc32f78
commit 578bbc2954
17 changed files with 467 additions and 192 deletions
@@ -15,6 +15,8 @@ VALUES
('loan_status_id',400,'Withdrawn by client','Withdrawn by client'), ('loan_status_id',400,'Withdrawn by client','Withdrawn by client'),
('loan_status_id',500,'Rejected','Rejected'), ('loan_status_id',500,'Rejected','Rejected'),
('loan_status_id',600,'Closed','Closed'), ('loan_status_id',600,'Closed','Closed'),
('loan_status_id',601,'Closed - Written Off','Closed - Written Off'),
('loan_status_id',602,'Closed - Reschedule Outstanding Amount','Closed - Reschedule Outstanding Amount'),
('loan_status_id',700,'Overpaid','Overpaid'), ('loan_status_id',700,'Overpaid','Overpaid'),
('loan_transaction_strategy_id',1,'mifos-standard-strategy','Mifos style'), ('loan_transaction_strategy_id',1,'mifos-standard-strategy','Mifos style'),
('loan_transaction_strategy_id',2,'heavensfamily-strategy','Heavensfamily'), ('loan_transaction_strategy_id',2,'heavensfamily-strategy','Heavensfamily'),
@@ -0,0 +1,5 @@
INSERT INTO `r_enum_value` (`enum_name`, `enum_id`, `enum_message_property`, `enum_value`)
VALUES ('loan_status_id', '601', 'Closed - Written Off', 'Closed - Written Off');
INSERT INTO `mifostenant-creocore`.`r_enum_value` (`enum_name`, `enum_id`, `enum_message_property`, `enum_value`)
VALUES ('loan_status_id', '602', 'Closed - Reschedule Outstanding Amount', 'Closed - Reschedule Outstanding Amount');
@@ -239,4 +239,16 @@ public class CommandWrapper {
public boolean isBulkUpdateLoanOfficer() { public boolean isBulkUpdateLoanOfficer() {
return this.actionName.equalsIgnoreCase("BULKREASSIGN") && this.entityName.equalsIgnoreCase("LOAN"); return this.actionName.equalsIgnoreCase("BULKREASSIGN") && this.entityName.equalsIgnoreCase("LOAN");
} }
public boolean isDatatableResource() {
return this.resource.toUpperCase().startsWith("DATATABLES");
}
public boolean isDeleteMultiple() {
return isDatatableResource() && this.apiOperation.equalsIgnoreCase("DELETE_MULTIPLE");
}
public boolean isUpdateMultiple() {
return isDatatableResource() && this.apiOperation.equalsIgnoreCase("UPDATE_MULTIPLE");
}
} }
@@ -45,7 +45,7 @@ public class PortfolioCommandSourceWritePlatformServiceImpl implements Portfolio
EntityIdentifier result = null; EntityIdentifier result = null;
try { try {
final JsonElement parsedCommand = this.fromApiJsonHelper.parse(json); final JsonElement parsedCommand = this.fromApiJsonHelper.parse(json);
final JsonCommand command = JsonCommand.from(json, parsedCommand, this.fromApiJsonHelper, resourceId, subRescourceId); final JsonCommand command = JsonCommand.from(json, parsedCommand, this.fromApiJsonHelper, entityName, resourceId, subRescourceId);
final boolean isApprovedByChecker = false; final boolean isApprovedByChecker = false;
result = this.processAndLogCommandService.processAndLogCommand(wrapper, command, isApprovedByChecker); result = this.processAndLogCommandService.processAndLogCommand(wrapper, command, isApprovedByChecker);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) { } catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
@@ -53,7 +53,7 @@ public class PortfolioCommandSourceWritePlatformServiceImpl implements Portfolio
final String jsonToUse = StringUtils.defaultIfEmpty(e.getJsonOfChangesOnly(), json); final String jsonToUse = StringUtils.defaultIfEmpty(e.getJsonOfChangesOnly(), json);
final JsonElement parsedCommand = this.fromApiJsonHelper.parse(jsonToUse); final JsonElement parsedCommand = this.fromApiJsonHelper.parse(jsonToUse);
final JsonCommand command = JsonCommand.from(jsonToUse, parsedCommand, this.fromApiJsonHelper, resourceId, subRescourceId); final JsonCommand command = JsonCommand.from(jsonToUse, parsedCommand, this.fromApiJsonHelper, entityName, resourceId, subRescourceId);
result = this.processAndLogCommandService.logCommand(wrapper, command); result = this.processAndLogCommandService.logCommand(wrapper, command);
} }
@@ -73,7 +73,7 @@ public class PortfolioCommandSourceWritePlatformServiceImpl implements Portfolio
EntityIdentifier result = null; EntityIdentifier result = null;
try { try {
final JsonElement parsedCommand = this.fromApiJsonHelper.parse(json); final JsonElement parsedCommand = this.fromApiJsonHelper.parse(json);
final JsonCommand command = JsonCommand.from(json, parsedCommand, this.fromApiJsonHelper, resourceId, null); final JsonCommand command = JsonCommand.from(json, parsedCommand, this.fromApiJsonHelper, entityName, resourceId, null);
final boolean isApprovedByChecker = false; final boolean isApprovedByChecker = false;
result = this.processAndLogCommandService.processAndLogCommand(wrapper, command, isApprovedByChecker); result = this.processAndLogCommandService.processAndLogCommand(wrapper, command, isApprovedByChecker);
@@ -82,7 +82,7 @@ public class PortfolioCommandSourceWritePlatformServiceImpl implements Portfolio
final String jsonToUse = StringUtils.defaultIfEmpty(e.getJsonOfChangesOnly(), json); final String jsonToUse = StringUtils.defaultIfEmpty(e.getJsonOfChangesOnly(), json);
final JsonElement parsedCommand = this.fromApiJsonHelper.parse(jsonToUse); final JsonElement parsedCommand = this.fromApiJsonHelper.parse(jsonToUse);
final JsonCommand command = JsonCommand.from(jsonToUse, parsedCommand, this.fromApiJsonHelper, resourceId, null); final JsonCommand command = JsonCommand.from(jsonToUse, parsedCommand, this.fromApiJsonHelper, entityName, resourceId, null);
result = this.processAndLogCommandService.logCommand(wrapper, command); result = this.processAndLogCommandService.logCommand(wrapper, command);
} }
@@ -98,7 +98,22 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer
private NewCommandSourceHandler findCommandHandler(final CommandWrapper wrapper) { private NewCommandSourceHandler findCommandHandler(final CommandWrapper wrapper) {
NewCommandSourceHandler handler = null; NewCommandSourceHandler handler = null;
if (wrapper.isClientNoteResource()) { if (wrapper.isDatatableResource()) {
if (wrapper.isCreate()) {
handler = applicationContext.getBean("createDatatableEntryCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isUpdateMultiple()) {
handler = applicationContext.getBean("updateOneToManyDatatableEntryCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isUpdate()) {
handler = applicationContext.getBean("updateOneToOneDatatableEntryCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isDeleteMultiple()) {
handler = applicationContext.getBean("deleteOneToManyDatatableEntryCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isDelete()) {
handler = applicationContext.getBean("deleteOneToOneDatatableEntryCommandHandler", NewCommandSourceHandler.class);
} else {
throw new UnsupportedCommandException(wrapper.commandName());
}
}
else if (wrapper.isClientNoteResource()) {
if (wrapper.isCreate()) { if (wrapper.isCreate()) {
handler = applicationContext.getBean("createClientNoteCommandHandler", NewCommandSourceHandler.class); handler = applicationContext.getBean("createClientNoteCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isUpdate()) { } else if (wrapper.isUpdate()) {
@@ -30,23 +30,25 @@ public final class JsonCommand {
private final Long commandId; private final Long commandId;
private final Long resourceId; private final Long resourceId;
private final Long subResourceId; private final Long subResourceId;
private final String entityName;
public static JsonCommand from(final String jsonCommand, final JsonElement parsedCommand, final FromJsonHelper fromApiJsonHelper, public static JsonCommand from(final String jsonCommand, final JsonElement parsedCommand, final FromJsonHelper fromApiJsonHelper,
final Long resourceId, final Long subResourceId) { final String entityName, final Long resourceId, final Long subResourceId) {
return new JsonCommand(null, jsonCommand, parsedCommand, fromApiJsonHelper, resourceId, subResourceId); return new JsonCommand(null, jsonCommand, parsedCommand, fromApiJsonHelper, entityName, resourceId, subResourceId);
} }
public static JsonCommand fromExistingCommand(final Long commandId, final String jsonCommand, final JsonElement parsedCommand, final FromJsonHelper fromApiJsonHelper, public static JsonCommand fromExistingCommand(final Long commandId, final String jsonCommand, final JsonElement parsedCommand, final FromJsonHelper fromApiJsonHelper,
final Long resourceId, final Long subResourceId) { final Long resourceId, final Long subResourceId) {
return new JsonCommand(commandId, jsonCommand, parsedCommand, fromApiJsonHelper, resourceId, subResourceId); return new JsonCommand(commandId, jsonCommand, parsedCommand, fromApiJsonHelper, null, resourceId, subResourceId);
} }
public JsonCommand(final Long commandId, final String jsonCommand, final JsonElement parsedCommand, final FromJsonHelper fromApiJsonHelper, public JsonCommand(final Long commandId, final String jsonCommand, final JsonElement parsedCommand, final FromJsonHelper fromApiJsonHelper,
final Long resourceId, final Long subResourceId) { final String entityName, final Long resourceId, final Long subResourceId) {
this.commandId = commandId; this.commandId = commandId;
this.jsonCommand = jsonCommand; this.jsonCommand = jsonCommand;
this.parsedCommand = parsedCommand; this.parsedCommand = parsedCommand;
this.fromApiJsonHelper = fromApiJsonHelper; this.fromApiJsonHelper = fromApiJsonHelper;
this.entityName = entityName;
this.resourceId = resourceId; this.resourceId = resourceId;
this.subResourceId = subResourceId; this.subResourceId = subResourceId;
} }
@@ -63,6 +65,10 @@ public final class JsonCommand {
return this.commandId; return this.commandId;
} }
public String entityName() {
return this.entityName;
}
public Long resourceId() { public Long resourceId() {
return this.resourceId; return this.resourceId;
} }
@@ -36,6 +36,10 @@ public class FromJsonHelper {
public Map<String, Boolean> extractMap(final Type typeOfMap, final String json) { public Map<String, Boolean> extractMap(final Type typeOfMap, final String json) {
return this.gsonConverter.fromJson(json, typeOfMap); return this.gsonConverter.fromJson(json, typeOfMap);
} }
public Map<String, String> extractDataMap(final Type typeOfMap, final String json) {
return this.gsonConverter.fromJson(json, typeOfMap);
}
public <T> T fromJson(final String json, Class<T> classOfT) { public <T> T fromJson(final String json, Class<T> classOfT) {
return this.gsonConverter.fromJson(json, classOfT); return this.gsonConverter.fromJson(json, classOfT);
@@ -23,6 +23,7 @@ import javax.ws.rs.core.UriInfo;
import org.codehaus.jettison.json.JSONArray; import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject; import org.codehaus.jettison.json.JSONObject;
import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService;
import org.mifosplatform.infrastructure.core.api.ApiParameterHelper; import org.mifosplatform.infrastructure.core.api.ApiParameterHelper;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier; import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
import org.mifosplatform.infrastructure.core.serialization.ToApiJsonSerializer; import org.mifosplatform.infrastructure.core.serialization.ToApiJsonSerializer;
@@ -44,197 +45,242 @@ import org.springframework.stereotype.Component;
@Scope("singleton") @Scope("singleton")
public class DataTableApiResource { public class DataTableApiResource {
private final static Logger logger = LoggerFactory.getLogger(DataTableApiResource.class); private final static Logger logger = LoggerFactory
.getLogger(DataTableApiResource.class);
private final PlatformSecurityContext context;
private final GenericDataService genericDataService;
private final ReadWriteNonCoreDataService readWriteNonCoreDataService;
private final ToApiJsonSerializer<GenericResultsetData> toApiJsonSerializer;
@Autowired private final PlatformSecurityContext context;
public DataTableApiResource(final PlatformSecurityContext context, final GenericDataService genericDataService, private final GenericDataService genericDataService;
final ReadWriteNonCoreDataService readWriteNonCoreDataService, ToApiJsonSerializer<GenericResultsetData> toApiJsonSerializer) { private final ReadWriteNonCoreDataService readWriteNonCoreDataService;
this.context = context; private final ToApiJsonSerializer<GenericResultsetData> toApiJsonSerializer;
this.genericDataService = genericDataService; private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
this.readWriteNonCoreDataService = readWriteNonCoreDataService;
this.toApiJsonSerializer = toApiJsonSerializer;
}
@GET @Autowired
@Consumes({ MediaType.APPLICATION_JSON }) public DataTableApiResource(
@Produces({ MediaType.APPLICATION_JSON }) final PlatformSecurityContext context,
public String getDatatables(@QueryParam("apptable") final String apptable, @Context final UriInfo uriInfo) { final GenericDataService genericDataService,
final ReadWriteNonCoreDataService readWriteNonCoreDataService,
ToApiJsonSerializer<GenericResultsetData> toApiJsonSerializer,
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) {
this.context = context;
this.genericDataService = genericDataService;
this.readWriteNonCoreDataService = readWriteNonCoreDataService;
this.toApiJsonSerializer = toApiJsonSerializer;
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
}
final List<DatatableData> result = this.readWriteNonCoreDataService.retrieveDatatableNames(apptable); @GET
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String getDatatables(@QueryParam("apptable") final String apptable,
@Context final UriInfo uriInfo) {
final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); final List<DatatableData> result = this.readWriteNonCoreDataService
return this.toApiJsonSerializer.serializePretty(prettyPrint, result); .retrieveDatatableNames(apptable);
}
@POST final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo
@Path("register/{datatable}/{apptable}") .getQueryParameters());
@Consumes({ MediaType.APPLICATION_JSON }) return this.toApiJsonSerializer.serializePretty(prettyPrint, result);
@Produces({ MediaType.APPLICATION_JSON }) }
public String registerDatatable(@PathParam("datatable") final String datatable, @PathParam("apptable") final String apptable) {
this.readWriteNonCoreDataService.registerDatatable(datatable, apptable); @POST
@Path("register/{datatable}/{apptable}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String registerDatatable(
@PathParam("datatable") final String datatable,
@PathParam("apptable") final String apptable) {
return this.toApiJsonSerializer.serialize(EntityIdentifier.empty()); this.readWriteNonCoreDataService.registerDatatable(datatable, apptable);
}
@POST return this.toApiJsonSerializer.serialize(EntityIdentifier.empty());
@Path("deregister/{datatable}") }
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String deregisterDatatable(@PathParam("datatable") final String datatable) {
this.readWriteNonCoreDataService.deregisterDatatable(datatable); @POST
@Path("deregister/{datatable}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String deregisterDatatable(
@PathParam("datatable") final String datatable) {
return this.toApiJsonSerializer.serialize(EntityIdentifier.empty()); this.readWriteNonCoreDataService.deregisterDatatable(datatable);
}
@GET return this.toApiJsonSerializer.serialize(EntityIdentifier.empty());
@Path("{datatable}/{apptableId}") }
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String getDatatable(@PathParam("datatable") final String datatable, @PathParam("apptableId") final Long apptableId,
@QueryParam("order") final String order, @Context final UriInfo uriInfo) {
checkUserPermissionForDatatable(datatable, "READ"); @GET
@Path("{datatable}/{apptableId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String getDatatable(@PathParam("datatable") final String datatable,
@PathParam("apptableId") final Long apptableId,
@QueryParam("order") final String order,
@Context final UriInfo uriInfo) {
GenericResultsetData results = this.readWriteNonCoreDataService.retrieveDataTableGenericResultSet(datatable, apptableId, order, checkUserPermissionForDatatable(datatable, "READ");
null);
String json = ""; GenericResultsetData results = this.readWriteNonCoreDataService
final boolean genericResultSet = ApiParameterHelper.genericResultSet(uriInfo.getQueryParameters()); .retrieveDataTableGenericResultSet(datatable, apptableId,
if (genericResultSet) { order, null);
final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
json = this.toApiJsonSerializer.serializePretty(prettyPrint, results);
} else {
json = this.genericDataService.generateJsonFromGenericResultsetData(results);
}
return json; String json = "";
} final boolean genericResultSet = ApiParameterHelper
.genericResultSet(uriInfo.getQueryParameters());
if (genericResultSet) {
final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo
.getQueryParameters());
json = this.toApiJsonSerializer.serializePretty(prettyPrint,
results);
} else {
json = this.genericDataService
.generateJsonFromGenericResultsetData(results);
}
@POST return json;
@Path("{datatable}/{apptableId}") }
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String newDatatableEntry(@PathParam("datatable") final String datatable, @PathParam("apptableId") final Long apptableId,
final String jsonRequestBody) {
checkUserPermissionForDatatable(datatable, "CREATE"); @POST
Map<String, String> queryParams = getQueryParamsFromJsonRequestBody(jsonRequestBody); @Path("{datatable}/{apptableId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String newDatatableEntry(
@PathParam("datatable") final String datatable,
@PathParam("apptableId") final Long apptableId,
final String apiRequestBodyAsJson) {
this.readWriteNonCoreDataService.newDatatableEntry(datatable, apptableId, queryParams); final EntityIdentifier entityIdentifier = this.commandsSourceWritePlatformService
.logCommandSource("CREATE", datatable, "CREATE", "datatables/"+datatable,
apptableId, apiRequestBodyAsJson);
EntityIdentifier entityIdentifier = EntityIdentifier.resourceResult(Long.valueOf(apptableId), null); return this.toApiJsonSerializer.serialize(entityIdentifier);
}
return this.toApiJsonSerializer.serialize(entityIdentifier); @PUT
} @Path("{datatable}/{apptableId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String updateDatatableEntryOnetoOne(
@PathParam("datatable") final String datatable,
@PathParam("apptableId") final Long apptableId,
final String apiRequestBodyAsJson) {
/*
* for updating one to one relationships (where foreign key is the
* primary key)
*/
// checkUserPermissionForDatatable(datatable, "UPDATE");
// Map<String, String> queryParams = getQueryParamsFromJsonRequestBody(jsonRequestBody);
final EntityIdentifier entityIdentifier = this.commandsSourceWritePlatformService
.logCommandSource("UPDATE", datatable, "UPDATE", "datatables/"+datatable,
apptableId, apiRequestBodyAsJson);
@PUT // this.readWriteNonCoreDataService.updateDatatableEntryOnetoOne(
@Path("{datatable}/{apptableId}") // datatable, apptableId, queryParams);
@Consumes({ MediaType.APPLICATION_JSON }) //
@Produces({ MediaType.APPLICATION_JSON }) // EntityIdentifier entityIdentifier = EntityIdentifier.resourceResult(
public String updateDatatableEntryOnetoOne(@PathParam("datatable") final String datatable, // Long.valueOf(apptableId), null);
@PathParam("apptableId") final Long apptableId, final String jsonRequestBody) {
/*
* for updating one to one relationships (where foreign key is the
* primary key)
*/
checkUserPermissionForDatatable(datatable, "UPDATE");
Map<String, String> queryParams = getQueryParamsFromJsonRequestBody(jsonRequestBody);
this.readWriteNonCoreDataService.updateDatatableEntryOnetoOne(datatable, apptableId, queryParams); return this.toApiJsonSerializer.serialize(entityIdentifier);
}
EntityIdentifier entityIdentifier = EntityIdentifier.resourceResult(Long.valueOf(apptableId), null); @PUT
@Path("{datatable}/{apptableId}/{datatableId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String updateDatatableEntryOnetoOne(
@PathParam("datatable") final String datatable,
@PathParam("apptableId") final Long apptableId,
@PathParam("datatableId") final Long datatableId,
final String apiRequestBodyAsJson) {
/*
* for updating one to many relationships (where foreign key isn't the
* primary key)
*/
final EntityIdentifier entityIdentifier = this.commandsSourceWritePlatformService
.logCommandSource("UPDATE", datatable, "UPDATE_MULTIPLE", "datatables/"+datatable, apptableId, "datatables/"+datatable, datatableId, apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(entityIdentifier); return this.toApiJsonSerializer.serialize(entityIdentifier);
}
// checkUserPermissionForDatatable(datatable, "UPDATE");
// Map<String, String> queryParams = getQueryParamsFromJsonRequestBody(jsonRequestBody);
//
// this.readWriteNonCoreDataService.updateDatatableEntryOnetoMany(
// datatable, apptableId, datatableId, queryParams);
//
// EntityIdentifier entityIdentifier = EntityIdentifier.resourceResult(
// Long.valueOf(apptableId), null);
//
// return this.toApiJsonSerializer.serialize(entityIdentifier);
}
@PUT @DELETE
@Path("{datatable}/{apptableId}/{datatableId}") @Path("{datatable}/{apptableId}")
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String updateDatatableEntryOnetoOne(@PathParam("datatable") final String datatable, public String deleteDatatableEntries(
@PathParam("apptableId") final Long apptableId, @PathParam("datatableId") final Long datatableId, final String jsonRequestBody) { @PathParam("datatable") final String datatable,
/* @PathParam("apptableId") final Long apptableId) {
* for updating one to many relationships (where foreign key isn't the
* primary key)
*/
checkUserPermissionForDatatable(datatable, "UPDATE");
Map<String, String> queryParams = getQueryParamsFromJsonRequestBody(jsonRequestBody);
this.readWriteNonCoreDataService.updateDatatableEntryOnetoMany(datatable, apptableId, datatableId, queryParams); final EntityIdentifier entityIdentifier = this.commandsSourceWritePlatformService
.logCommandSource("DELETE", datatable, "DELETE", "datatables/"+datatable,
apptableId, "{}");
return this.toApiJsonSerializer.serialize(entityIdentifier);
}
EntityIdentifier entityIdentifier = EntityIdentifier.resourceResult(Long.valueOf(apptableId), null); @DELETE
@Path("{datatable}/{apptableId}/{datatableId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String deleteDatatableEntries(
@PathParam("datatable") final String datatable,
@PathParam("apptableId") final Long apptableId,
@PathParam("datatableId") final Long datatableId) {
return this.toApiJsonSerializer.serialize(entityIdentifier); final EntityIdentifier entityIdentifier = this.commandsSourceWritePlatformService
} .logCommandSource("DELETE", datatable, "DELETE_MULTIPLE", "datatables/"+datatable, apptableId, "datatables/"+datatable, datatableId, "{}");
@DELETE return this.toApiJsonSerializer.serialize(entityIdentifier);
@Path("{datatable}/{apptableId}") }
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String deleteDatatableEntries(@PathParam("datatable") final String datatable, @PathParam("apptableId") final Long apptableId) {
checkUserPermissionForDatatable(datatable, "DELETE"); private Map<String, String> getQueryParamsFromJsonRequestBody(
final String jsonRequestBody) {
this.readWriteNonCoreDataService.deleteDatatableEntries(datatable, apptableId); Map<String, String> queryParams = new HashMap<String, String>();
EntityIdentifier entityIdentifier = EntityIdentifier.resourceResult(Long.valueOf(apptableId), null); String pValue = "";
String pName;
try {
JSONObject jsonObj = new JSONObject(jsonRequestBody);
JSONArray jsonArr = jsonObj.names();
if (jsonArr != null) {
for (int i = 0; i < jsonArr.length(); i++) {
pName = (String) jsonArr.get(i);
pValue = jsonObj.getString(pName);
logger.info("getQueryParamsFromJsonRequestBody: " + pName
+ " - " + pValue);
queryParams.put(pName, pValue);
}
return queryParams;
}
throw new WebApplicationException(Response
.status(Status.BAD_REQUEST).entity("JSON body empty")
.build());
return this.toApiJsonSerializer.serialize(entityIdentifier); } catch (JSONException e) {
throw new WebApplicationException(Response
.status(Status.BAD_REQUEST).entity("JSON body is wrong")
.build());
}
} }
@DELETE private void checkUserPermissionForDatatable(final String datatable,
@Path("{datatable}/{apptableId}/{datatableId}") final String accessType) {
@Consumes({ MediaType.APPLICATION_JSON }) AppUser currentUser = context.authenticatedUser();
@Produces({ MediaType.APPLICATION_JSON }) if (currentUser.hasNotPermissionForDatatable(datatable, accessType)) {
public String deleteDatatableEntries(@PathParam("datatable") final String datatable, @PathParam("apptableId") final Long apptableId, throw new NoAuthorizationException("Not Authorised to "
@PathParam("datatableId") final Long datatableId) { + accessType + " Data Table: " + datatable);
}
checkUserPermissionForDatatable(datatable, "DELETE"); }
this.readWriteNonCoreDataService.deleteDatatableEntry(datatable, apptableId, datatableId);
EntityIdentifier entityIdentifier = EntityIdentifier.resourceResult(Long.valueOf(apptableId), null);
return this.toApiJsonSerializer.serialize(entityIdentifier);
}
private Map<String, String> getQueryParamsFromJsonRequestBody(final String jsonRequestBody) {
Map<String, String> queryParams = new HashMap<String, String>();
String pValue = "";
String pName;
try {
JSONObject jsonObj = new JSONObject(jsonRequestBody);
JSONArray jsonArr = jsonObj.names();
if (jsonArr != null) {
for (int i = 0; i < jsonArr.length(); i++) {
pName = (String) jsonArr.get(i);
pValue = jsonObj.getString(pName);
logger.info("getQueryParamsFromJsonRequestBody: " + pName + " - " + pValue);
queryParams.put(pName, pValue);
}
return queryParams;
}
throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity("JSON body empty").build());
} catch (JSONException e) {
throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity("JSON body is wrong").build());
}
}
private void checkUserPermissionForDatatable(final String datatable, final String accessType) {
AppUser currentUser = context.authenticatedUser();
if (currentUser.hasNotPermissionForDatatable(datatable, accessType)) { throw new NoAuthorizationException("Not Authorised to "
+ accessType + " Data Table: " + datatable); }
}
} }
@@ -0,0 +1,33 @@
package org.mifosplatform.infrastructure.dataqueries.handler;
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
import org.mifosplatform.infrastructure.dataqueries.service.ReadWriteNonCoreDataService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class CreateDatatableEntryCommandHandler implements
NewCommandSourceHandler {
private final ReadWriteNonCoreDataService writePlatformService;
@Autowired
public CreateDatatableEntryCommandHandler(
final ReadWriteNonCoreDataService writePlatformService) {
this.writePlatformService = writePlatformService;
}
@Transactional
@Override
public EntityIdentifier processCommand(final JsonCommand command) {
this.writePlatformService.newDatatableEntry(command.entityName(),
command.resourceId(), command);
return EntityIdentifier.resourceResult(command.resourceId(),
command.commandId());
}
}
@@ -0,0 +1,32 @@
package org.mifosplatform.infrastructure.dataqueries.handler;
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
import org.mifosplatform.infrastructure.dataqueries.service.ReadWriteNonCoreDataService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class DeleteOneToManyDatatableEntryCommandHandler implements
NewCommandSourceHandler {
private final ReadWriteNonCoreDataService writePlatformService;
@Autowired
public DeleteOneToManyDatatableEntryCommandHandler(
final ReadWriteNonCoreDataService writePlatformService) {
this.writePlatformService = writePlatformService;
}
@Transactional
@Override
public EntityIdentifier processCommand(final JsonCommand command) {
this.writePlatformService.deleteDatatableEntry(command.entityName(), command.resourceId(), command.subResourceId());
return EntityIdentifier.subResourceResult(command.resourceId(), command.subResourceId(),
command.commandId());
}
}
@@ -0,0 +1,32 @@
package org.mifosplatform.infrastructure.dataqueries.handler;
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
import org.mifosplatform.infrastructure.dataqueries.service.ReadWriteNonCoreDataService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class DeleteOneToOneDatatableEntryCommandHandler implements
NewCommandSourceHandler {
private final ReadWriteNonCoreDataService writePlatformService;
@Autowired
public DeleteOneToOneDatatableEntryCommandHandler(
final ReadWriteNonCoreDataService writePlatformService) {
this.writePlatformService = writePlatformService;
}
@Transactional
@Override
public EntityIdentifier processCommand(final JsonCommand command) {
this.writePlatformService.deleteDatatableEntries(command.entityName(), command.resourceId());
return EntityIdentifier.resourceResult(command.resourceId(),
command.commandId());
}
}
@@ -0,0 +1,32 @@
package org.mifosplatform.infrastructure.dataqueries.handler;
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
import org.mifosplatform.infrastructure.dataqueries.service.ReadWriteNonCoreDataService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class UpdateOneToManyDatatableEntryCommandHandler implements
NewCommandSourceHandler {
private final ReadWriteNonCoreDataService writePlatformService;
@Autowired
public UpdateOneToManyDatatableEntryCommandHandler(
final ReadWriteNonCoreDataService writePlatformService) {
this.writePlatformService = writePlatformService;
}
@Transactional
@Override
public EntityIdentifier processCommand(final JsonCommand command) {
this.writePlatformService.updateDatatableEntryOneToMany(command.entityName(), command.resourceId(), command.subResourceId(), command);
return EntityIdentifier.subResourceResult(command.resourceId(), command.subResourceId(),
command.commandId());
}
}
@@ -0,0 +1,33 @@
package org.mifosplatform.infrastructure.dataqueries.handler;
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
import org.mifosplatform.infrastructure.dataqueries.service.ReadWriteNonCoreDataService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class UpdateOneToOneDatatableEntryCommandHandler implements
NewCommandSourceHandler {
private final ReadWriteNonCoreDataService writePlatformService;
@Autowired
public UpdateOneToOneDatatableEntryCommandHandler(
final ReadWriteNonCoreDataService writePlatformService) {
this.writePlatformService = writePlatformService;
}
@Transactional
@Override
public EntityIdentifier processCommand(final JsonCommand command) {
// TODO - return only detected changes
this.writePlatformService.updateDatatableEntryOneToOne(command.entityName(), command.resourceId(), command);
return EntityIdentifier.resourceResult(command.resourceId(),
command.commandId());
}
}
@@ -36,7 +36,7 @@ public class GenericDataServiceImpl implements GenericDataService {
@Override @Override
public CachedRowSet getCachedResultSet(final String sql, final String sqlErrorMsg) { public CachedRowSet getCachedResultSet(final String sql, final String sqlErrorMsg) {
// TODO - Need to reimplement this away from Sun library - could be // FIXME - Need to reimplement this away from Sun library - could be
// mixture of Lists and jdbcTemplate.query // mixture of Lists and jdbcTemplate.query
// long startTime = System.currentTimeMillis(); // long startTime = System.currentTimeMillis();
@@ -1,32 +1,37 @@
package org.mifosplatform.infrastructure.dataqueries.service; package org.mifosplatform.infrastructure.dataqueries.service;
import java.util.List; import java.util.List;
import java.util.Map;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.dataqueries.data.DatatableData; import org.mifosplatform.infrastructure.dataqueries.data.DatatableData;
import org.mifosplatform.infrastructure.dataqueries.data.GenericResultsetData; import org.mifosplatform.infrastructure.dataqueries.data.GenericResultsetData;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
public interface ReadWriteNonCoreDataService { public interface ReadWriteNonCoreDataService {
List<DatatableData> retrieveDatatableNames(String appTable); List<DatatableData> retrieveDatatableNames(String appTable);
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'REGISTER_DATATABLE')") @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'REGISTER_DATATABLE')")
void registerDatatable(String datatable, String appTable); void registerDatatable(String datatable, String appTable);
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'DEREGISTER_DATATABLE')") @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'DEREGISTER_DATATABLE')")
void deregisterDatatable(String datatable); void deregisterDatatable(String datatable);
GenericResultsetData retrieveDataTableGenericResultSet(String datatable, Long appTableId, String order, Long id); GenericResultsetData retrieveDataTableGenericResultSet(String datatable,
Long appTableId, String order, Long id);
void newDatatableEntry(String datatable, Long appTableId, Map<String, String> queryParams); void newDatatableEntry(String datatable, Long appTableId,
JsonCommand command);
void updateDatatableEntryOnetoOne(String datatable, Long appTableId, Map<String, String> queryParams); void updateDatatableEntryOneToOne(String datatable, Long appTableId,
JsonCommand command);
void updateDatatableEntryOnetoMany(String datatable, Long appTableId, Long datatableId, Map<String, String> queryParams); void updateDatatableEntryOneToMany(String datatable, Long appTableId,
Long datatableId, JsonCommand command);
void deleteDatatableEntries(String datatable, Long appTableId); void deleteDatatableEntries(String datatable, Long appTableId);
void deleteDatatableEntry(String datatable, Long appTableId, Long datatableId); void deleteDatatableEntry(String datatable, Long appTableId,
Long datatableId);
} }
@@ -1,5 +1,6 @@
package org.mifosplatform.infrastructure.dataqueries.service; package org.mifosplatform.infrastructure.dataqueries.service;
import java.lang.reflect.Type;
import java.sql.ResultSetMetaData; import java.sql.ResultSetMetaData;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
@@ -12,9 +13,11 @@ import java.util.Set;
import javax.sql.rowset.CachedRowSet; import javax.sql.rowset.CachedRowSet;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.ApiParameterError; import org.mifosplatform.infrastructure.core.data.ApiParameterError;
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException; import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException; import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.infrastructure.core.serialization.JsonParserHelper; import org.mifosplatform.infrastructure.core.serialization.JsonParserHelper;
import org.mifosplatform.infrastructure.dataqueries.data.DatatableData; import org.mifosplatform.infrastructure.dataqueries.data.DatatableData;
import org.mifosplatform.infrastructure.dataqueries.data.GenericResultsetData; import org.mifosplatform.infrastructure.dataqueries.data.GenericResultsetData;
@@ -29,16 +32,20 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.google.gson.reflect.TypeToken;
@Service @Service
public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataService { public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataService {
private final static Logger logger = LoggerFactory.getLogger(ReadWriteNonCoreDataServiceImpl.class);
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
private final FromJsonHelper fromJsonHelper;
private final static Logger logger = LoggerFactory.getLogger(ReadWriteNonCoreDataServiceImpl.class);
@Autowired @Autowired
public ReadWriteNonCoreDataServiceImpl(final PlatformSecurityContext context) { public ReadWriteNonCoreDataServiceImpl(final PlatformSecurityContext context, final FromJsonHelper fromJsonHelper) {
this.context = context; this.context = context;
this.fromJsonHelper = fromJsonHelper;
} }
@Autowired @Autowired
@@ -147,14 +154,17 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
} }
@Override @Override
public void newDatatableEntry(final String datatable, final Long appTableId, final Map<String, String> queryParams) { public void newDatatableEntry(final String datatable, final Long appTableId, final JsonCommand command) {
// long startTime = System.currentTimeMillis(); // long startTime = System.currentTimeMillis();
String appTable = getWithinScopeApplicationTableName(datatable, appTableId); String appTable = getWithinScopeApplicationTableName(datatable, appTableId);
List<ResultsetColumnHeader> columnHeaders = getDatatableResultsetColumnHeaders(datatable); List<ResultsetColumnHeader> columnHeaders = getDatatableResultsetColumnHeaders(datatable);
final Type typeOfMap = new TypeToken<Map<String, String>>() {}.getType();
Map<String, String> dataParams = this.fromJsonHelper.extractDataMap(typeOfMap, command.json());
String sql = getAddSql(columnHeaders, datatable, getFKField(appTable), appTableId, queryParams); String sql = getAddSql(columnHeaders, datatable, getFKField(appTable), appTableId, dataParams);
genericDataService.updateSQL(sql, "SQL: " + sql); genericDataService.updateSQL(sql, "SQL: " + sql);
@@ -166,7 +176,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
} }
@Override @Override
public void updateDatatableEntryOnetoOne(final String datatable, final Long appTableId, final Map<String, String> queryParams) { public void updateDatatableEntryOneToOne(final String datatable, final Long appTableId, final JsonCommand command) {
// long startTime = System.currentTimeMillis(); // long startTime = System.currentTimeMillis();
GenericResultsetData grs = retrieveDataTableGenericResultSet(datatable, appTableId, null, null); GenericResultsetData grs = retrieveDataTableGenericResultSet(datatable, appTableId, null, null);
@@ -178,7 +188,11 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
+ " Foreign Key Id: " + appTableId); + " Foreign Key Id: " + appTableId);
String fkName = getFKField(getApplicationTableName(datatable)); String fkName = getFKField(getApplicationTableName(datatable));
String sql = getUpdateSql(grs, datatable, fkName, appTableId, queryParams);
final Type typeOfMap = new TypeToken<Map<String, String>>() {}.getType();
Map<String, String> dataParams = this.fromJsonHelper.extractDataMap(typeOfMap, command.json());
String sql = getUpdateSql(grs, datatable, fkName, appTableId, dataParams);
if (sql != null) { if (sql != null) {
genericDataService.updateSQL(sql, "SQL: " + sql); genericDataService.updateSQL(sql, "SQL: " + sql);
@@ -194,15 +208,18 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
} }
@Override @Override
public void updateDatatableEntryOnetoMany(final String datatable, final Long appTableId, final Long datatableId, public void updateDatatableEntryOneToMany(final String datatable, final Long appTableId, final Long datatableId,
final Map<String, String> queryParams) { final JsonCommand command) {
// long startTime = System.currentTimeMillis(); // long startTime = System.currentTimeMillis();
GenericResultsetData grs = retrieveDataTableGenericResultSet(datatable, appTableId, null, datatableId); GenericResultsetData grs = retrieveDataTableGenericResultSet(datatable, appTableId, null, datatableId);
if (grs.getData().size() == 0) throw new DataTableNotFoundException(datatable, appTableId); if (grs.getData().size() == 0) throw new DataTableNotFoundException(datatable, appTableId);
String sql = getUpdateSql(grs, datatable, "id", datatableId, queryParams); final Type typeOfMap = new TypeToken<Map<String, String>>() {}.getType();
Map<String, String> dataParams = this.fromJsonHelper.extractDataMap(typeOfMap, command.json());
String sql = getUpdateSql(grs, datatable, "id", datatableId, dataParams);
if (sql != null) { if (sql != null) {
genericDataService.updateSQL(sql, "SQL: " + sql); genericDataService.updateSQL(sql, "SQL: " + sql);
@@ -125,9 +125,10 @@ public class GuarantorWritePlatformServiceImpl implements GuarantorWritePlatform
modifiedParametersMap.put("locale", command.getLocale()); modifiedParametersMap.put("locale", command.getLocale());
modifiedParametersMap.put("dateFormat", command.getDateFormat()); modifiedParametersMap.put("dateFormat", command.getDateFormat());
if (guarantorReadPlatformService.getExternalGuarantor(loanId) != null) { if (guarantorReadPlatformService.getExternalGuarantor(loanId) != null) {
readWriteNonCoreDataService.updateDatatableEntryOnetoOne(EXTERNAL_GUARANTOR_TABLE_NAME, loanId, modifiedParametersMap); // readWriteNonCoreDataService.updateDatatableEntryOnetoOne(EXTERNAL_GUARANTOR_TABLE_NAME, loanId, modifiedParametersMap);
} else { } else {
readWriteNonCoreDataService.newDatatableEntry(EXTERNAL_GUARANTOR_TABLE_NAME, loanId, modifiedParametersMap); // FIXME - put back in call to datatable passing JsonCommand
// readWriteNonCoreDataService.newDatatableEntry(EXTERNAL_GUARANTOR_TABLE_NAME, loanId, modifiedParametersMap);
} }
// finally unset any existing internal guarantors // finally unset any existing internal guarantors
if (loan.getGuarantor() != null) { if (loan.getGuarantor() != null) {