Merge remote-tracking branch 'ashok/MIFOSX-36'

This commit is contained in:
Keith Woodlock
2013-02-07 13:56:08 +00:00
14 changed files with 279 additions and 36 deletions
@@ -268,6 +268,13 @@ INSERT INTO `m_permission`
('configuration', 'DEREGISTER_DATATABLE', 'DATATABLE', 'DEREGISTER', '1'),
('configuration', 'DEREGISTER_DATATABLE_CHECKER', 'DATATABLE', 'DEREGISTER', '0'),
('configuration', 'READ_AUDIT', 'AUDIT', 'READ', '0'),
('configuration', 'CREATE_CODEVALUE', 'CODEVALUE', 'CREATE', '0'),
('configuration', 'READ_CODEVALUE', 'CODEVALUE', 'READ', '0'),
('configuration', 'UPDATE_CODEVALUE', 'CODEVALUE', 'UPDATE', '0'),
('configuration', 'DELETE_CODEVALUE', 'CODEVALUE', 'DELETE', '0'),
('configuration', 'CREATE_CODEVALUE_CHECKER', 'CODEVALUE', 'CREATE', '0'),
('configuration', 'UPDATE_CODEVALUE_CHECKER', 'CODEVALUE', 'UPDATE', '0'),
('configuration', 'DELETE_CODEVALUE_CHECKER', 'CODEVALUE', 'DELETE', '0'),
('organisation', 'READ_MAKERCHECKER', 'MAKERCHECKER', 'READ', '0'),
('organisation', 'READ_CHARGE', 'CHARGE', 'READ', '0'),
('organisation', 'CREATE_CHARGE', 'CHARGE', 'CREATE', '1'),
@@ -0,0 +1,8 @@
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`)
VALUES('configuration', 'CREATE_CODEVALUE', 'CODEVALUE', 'CREATE', '0'),
('configuration', 'READ_CODEVALUE', 'CODEVALUE', 'READ', '0'),
('configuration', 'UPDATE_CODEVALUE', 'CODEVALUE', 'UPDATE', '0'),
('configuration', 'DELETE_CODEVALUE', 'CODEVALUE', 'DELETE', '0'),
('configuration', 'CREATE_CODEVALUE_CHECKER', 'CODEVALUE', 'CREATE', '0'),
('configuration', 'UPDATE_CODEVALUE_CHECKER', 'CODEVALUE', 'UPDATE', '0'),
('configuration', 'DELETE_CODEVALUE_CHECKER', 'CODEVALUE', 'DELETE', '0');
@@ -573,5 +573,21 @@ public class CommandWrapperBuilder {
this.href = "/codes/" + codeId + "/codevalues/template";
return this;
}
public CommandWrapperBuilder updateCodeValue(Long codeId, final Long codeValueId) {
this.actionName = "UPDATE";
this.entityName = "CODEVALUE";
this.entityId = codeValueId;
this.codeId = codeId;
this.href = "/codes/" + codeId + "/codevalues/" + codeValueId;
return this;
}
public CommandWrapperBuilder deleteCodeValue(Long codeId, final Long codeValueId) {
this.actionName = "DELETE";
this.entityName = "CODEVALUE";
this.entityId = codeValueId;
this.href = "/codes/" + codeId + "/codevalues/" + codeValueId;
return this;
}
}
@@ -203,10 +203,10 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer
} else if (wrapper.isCodeValueResource()) {
if (wrapper.isCreate()) {
handler = applicationContext.getBean("createCodeValueCommandHandler", NewCommandSourceHandler.class);
//} else if (wrapper.isUpdate()) {
// handler = applicationContext.getBean("updateCodeCommandHandler", NewCommandSourceHandler.class);
//} else if (wrapper.isDelete()) {
// handler = applicationContext.getBean("deleteCodeCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isUpdate()) {
handler = applicationContext.getBean("updateCodeValueCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isDelete()) {
handler = applicationContext.getBean("deleteCodeValueCommandHandler", NewCommandSourceHandler.class);
} else {
throw new UnsupportedCommandException(wrapper.commandName());
}
@@ -6,8 +6,10 @@ import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
@@ -63,12 +65,26 @@ public class CodeValuesApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveAllCodeValues(@Context final UriInfo uriInfo, @PathParam("codeId") final Long codeId) {
context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions);
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermissions);
final Collection<CodeValueData> codeValues = this.readPlatformService.retrieveAllCodeValues(codeId);
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, codeValues, RESPONSE_DATA_PARAMETERS);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, codeValues, this.RESPONSE_DATA_PARAMETERS);
}
@GET
@Path("{codeValueId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveCodeValue(@Context final UriInfo uriInfo, @PathParam("codeValueId") final Long codeValueId) {
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermissions);
final CodeValueData codeValue = this.readPlatformService.retrieveCodeValue(codeValueId);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, codeValue, this.RESPONSE_DATA_PARAMETERS);
}
@POST
@@ -81,7 +97,33 @@ public class CodeValuesApiResource {
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
}
@PUT
@Path("{codeValueId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String updateCodeValue(@PathParam("codeId") final Long codeId, @PathParam("codeValueId") final Long codeValueId,
final String apiRequestBodyAsJson) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateCodeValue(codeId, codeValueId).withJson(apiRequestBodyAsJson).build();
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
}
@DELETE
@Path("{codeValueId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String deleteCodeValue(@PathParam("codeId") final Long codeId, @PathParam("codeValueId") final Long codeValueId) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteCodeValue(codeId, codeValueId).build();
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
}
}
@@ -1,5 +1,8 @@
package org.mifosplatform.infrastructure.codes.domain;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
@@ -55,4 +58,26 @@ public class CodeValue extends AbstractPersistable<Long> {
final Integer position = command.integerValueSansLocaleOfParameterNamed(CODEVALUE_JSON_INPUT_PARAMS.POSITION.getValue());
return new CodeValue(code, label, position.intValue());
}
public Map<String, Object> update(final JsonCommand command) {
final Map<String, Object> actualChanges = new LinkedHashMap<String, Object>(2);
final String labelParamName = CODEVALUE_JSON_INPUT_PARAMS.NAME.getValue();
if (command.isChangeInStringParameterNamed(labelParamName, this.label)) {
final String newValue = command.stringValueOfParameterNamed(labelParamName);
actualChanges.put(labelParamName, newValue);
this.label = StringUtils.defaultIfEmpty(newValue, null);
}
final String positionParamName = CODEVALUE_JSON_INPUT_PARAMS.POSITION.getValue();
if (command.isChangeInIntegerSansLocaleParameterNamed(positionParamName, this.position)) {
final Integer newValue = command.integerValueSansLocaleOfParameterNamed(positionParamName);
actualChanges.put(positionParamName, newValue);
this.position = newValue.intValue();
}
return actualChanges;
}
}
@@ -0,0 +1,27 @@
package org.mifosplatform.infrastructure.codes.handler;
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.codes.service.CodeValueWritePlatformService;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class DeleteCodeValueCommandHandler implements NewCommandSourceHandler {
private final CodeValueWritePlatformService writePlatformService;
@Autowired
public DeleteCodeValueCommandHandler(final CodeValueWritePlatformService writePlatformService) {
this.writePlatformService = writePlatformService;
}
@Transactional
@Override
public CommandProcessingResult processCommand(final JsonCommand command) {
return this.writePlatformService.deleteCodeValue(command.entityId());
}
}
@@ -0,0 +1,27 @@
package org.mifosplatform.infrastructure.codes.handler;
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.codes.service.CodeValueWritePlatformService;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class UpdateCodeValueCommandHandler implements NewCommandSourceHandler {
private final CodeValueWritePlatformService writePlatformService;
@Autowired
public UpdateCodeValueCommandHandler(final CodeValueWritePlatformService writePlatformService) {
this.writePlatformService = writePlatformService;
}
@Transactional
@Override
public CommandProcessingResult processCommand(final JsonCommand command) {
return this.writePlatformService.updateCodeValue(command.entityId(), command);
}
}
@@ -40,18 +40,20 @@ public final class CodeValueCommandFromApiJsonDeserializer {
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters);
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, this.supportedParameters);
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("codevalue");
final JsonElement element = fromApiJsonHelper.parse(json);
final JsonElement element = this.fromApiJsonHelper.parse(json);
final String name = fromApiJsonHelper.extractStringNamed(CODEVALUE_JSON_INPUT_PARAMS.NAME.getValue(), element);
final String name = this.fromApiJsonHelper.extractStringNamed(CODEVALUE_JSON_INPUT_PARAMS.NAME.getValue(), element);
baseDataValidator.reset().parameter(CODEVALUE_JSON_INPUT_PARAMS.NAME.getValue()).value(name).notBlank().notExceedingLengthOf(100);
final Integer position = fromApiJsonHelper.extractIntegerSansLocaleNamed(CODEVALUE_JSON_INPUT_PARAMS.POSITION.getValue(), element);
baseDataValidator.reset().parameter(CODEVALUE_JSON_INPUT_PARAMS.POSITION.getValue()).value(position).notBlank().integerGreaterThanZero();
final Integer position = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(CODEVALUE_JSON_INPUT_PARAMS.POSITION.getValue(),
element);
baseDataValidator.reset().parameter(CODEVALUE_JSON_INPUT_PARAMS.POSITION.getValue()).value(position).notBlank()
.integerGreaterThanZero();
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
@@ -60,15 +62,24 @@ public final class CodeValueCommandFromApiJsonDeserializer {
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters);
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, this.supportedParameters);
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("code");
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("codevalue");
final JsonElement element = fromApiJsonHelper.parse(json);
if (fromApiJsonHelper.parameterExists("name", element)) {
final String name = fromApiJsonHelper.extractStringNamed("name", element);
baseDataValidator.reset().parameter("name").value(name).notBlank().notExceedingLengthOf(100);
final JsonElement element = this.fromApiJsonHelper.parse(json);
if (this.fromApiJsonHelper.parameterExists(CODEVALUE_JSON_INPUT_PARAMS.NAME.getValue(), element)) {
final String name = this.fromApiJsonHelper.extractStringNamed(CODEVALUE_JSON_INPUT_PARAMS.NAME.getValue(), element);
baseDataValidator.reset().parameter(CODEVALUE_JSON_INPUT_PARAMS.NAME.getValue()).value(name).notBlank()
.notExceedingLengthOf(100);
}
if (this.fromApiJsonHelper.parameterExists(CODEVALUE_JSON_INPUT_PARAMS.POSITION.getValue(), element)) {
final Integer position = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(CODEVALUE_JSON_INPUT_PARAMS.POSITION.getValue(),
element);
baseDataValidator.reset().parameter(CODEVALUE_JSON_INPUT_PARAMS.POSITION.getValue()).value(position).notBlank()
.integerGreaterThanZero();
}
throwExceptionIfValidationWarningsExist(dataValidationErrors);
@@ -23,4 +23,6 @@ public interface CodeValueReadPlatformService {
Collection<CodeValueData> retrieveCustomIdentifierCodeValues();
Collection<CodeValueData> retrieveAllCodeValues(final Long codeId);
CodeValueData retrieveCodeValue(final Long codeValueId);
}
@@ -53,16 +53,26 @@ public class CodeValueReadPlatformServiceImpl implements CodeValueReadPlatformSe
return this.jdbcTemplate.query(sql, rm, new Object[] { "Customer Identifier" });
}
@Override
public Collection<CodeValueData> retrieveAllCodeValues(Long codeId) {
context.authenticatedUser();
@Override
public Collection<CodeValueData> retrieveAllCodeValues(Long codeId) {
context.authenticatedUser();
final CodeValueDataMapper rm = new CodeValueDataMapper();
final String sql = "select " + rm.schema() + "where cv.code_id = ? order by position";
return this.jdbcTemplate.query(sql, rm, new Object[] { codeId });
}
}
@Override
public CodeValueData retrieveCodeValue(Long codeValueId){
context.authenticatedUser();
final CodeValueDataMapper rm = new CodeValueDataMapper();
final String sql = "select " + rm.schema() + "where cv.id = ? order by position";
return this.jdbcTemplate.queryForObject(sql, rm, new Object[] { codeValueId });
}
}
@@ -7,7 +7,7 @@ public interface CodeValueWritePlatformService {
CommandProcessingResult createCodeValue(JsonCommand command);
//CommandProcessingResult updateCode(Long codeId, JsonCommand command);
CommandProcessingResult updateCodeValue(Long codeValueId, JsonCommand command);
//CommandProcessingResult deleteCode(Long codeId);
CommandProcessingResult deleteCodeValue(Long codeValueId);
}
@@ -1,9 +1,12 @@
package org.mifosplatform.infrastructure.codes.service;
import java.util.Map;
import org.mifosplatform.infrastructure.codes.domain.Code;
import org.mifosplatform.infrastructure.codes.domain.CodeRepository;
import org.mifosplatform.infrastructure.codes.domain.CodeValue;
import org.mifosplatform.infrastructure.codes.domain.CodeValueRepository;
import org.mifosplatform.infrastructure.codes.exception.CodeValueNotFoundException;
import org.mifosplatform.infrastructure.codes.serialization.CodeValueCommandFromApiJsonDeserializer;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
@@ -28,8 +31,8 @@ public class CodeValueWritePlatformServiceJpaRepositoryImpl implements CodeValue
private final CodeValueCommandFromApiJsonDeserializer fromApiJsonDeserializer;
@Autowired
public CodeValueWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final CodeRepository codeRepository, final CodeValueRepository codeValueRepository,
final CodeValueCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
public CodeValueWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final CodeRepository codeRepository,
final CodeValueRepository codeValueRepository, final CodeValueCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
this.context = context;
this.codeRepository = codeRepository;
this.codeValueRepository = codeValueRepository;
@@ -41,10 +44,10 @@ public class CodeValueWritePlatformServiceJpaRepositoryImpl implements CodeValue
public CommandProcessingResult createCodeValue(final JsonCommand command) {
try {
context.authenticatedUser();
this.context.authenticatedUser();
this.fromApiJsonDeserializer.validateForCreate(command.json());
final Long codeId = command.getCodeId();
final Code code = this.codeRepository.findOne(codeId);
final CodeValue codeValue = CodeValue.fromJson(code, command);
@@ -64,14 +67,70 @@ public class CodeValueWritePlatformServiceJpaRepositoryImpl implements CodeValue
* is.
*/
private void handleCodeValueDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) {
Throwable realCause = dve.getMostSpecificCause();
final Throwable realCause = dve.getMostSpecificCause();
if (realCause.getMessage().contains("code_value_duplicate")) {
final String name = command.stringValueOfParameterNamed("name");
throw new PlatformDataIntegrityException("error.msg.code.value.duplicate.label", "A code value with lable '" + name + "' already exists");
throw new PlatformDataIntegrityException("error.msg.code.value.duplicate.label", "A code value with lable '" + name
+ "' already exists");
}
logger.error(dve.getMessage(), dve);
throw new PlatformDataIntegrityException("error.msg.cund.unknown.data.integrity.issue",
"Unknown data integrity issue with resource: " + realCause.getMessage());
}
@Transactional
@Override
public CommandProcessingResult updateCodeValue(final Long codeValueId, final JsonCommand command) {
try {
this.context.authenticatedUser();
this.fromApiJsonDeserializer.validateForUpdate(command.json());
final CodeValue codeValue = retrieveCodeValueBy(codeValueId);
final Map<String, Object> changes = codeValue.update(command);
if (!changes.isEmpty()) {
this.codeValueRepository.saveAndFlush(codeValue);
}
return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) //
.withEntityId(codeValueId) //
.with(changes) //
.build();
} catch (DataIntegrityViolationException dve) {
handleCodeValueDataIntegrityIssues(command, dve);
return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) //
.build();
}
}
@Transactional
@Override
public CommandProcessingResult deleteCodeValue(final Long codeValueId) {
try {
this.context.authenticatedUser();
CodeValue codeValue = retrieveCodeValueBy(codeValueId);
this.codeValueRepository.delete(codeValue);
return new CommandProcessingResultBuilder().withEntityId(codeValueId).build();
} catch (DataIntegrityViolationException dve) {
logger.error(dve.getMessage(), dve);
throw new PlatformDataIntegrityException("error.msg.cund.unknown.data.integrity.issue",
"Unknown data integrity issue with resource: " + dve.getMostSpecificCause().getMessage());
}
}
private CodeValue retrieveCodeValueBy(final Long codeValueId) {
final CodeValue codeValue = this.codeValueRepository.findOne(codeValueId);
if (codeValue == null) { throw new CodeValueNotFoundException(codeValueId); }
return codeValue;
}
}
@@ -270,6 +270,15 @@ public final class JsonCommand {
return this.fromApiJsonHelper.extractIntegerWithLocaleNamed(parameterName, parsedCommand);
}
public boolean isChangeInIntegerSansLocaleParameterNamed(final String parameterName, final Integer existingValue) {
boolean isChanged = false;
if (parameterExists(parameterName)) {
final Integer workingValue = integerValueSansLocaleOfParameterNamed(parameterName);
isChanged = differenceExists(existingValue, workingValue);
}
return isChanged;
}
public Integer integerValueSansLocaleOfParameterNamed(final String parameterName) {
return this.fromApiJsonHelper.extractIntegerSansLocaleNamed(parameterName, parsedCommand);
}