MIFOSX-47: natus commits around code values.

This commit is contained in:
Natu Lauchande
2012-10-25 23:36:12 +01:00
committed by Keith Woodlock
parent 675cebbbc7
commit e5480dca8d
12 changed files with 385 additions and 1 deletions
@@ -0,0 +1,81 @@
package org.mifosng.platform.api;
import java.util.Collection;
import java.util.Set;
import javax.ws.rs.Consumes;
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;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import org.mifosng.platform.api.commands.CodeCommand;
import org.mifosng.platform.api.data.CodeData;
import org.mifosng.platform.api.data.EntityIdentifier;
import org.mifosng.platform.api.infrastructure.ApiDataConversionService;
import org.mifosng.platform.api.infrastructure.ApiJsonSerializerService;
import org.mifosng.platform.api.infrastructure.ApiParameterHelper;
import org.mifosng.platform.organisation.service.CodeWritePlatformService;
import org.mifosng.platform.organisation.service.CodeReadPlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Path("/codes")
@Component
@Scope("singleton")
public class CodesApiResource {
@Autowired
private CodeReadPlatformService readPlatformService;
@Autowired
private CodeWritePlatformService writePlatformService;
@Autowired
private ApiDataConversionService apiDataConversionService;
@Autowired
private ApiJsonSerializerService apiJsonSerializerService;
@GET
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public String retrieveCodes(@Context final UriInfo uriInfo) {
Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
final Collection<CodeData> codes = this.readPlatformService.retrieveAllCodes();
return this.apiJsonSerializerService.serializeCodeDataToJson(prettyPrint, responseParameters, codes);
}
@POST
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public Response createCode(final String jsonRequestBody) {
final CodeCommand command = this.apiDataConversionService.convertJsonToCodeCommand(null, jsonRequestBody);
final Long id = this.writePlatformService.createCode(command);
return Response.ok().entity(new EntityIdentifier(id)).build();
}
@PUT
@Path("{Id}")
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public Response updateCode(@PathParam("Id") final Long Id, final String jsonRequestBody) {
return null;
}
}
@@ -0,0 +1,33 @@
package org.mifosng.platform.api.commands;
import java.util.Set;
/**
* Immutable command for creating or updating details of a Code in mifos.
*/
public class CodeCommand {
private final Long id;
private final String codeName;
private final Set<String> modifiedParameters;
public CodeCommand(final Set<String> modifiedParameters, final Long id, final String codeName) {
this.modifiedParameters = modifiedParameters;
this.id = id;
this.codeName = codeName;
}
public Long getId() {
return id;
}
public String getCodeName() {
return codeName;
}
public boolean isNameChanged() {
return this.modifiedParameters.contains("codename");
}
}
@@ -0,0 +1,35 @@
package org.mifosng.platform.api.data;
import java.io.Serializable;
public class CodeData implements Serializable {
private Long id;
private String codeName;
public CodeData() {
//
}
public CodeData(final Long id, final String codeName) {
this.id = id;
this.codeName = codeName;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getCodeName() {
return codeName;
}
public void setName(String codeName) {
this.codeName = codeName;
}
}
@@ -5,6 +5,7 @@ import org.mifosng.platform.api.commands.BranchMoneyTransferCommand;
import org.mifosng.platform.api.commands.ChargeCommand;
import org.mifosng.platform.api.commands.ClientCommand;
import org.mifosng.platform.api.commands.ClientIdentifierCommand;
import org.mifosng.platform.api.commands.CodeCommand;
import org.mifosng.platform.api.commands.DepositAccountCommand;
import org.mifosng.platform.api.commands.DepositAccountWithdrawInterestCommand;
import org.mifosng.platform.api.commands.DepositAccountWithdrawalCommand;
@@ -78,4 +79,7 @@ public interface ApiDataConversionService {
DepositAccountWithdrawInterestCommand convertJsonToDepositAccountWithdrawInterestCommand(Long resourceIdentifier, String jsonRequestBody);
ClientIdentifierCommand convertJsonToClientIdentifierCommand(Long resourceIdentifier, Long clientId, String jsonRequestBody);
CodeCommand convertJsonToCodeCommand(Long resourceIdentifier, String json);
}
@@ -22,6 +22,7 @@ import org.mifosng.platform.api.commands.BranchMoneyTransferCommand;
import org.mifosng.platform.api.commands.ChargeCommand;
import org.mifosng.platform.api.commands.ClientCommand;
import org.mifosng.platform.api.commands.ClientIdentifierCommand;
import org.mifosng.platform.api.commands.CodeCommand;
import org.mifosng.platform.api.commands.DepositAccountCommand;
import org.mifosng.platform.api.commands.DepositAccountWithdrawInterestCommand;
import org.mifosng.platform.api.commands.DepositAccountWithdrawalCommand;
@@ -1476,5 +1477,33 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
return new ClientIdentifierCommand(modifiedParameters,resourceIdentifier,clientId,documentTypeId,documentKey,documentDescription);
}
@Override
public CodeCommand convertJsonToCodeCommand(Long resourceIdentifier,String json) {
// TODO Auto-generated method stub
if (StringUtils.isBlank(json)) {
throw new InvalidJsonException();
}
Type typeOfMap = new TypeToken<Map<String, String>>(){}.getType();
Map<String, String> requestMap = gsonConverter.fromJson(json, typeOfMap);
Set<String> supportedParams = new HashSet<String>(
Arrays.asList("name")
);
checkForUnsupportedParameters(requestMap, supportedParams);
Set<String> modifiedParameters = new HashSet<String>();
String name = extractStringParameter("name", requestMap, modifiedParameters);
return new CodeCommand(modifiedParameters, resourceIdentifier, name);
}
}
@@ -11,6 +11,7 @@ import org.mifosng.platform.api.data.ChargeData;
import org.mifosng.platform.api.data.ClientAccountSummaryCollectionData;
import org.mifosng.platform.api.data.ClientData;
import org.mifosng.platform.api.data.ClientIdentifierData;
import org.mifosng.platform.api.data.CodeData;
import org.mifosng.platform.api.data.ConfigurationData;
import org.mifosng.platform.api.data.DatatableData;
import org.mifosng.platform.api.data.DepositAccountData;
@@ -33,6 +34,8 @@ import org.mifosng.platform.api.data.RoleData;
import org.mifosng.platform.api.data.SavingProductData;
import org.mifosng.platform.api.data.StaffData;
import com.google.gson.Gson;
public interface ApiJsonSerializerService {
String serializeAuthenticatedUserDataToJson(boolean prettyPrint, AuthenticatedUserData authenticatedUserData);
@@ -125,4 +128,8 @@ public interface ApiJsonSerializerService {
String serializeDocumentDataToJson(boolean prettyPrint, Set<String> responseParameters, DocumentData documentData);
String serializeCodeDataToJson(boolean prettyPrint,Set<String> responseParameters, Collection<CodeData> codes);
String serializeCodeDataToJson(boolean prettyPrint,Set<String> responseParameters, CodeData code);
}
@@ -13,6 +13,7 @@ import org.mifosng.platform.api.data.ChargeData;
import org.mifosng.platform.api.data.ClientAccountSummaryCollectionData;
import org.mifosng.platform.api.data.ClientData;
import org.mifosng.platform.api.data.ClientIdentifierData;
import org.mifosng.platform.api.data.CodeData;
import org.mifosng.platform.api.data.ConfigurationData;
import org.mifosng.platform.api.data.DatatableData;
import org.mifosng.platform.api.data.DepositAccountData;
@@ -194,6 +195,9 @@ public class GoogleGsonApiJsonSerializerService implements ApiJsonSerializerServ
private static final Set<String> LOAN_CHARGES_DATA_PARAMETERS = new HashSet<String>(
Arrays.asList("chargeOptions"));
private static final Set<String> CODE_DATA_PARAMETERS = new HashSet<String>(
Arrays.asList("id", "codename"));
private final GoogleGsonSerializerHelper helper;
@@ -662,4 +666,24 @@ public class GoogleGsonApiJsonSerializerService implements ApiJsonSerializerServ
DOCUMENT_DATA_PARAMETERS, prettyPrint, responseParameters);
return helper.serializedJsonFrom(gsonDeserializer, documentData);
}
@Override
public String serializeCodeDataToJson(boolean prettyPrint,
Set<String> responseParameters, Collection<CodeData> codes) {
final Gson gsonDeserializer = helper
.createGsonBuilderWithParameterExclusionSerializationStrategy(
CODE_DATA_PARAMETERS, prettyPrint, responseParameters);
return helper.serializedJsonFrom(gsonDeserializer,
codes.toArray(new CodeData[codes.size()]));
}
@Override
public String serializeCodeDataToJson(boolean prettyPrint,
Set<String> responseParameters, CodeData code) {
final Gson gsonDeserializer = helper
.createGsonBuilderWithParameterExclusionSerializationStrategy(
CODE_DATA_PARAMETERS, prettyPrint, responseParameters);
return helper.serializedJsonFrom(gsonDeserializer, code);
}
}
@@ -3,7 +3,7 @@ package org.mifosng.platform.organisation.domain;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
public interface CodeRepository extends JpaRepository<Office, Long>,
public interface CodeRepository extends JpaRepository<Code, Long>,
JpaSpecificationExecutor<Code> {
// no added behaviour
}
@@ -0,0 +1,11 @@
package org.mifosng.platform.organisation.service;
import java.util.Collection;
import org.mifosng.platform.api.data.CodeData;
public interface CodeReadPlatformService {
Collection<CodeData> retrieveAllCodes();
CodeData retrieveCode(Long codeId);
}
@@ -0,0 +1,77 @@
package org.mifosng.platform.organisation.service;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;
import org.mifosng.platform.api.data.CodeData;
import org.mifosng.platform.api.data.FundData;
import org.mifosng.platform.exceptions.FundNotFoundException;
import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource;
import org.mifosng.platform.security.PlatformSecurityContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;
@Service
public class CodeReadPlatformServiceImpl implements CodeReadPlatformService {
private final JdbcTemplate jdbcTemplate;
private final PlatformSecurityContext context;
@Autowired
public CodeReadPlatformServiceImpl(final PlatformSecurityContext context,
final TenantAwareRoutingDataSource dataSource) {
this.context = context;
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
private static final class CodeMapper implements RowMapper<CodeData> {
public String schema() {
return " c.id as id, c.code_name as code_name from m_code c ";
}
@Override
public CodeData mapRow(final ResultSet rs, final int rowNum)
throws SQLException {
Long id = rs.getLong("id");
String code_name = rs.getString("code_name");
return new CodeData(id, code_name);
}
}
@Override
public Collection<CodeData> retrieveAllCodes()
{
context.authenticatedUser();
CodeMapper rm = new CodeMapper();
String sql = "select "
+ rm.schema()
+ " order by c.code_name";
return this.jdbcTemplate.query(sql,rm,new Object[] {} );
}
@Override
public CodeData retrieveCode(Long codeId)
{
try {
context.authenticatedUser();
CodeMapper rm = new CodeMapper();
String sql = "select " + rm.schema() + " where c.id = ?";
CodeData selectedCode = this.jdbcTemplate.queryForObject(sql, rm, new Object[] {codeId});
return selectedCode;
} catch (EmptyResultDataAccessException e) {
throw new FundNotFoundException(codeId);
}
}
}
@@ -0,0 +1,13 @@
package org.mifosng.platform.organisation.service;
import org.mifosng.platform.api.commands.CodeCommand;
import org.springframework.security.access.prepost.PreAuthorize;
public interface CodeWritePlatformService {
@PreAuthorize(value = "hasRole('ORGANISATION_ADMINISTRATION_SUPER_USER_ROLE')")
Long createCode(final CodeCommand command);
@PreAuthorize(value = "hasRole('ORGANISATION_ADMINISTRATION_SUPER_USER_ROLE')")
Long updateCode(final CodeCommand command);
}
@@ -0,0 +1,70 @@
package org.mifosng.platform.organisation.service;
import org.mifosng.platform.api.commands.CodeCommand;
import org.mifosng.platform.api.commands.FundCommand;
import org.mifosng.platform.organisation.domain.Code;
import org.mifosng.platform.organisation.domain.CodeRepository;
import org.mifosng.platform.exceptions.FundNotFoundException;
import org.mifosng.platform.exceptions.PlatformDataIntegrityException;
import org.mifosng.platform.fund.domain.Fund;
import org.mifosng.platform.fund.domain.FundRepository;
import org.mifosng.platform.security.PlatformSecurityContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class CodeWritePlatformServiceJpaRepositoryImpl implements CodeWritePlatformService {
private final static Logger logger = LoggerFactory.getLogger(CodeWritePlatformServiceJpaRepositoryImpl.class);
private final PlatformSecurityContext context;
private final CodeRepository codeRepository;
@Autowired
public CodeWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final CodeRepository codeRepository) {
this.context = context;
this.codeRepository = codeRepository;
}
@Transactional
@Override
public Long createCode(final CodeCommand command) {
try {
context.authenticatedUser();
Code code = Code.createNew(command.getCodeName());
this.codeRepository.saveAndFlush(code);
return code.getId();
} catch (DataIntegrityViolationException dve) {
return Long.valueOf(-1);
}
}
@Transactional
@Override
public Long updateCode(final CodeCommand command) {
/**
* TODO
**/
return null;
}
/*
* Guaranteed to throw an exception no matter what the data integrity issue is.
*/
private void handleCodeDataIntegrityIssues(final FundCommand command, DataIntegrityViolationException dve) {
}
}