MIFOSX-237: api doc changes and ensure error handling supported is added back in for datatables api.
This commit is contained in:
+142
-49
@@ -8126,21 +8126,20 @@ GET https://DomainName/api/v1/datatables
|
||||
POST https://DomainName/api/v1/datatables/register/{datatable}/{apptable}
|
||||
</code>
|
||||
<code class="method-request">
|
||||
POST datatables/register/userDefinedTableName/m_client
|
||||
POST datatables/register/extra_client_details/m_client
|
||||
|
||||
Content-Type: application/json
|
||||
Request Body:
|
||||
{}
|
||||
</code>
|
||||
<code class="method-response">
|
||||
{
|
||||
"resourceId": null
|
||||
{
|
||||
"resourceIdentifier": "extra_client_details"
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<a id="datatables_deregister" name="datatables_deregister"
|
||||
class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
@@ -8154,7 +8153,7 @@ Request Body:
|
||||
POST https://DomainName/api/v1/datatables/deregister/{datatable}
|
||||
</code>
|
||||
<code class="method-request">
|
||||
POST datatables/deregister/userDefinedTableName
|
||||
POST datatables/deregister/extra_client_details
|
||||
|
||||
Content-Type: application/json
|
||||
Request Body:
|
||||
@@ -8162,8 +8161,8 @@ Request Body:
|
||||
</code>
|
||||
<code class="method-response">
|
||||
{
|
||||
"resourceId": null
|
||||
}
|
||||
"resourceIdentifier": "extra_client_details"
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
@@ -8186,20 +8185,20 @@ Request Body:
|
||||
POST https://DomainName/api/v1/datatables/{datatable}/{apptableId}
|
||||
</code>
|
||||
<code class="method-request">
|
||||
POST datatables/Additional Client Fields Data/1
|
||||
POST datatables/extra_client_details/1
|
||||
|
||||
Content-Type: application/json
|
||||
Request Body:
|
||||
{
|
||||
"Business Description": "Livestock sales",
|
||||
Comment: "First comment\nmade",
|
||||
Education_cv: "Trade",
|
||||
Gender_cd: "21",
|
||||
"Comment": "First comment made",
|
||||
"Education_cv": "Primary",
|
||||
"Gender_cd": "6",
|
||||
"Highest Rate Paid": "8.5",
|
||||
"Next Visit": "01 October 2012",
|
||||
"Years in Business": "5",
|
||||
dateFormat: "dd MMMM yyyy",
|
||||
locale: "en"
|
||||
"dateFormat": "dd MMMM yyyy",
|
||||
"locale": "en"
|
||||
}
|
||||
</code>
|
||||
<code class="method-response">
|
||||
@@ -8235,46 +8234,142 @@ Request Body:
|
||||
<dd>
|
||||
<span>optional</span>
|
||||
</dd>
|
||||
<dd>If 'true' a Generic Result Set JSON format is returned.
|
||||
<dd>If 'true' an optimised JSON format is returned suitable for tabular display of data.
|
||||
This format is used by the default data tables UI functionality.</dd>
|
||||
</dl>
|
||||
|
||||
<p>Example Requests:</p>
|
||||
<div class=apiClick>datatables/Additional Client Fields
|
||||
Data/1</div>
|
||||
<div class=apiClick>datatables/extra_client_details/1</div>
|
||||
<br>
|
||||
<br>
|
||||
<div class=apiClick>datatables/Extra Family Details
|
||||
Data/1?order=`Date of Birth` desc</div>
|
||||
<div class=apiClick>datatables/extra_family_details/1?order=`Date of Birth` desc</div>
|
||||
<br>
|
||||
<br>
|
||||
<div class=apiClick>datatables/Additional Client Fields
|
||||
Data/1?genericResultSet=true</div>
|
||||
<div class=apiClick>datatables/extra_client_details/1?genericResultSet=true</div>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">
|
||||
GET https://DomainName/api/v1/datatables/{datatable}/{apptableId}
|
||||
GET https://DomainName/api/v1/datatables/{datatable}/{apptableId}?genericResultSet=true
|
||||
</code>
|
||||
<code class="method-response">
|
||||
[
|
||||
{
|
||||
"client_id": 1,
|
||||
"Business Description": "Livestock sales",
|
||||
"Years in Business": 5,
|
||||
"Gender_cd": "21",
|
||||
"Education_cv": "Trade",
|
||||
"Next Visit": [2012, 10, 1],
|
||||
"Highest Rate Paid": 8.500000,
|
||||
"Comment": "First comment made"
|
||||
}
|
||||
]
|
||||
"columnHeaders": [
|
||||
{
|
||||
"columnName": "client_id",
|
||||
"columnType": "bigint",
|
||||
"columnLength": 0,
|
||||
"columnDisplayType": "INTEGER",
|
||||
"isColumnNullable": false,
|
||||
"isColumnPrimaryKey": true,
|
||||
"columnValues": []
|
||||
},
|
||||
{
|
||||
"columnName": "Business Description",
|
||||
"columnType": "varchar",
|
||||
"columnLength": 100,
|
||||
"columnDisplayType": "STRING",
|
||||
"isColumnNullable": true,
|
||||
"isColumnPrimaryKey": false,
|
||||
"columnValues": []
|
||||
},
|
||||
{
|
||||
"columnName": "Years in Business",
|
||||
"columnType": "int",
|
||||
"columnLength": 0,
|
||||
"columnDisplayType": "INTEGER",
|
||||
"isColumnNullable": true,
|
||||
"isColumnPrimaryKey": false,
|
||||
"columnValues": []
|
||||
},
|
||||
{
|
||||
"columnName": "Gender_cd",
|
||||
"columnType": "int",
|
||||
"columnLength": 0,
|
||||
"columnDisplayType": "CODELOOKUP",
|
||||
"isColumnNullable": true,
|
||||
"isColumnPrimaryKey": false,
|
||||
"columnValues": [
|
||||
{
|
||||
"id": 5,
|
||||
"value": "option.Male"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"value": "option.Female"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"columnName": "Education_cv",
|
||||
"columnType": "varchar",
|
||||
"columnLength": 60,
|
||||
"columnDisplayType": "CODEVALUE",
|
||||
"isColumnNullable": true,
|
||||
"isColumnPrimaryKey": false,
|
||||
"columnValues": [
|
||||
{
|
||||
"id": 9,
|
||||
"value": "Primary"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"value": "Secondary"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"value": "University"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"columnName": "Next Visit",
|
||||
"columnType": "date",
|
||||
"columnLength": 0,
|
||||
"columnDisplayType": "DATE",
|
||||
"isColumnNullable": true,
|
||||
"isColumnPrimaryKey": false,
|
||||
"columnValues": []
|
||||
},
|
||||
{
|
||||
"columnName": "Highest Rate Paid",
|
||||
"columnType": "decimal",
|
||||
"columnLength": 0,
|
||||
"columnDisplayType": "DECIMAL",
|
||||
"isColumnNullable": true,
|
||||
"isColumnPrimaryKey": false,
|
||||
"columnValues": []
|
||||
},
|
||||
{
|
||||
"columnName": "Comment",
|
||||
"columnType": "text",
|
||||
"columnLength": 65535,
|
||||
"columnDisplayType": "TEXT",
|
||||
"isColumnNullable": true,
|
||||
"isColumnPrimaryKey": false,
|
||||
"columnValues": []
|
||||
}
|
||||
],
|
||||
"data": [
|
||||
{
|
||||
"row": [
|
||||
"1",
|
||||
"Livestock sales",
|
||||
"5",
|
||||
"6",
|
||||
"Primary",
|
||||
"2012-10-01",
|
||||
"8.500000",
|
||||
"First\tcomment made"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<a id="datatables_update" name="datatables_update"
|
||||
class="old-syle-anchor"> </a>
|
||||
<a id="datatables_update" name="datatables_update" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h4>Update Entry in Data Table (One to One)</h4>
|
||||
@@ -8285,23 +8380,22 @@ GET https://DomainName/api/v1/datatables/{datatable}/{apptableId}
|
||||
PUT https://DomainName/api/v1/datatables/{datatable}/{apptableId}
|
||||
</code>
|
||||
<code class="method-request">
|
||||
PUT datatables/Additional Client Fields Data/1
|
||||
PUT datatables/extra_client_details/1
|
||||
|
||||
Content-Type: application/json
|
||||
Request Body:
|
||||
{
|
||||
"Business Description": "Livestock sales updated",
|
||||
Comment: "First comment\nmade",
|
||||
Education_cv: "Trade",
|
||||
Gender_cd: "21",
|
||||
"Highest Rate Paid": "8.5",
|
||||
"Next Visit": "01 October 2012",
|
||||
"Years in Business": "5",
|
||||
dateFormat: "dd MMMM yyyy",
|
||||
locale: "en"
|
||||
}
|
||||
{
|
||||
"Business Description": "Livestock sales updated",
|
||||
}
|
||||
</code>
|
||||
<code class="method-response">
|
||||
{
|
||||
"resourceId": 1,
|
||||
"changes": {
|
||||
"Business Description": "Livestock sales updated"
|
||||
}
|
||||
}
|
||||
</code>
|
||||
<code class="method-response">{ "resourceId": 1 } </code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -8385,8 +8479,7 @@ Request Body:
|
||||
<code class="method-response">{ "resourceId": 1 } </code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- start of datatables api docs -->
|
||||
<!-- end of datatables api docs -->
|
||||
|
||||
<!-- start of Notes api docs -->
|
||||
<a id="notes" name="notes" class="old-syle-anchor"> </a>
|
||||
|
||||
+25
-7
@@ -19,13 +19,17 @@ public class CommandProcessingResult {
|
||||
private final Long groupId;
|
||||
private final Long clientId;
|
||||
private final Long loanId;
|
||||
private Long resourceId;
|
||||
private final Long resourceId;
|
||||
private final String transactionId;
|
||||
private Map<String, Object> changes;
|
||||
private final Map<String, Object> changes;
|
||||
@SuppressWarnings("unused")
|
||||
private final String resourceIdentifier;
|
||||
|
||||
public static CommandProcessingResult fromDetails(final Long commandId, final Long officeId, final Long groupId, final Long clientId,
|
||||
final Long loanId, final Long entityId, final String transactionId, final Map<String, Object> changes) {
|
||||
return new CommandProcessingResult(commandId, officeId, groupId, clientId, loanId, entityId, transactionId, changes);
|
||||
final Long loanId, final String resourceIdentifier, final Long entityId, final String transactionId,
|
||||
final Map<String, Object> changes) {
|
||||
return new CommandProcessingResult(commandId, officeId, groupId, clientId, loanId, resourceIdentifier, entityId, transactionId,
|
||||
changes);
|
||||
}
|
||||
|
||||
public static CommandProcessingResult commandOnlyResult(final Long commandId) {
|
||||
@@ -54,10 +58,18 @@ public class CommandProcessingResult {
|
||||
}
|
||||
|
||||
public static CommandProcessingResult empty() {
|
||||
return new CommandProcessingResult(Long.valueOf(-1), Long.valueOf(-1), Long.valueOf(-1), null);
|
||||
return new CommandProcessingResult(null, null, null, null);
|
||||
}
|
||||
|
||||
/*
|
||||
* Deprecated
|
||||
*/
|
||||
public CommandProcessingResult(final Long entityId) {
|
||||
if (entityId != null) {
|
||||
this.resourceIdentifier = entityId.toString();
|
||||
} else {
|
||||
this.resourceIdentifier = null;
|
||||
}
|
||||
this.resourceId = entityId;
|
||||
this.officeId = null;
|
||||
this.groupId = null;
|
||||
@@ -68,18 +80,24 @@ public class CommandProcessingResult {
|
||||
}
|
||||
|
||||
private CommandProcessingResult(final Long commandId, final Long officeId, final Long groupId, final Long clientId, final Long loanId,
|
||||
final Long resourceId, final String transactionId, final Map<String, Object> changesOnly) {
|
||||
final String resourceIdentifier, final Long resourceId, final String transactionId, final Map<String, Object> changesOnly) {
|
||||
this.commandId = commandId;
|
||||
this.officeId = officeId;
|
||||
this.groupId = groupId;
|
||||
this.clientId = clientId;
|
||||
this.loanId = loanId;
|
||||
this.resourceIdentifier = resourceIdentifier;
|
||||
this.resourceId = resourceId;
|
||||
this.changes = changesOnly;
|
||||
this.transactionId = transactionId;
|
||||
}
|
||||
|
||||
private CommandProcessingResult(final Long resourceId, final Long officeId, final Long commandId, final Map<String, Object> changesOnly) {
|
||||
if (resourceId != null) {
|
||||
this.resourceIdentifier = resourceId.toString();
|
||||
} else {
|
||||
this.resourceIdentifier = null;
|
||||
}
|
||||
this.resourceId = resourceId;
|
||||
this.officeId = officeId;
|
||||
this.groupId = null;
|
||||
@@ -102,7 +120,7 @@ public class CommandProcessingResult {
|
||||
return this.officeId;
|
||||
}
|
||||
|
||||
public void setOfficeId(Long officeId) {
|
||||
public void setOfficeId(final Long officeId) {
|
||||
this.officeId = officeId;
|
||||
}
|
||||
|
||||
|
||||
+8
-1
@@ -18,12 +18,14 @@ public class CommandProcessingResultBuilder {
|
||||
private Long groupId;
|
||||
private Long clientId;
|
||||
private Long loanId;
|
||||
private String resourceIdentifier;
|
||||
private Long entityId;
|
||||
private String transactionId;
|
||||
private Map<String, Object> changes;
|
||||
|
||||
public CommandProcessingResult build() {
|
||||
return CommandProcessingResult.fromDetails(commandId, officeId, groupId, clientId, loanId, entityId, transactionId, changes);
|
||||
return CommandProcessingResult.fromDetails(commandId, officeId, groupId, clientId, loanId, resourceIdentifier, entityId,
|
||||
transactionId, changes);
|
||||
}
|
||||
|
||||
public CommandProcessingResultBuilder withCommandId(final Long withCommandId) {
|
||||
@@ -36,6 +38,11 @@ public class CommandProcessingResultBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandProcessingResultBuilder withResourceIdAsString(final String withResourceIdentifier) {
|
||||
this.resourceIdentifier = withResourceIdentifier;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandProcessingResultBuilder withEntityId(final Long withEntityId) {
|
||||
this.entityId = withEntityId;
|
||||
return this;
|
||||
|
||||
+10
-5
@@ -25,6 +25,7 @@ import org.mifosplatform.commands.service.CommandWrapperBuilder;
|
||||
import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService;
|
||||
import org.mifosplatform.infrastructure.core.api.ApiParameterHelper;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
|
||||
import org.mifosplatform.infrastructure.core.serialization.ToApiJsonSerializer;
|
||||
import org.mifosplatform.infrastructure.dataqueries.data.DatatableData;
|
||||
import org.mifosplatform.infrastructure.dataqueries.data.GenericResultsetData;
|
||||
@@ -38,7 +39,7 @@ import org.springframework.stereotype.Component;
|
||||
@Path("/datatables")
|
||||
@Component
|
||||
@Scope("singleton")
|
||||
public class DataTableApiResource {
|
||||
public class DatatablesApiResource {
|
||||
|
||||
private final PlatformSecurityContext context;
|
||||
private final GenericDataService genericDataService;
|
||||
@@ -47,7 +48,7 @@ public class DataTableApiResource {
|
||||
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
|
||||
|
||||
@Autowired
|
||||
public DataTableApiResource(final PlatformSecurityContext context, final GenericDataService genericDataService,
|
||||
public DatatablesApiResource(final PlatformSecurityContext context, final GenericDataService genericDataService,
|
||||
final ReadWriteNonCoreDataService readWriteNonCoreDataService,
|
||||
final ToApiJsonSerializer<GenericResultsetData> toApiJsonSerializer,
|
||||
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) {
|
||||
@@ -77,7 +78,9 @@ public class DataTableApiResource {
|
||||
|
||||
this.readWriteNonCoreDataService.registerDatatable(datatable, apptable);
|
||||
|
||||
return this.toApiJsonSerializer.serialize(CommandProcessingResult.empty());
|
||||
final CommandProcessingResult result = new CommandProcessingResultBuilder().withResourceIdAsString(datatable).build();
|
||||
|
||||
return this.toApiJsonSerializer.serialize(result);
|
||||
}
|
||||
|
||||
@POST
|
||||
@@ -88,7 +91,9 @@ public class DataTableApiResource {
|
||||
|
||||
this.readWriteNonCoreDataService.deregisterDatatable(datatable);
|
||||
|
||||
return this.toApiJsonSerializer.serialize(CommandProcessingResult.empty());
|
||||
final CommandProcessingResult result = new CommandProcessingResultBuilder().withResourceIdAsString(datatable).build();
|
||||
|
||||
return this.toApiJsonSerializer.serialize(result);
|
||||
}
|
||||
|
||||
@GET
|
||||
@@ -143,7 +148,7 @@ public class DataTableApiResource {
|
||||
@Path("{datatable}/{apptableId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String newDatatableEntry(@PathParam("datatable") final String datatable, @PathParam("apptableId") final Long apptableId,
|
||||
public String createDatatableEntry(@PathParam("datatable") final String datatable, @PathParam("apptableId") final Long apptableId,
|
||||
final String apiRequestBodyAsJson) {
|
||||
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().createDatatable(datatable, apptableId, null)
|
||||
+8
-10
@@ -10,15 +10,13 @@ import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceN
|
||||
/**
|
||||
* A {@link RuntimeException} thrown when client resources are not found.
|
||||
*/
|
||||
public class DataTableNotFoundException extends AbstractPlatformResourceNotFoundException {
|
||||
public class DatatableNotFoundException extends AbstractPlatformResourceNotFoundException {
|
||||
|
||||
public DataTableNotFoundException(final String datatable, Long id) {
|
||||
super("error.msg.datatable.data.not.found", "Data Not Found for Data Table: ",
|
||||
datatable + " Id:" + id);
|
||||
}
|
||||
|
||||
public DataTableNotFoundException(final String datatable) {
|
||||
super("error.msg.datatable.not.found", "Data Table Not Found",
|
||||
datatable);
|
||||
}
|
||||
public DatatableNotFoundException(final String datatable, final Long id) {
|
||||
super("error.msg.datatable.data.not.found", "Data not found for datatable: ", datatable + " Id:" + id);
|
||||
}
|
||||
|
||||
public DatatableNotFoundException(final String datatable) {
|
||||
super("error.msg.datatable.not.found", "Datatable not found.", datatable);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -13,6 +13,6 @@ import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceN
|
||||
public class ReportNotFoundException extends AbstractPlatformResourceNotFoundException {
|
||||
|
||||
public ReportNotFoundException(final String reportSql) {
|
||||
super("error.msg.report.name.not.found", "Reporting Meta Data Entry Not Found", "Input Sql: " + reportSql);
|
||||
super("error.msg.report.name.not.found", "Reporting meta-data entry not found.", "Input sql: " + reportSql);
|
||||
}
|
||||
}
|
||||
+1
-3
@@ -12,7 +12,6 @@ import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder
|
||||
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 {
|
||||
@@ -24,11 +23,10 @@ public class CreateDatatableEntryCommandHandler implements NewCommandSourceHandl
|
||||
this.writePlatformService = writePlatformService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
|
||||
this.writePlatformService.newDatatableEntry(command.entityName(), command.getApptableId(), command);
|
||||
this.writePlatformService.createNewDatatableEntry(command.entityName(), command.getApptableId(), command);
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withCommandId(command.commandId()) //
|
||||
|
||||
-2
@@ -20,7 +20,5 @@ public interface GenericDataService {
|
||||
|
||||
String wrapSQL(String sql);
|
||||
|
||||
String getDatabaseName();
|
||||
|
||||
List<ResultsetColumnHeaderData> fillResultsetColumnHeaders(String datatable);
|
||||
}
|
||||
+2
-13
@@ -5,20 +5,18 @@
|
||||
*/
|
||||
package org.mifosplatform.infrastructure.dataqueries.service;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException;
|
||||
import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource;
|
||||
import org.mifosplatform.infrastructure.dataqueries.data.GenericResultsetData;
|
||||
import org.mifosplatform.infrastructure.dataqueries.data.ResultsetColumnHeaderData;
|
||||
import org.mifosplatform.infrastructure.dataqueries.data.ResultsetColumnValueData;
|
||||
import org.mifosplatform.infrastructure.dataqueries.data.ResultsetRowData;
|
||||
import org.mifosplatform.infrastructure.dataqueries.exception.DataTableNotFoundException;
|
||||
import org.mifosplatform.infrastructure.dataqueries.exception.DatatableNotFoundException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.support.rowset.SqlRowSet;
|
||||
@@ -168,15 +166,6 @@ public class GenericDataServiceImpl implements GenericDataService {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDatabaseName() {
|
||||
try {
|
||||
return dataSource.getConnection().getCatalog();
|
||||
} catch (SQLException e) {
|
||||
throw new PlatformDataIntegrityException("error.msg.sql.error", e.getMessage(), "Error Accessing Database Name");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ResultsetColumnHeaderData> fillResultsetColumnHeaders(final String datatable) {
|
||||
|
||||
@@ -249,6 +238,6 @@ public class GenericDataServiceImpl implements GenericDataService {
|
||||
final SqlRowSet columnDefinitions = this.jdbcTemplate.queryForRowSet(sql);
|
||||
if (columnDefinitions.next()) { return columnDefinitions; }
|
||||
|
||||
throw new DataTableNotFoundException(datatable);
|
||||
throw new DatatableNotFoundException(datatable);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -25,7 +25,7 @@ public interface ReadWriteNonCoreDataService {
|
||||
|
||||
GenericResultsetData retrieveDataTableGenericResultSet(String datatable, Long appTableId, String order, Long id);
|
||||
|
||||
void newDatatableEntry(String datatable, Long appTableId, JsonCommand command);
|
||||
void createNewDatatableEntry(String datatable, Long appTableId, JsonCommand command);
|
||||
|
||||
Map<String, Object> updateDatatableEntryOneToOne(String datatable, Long appTableId, JsonCommand command);
|
||||
|
||||
|
||||
+121
-68
@@ -17,6 +17,7 @@ import java.util.Set;
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.hibernate.exception.ConstraintViolationException;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
|
||||
@@ -29,12 +30,14 @@ import org.mifosplatform.infrastructure.dataqueries.data.DatatableData;
|
||||
import org.mifosplatform.infrastructure.dataqueries.data.GenericResultsetData;
|
||||
import org.mifosplatform.infrastructure.dataqueries.data.ResultsetColumnHeaderData;
|
||||
import org.mifosplatform.infrastructure.dataqueries.data.ResultsetRowData;
|
||||
import org.mifosplatform.infrastructure.dataqueries.exception.DataTableNotFoundException;
|
||||
import org.mifosplatform.infrastructure.dataqueries.exception.DatatableNotFoundException;
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.mifosplatform.useradministration.domain.AppUser;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.support.rowset.SqlRowSet;
|
||||
import org.springframework.jdbc.support.rowset.SqlRowSetMetaData;
|
||||
@@ -96,63 +99,89 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
||||
return datatables;
|
||||
}
|
||||
|
||||
private void logAsErrorUnexpectedDataIntegrityException(final Exception dve) {
|
||||
logger.error(dve.getMessage(), dve);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerDatatable(final String datatable, final String appTable) {
|
||||
public void registerDatatable(final String dataTableName, final String applicationTableName) {
|
||||
|
||||
validateAppTable(appTable);
|
||||
// FIXME - KW - hardcoded supported app tables are m_loan or m_client?
|
||||
validateAppTable(applicationTableName);
|
||||
|
||||
final String createPermission = "'CREATE_" + datatable + "'";
|
||||
final String createPermissionChecker = "'CREATE_" + datatable + "_CHECKER'";
|
||||
final String readPermission = "'READ_" + datatable + "'";
|
||||
final String updatePermission = "'UPDATE_" + datatable + "'";
|
||||
final String updatePermissionChecker = "'UPDATE_" + datatable + "_CHECKER'";
|
||||
final String deletePermission = "'DELETE_" + datatable + "'";
|
||||
final String deletePermissionChecker = "'DELETE_" + datatable + "_CHECKER'";
|
||||
try {
|
||||
// TODO - JW - put in batch command later
|
||||
final String registerDatatableSql = "insert into x_registered_table (registered_table_name, application_table_name) values ('"
|
||||
+ dataTableName + "', '" + applicationTableName + "')";
|
||||
|
||||
// TODO - JW - put in batch command later
|
||||
final String registerDatatableSql = "insert into x_registered_table (registered_table_name, application_table_name) values ('"
|
||||
+ datatable + "', '" + appTable + "')";
|
||||
this.jdbcTemplate.update(registerDatatableSql);
|
||||
} catch (DataIntegrityViolationException dve) {
|
||||
Throwable realCause = dve.getMostSpecificCause();
|
||||
if (realCause.getMessage().contains("Duplicate entry")) { throw new PlatformDataIntegrityException(
|
||||
"error.msg.datatable.registered", "Datatable `" + dataTableName
|
||||
+ "` is already registered against an application table.", "dataTableName", dataTableName); }
|
||||
|
||||
this.jdbcTemplate.update(registerDatatableSql);
|
||||
logAsErrorUnexpectedDataIntegrityException(dve);
|
||||
throw new PlatformDataIntegrityException("error.msg.unknown.data.integrity.issue",
|
||||
"Unknown data integrity issue with resource.");
|
||||
}
|
||||
|
||||
final String permissionsSql = "insert into m_permission (grouping, code, action_name, entity_name, can_maker_checker) values "
|
||||
+ "('datatable', "
|
||||
+ createPermission
|
||||
+ ", 'CREATE', '"
|
||||
+ datatable
|
||||
+ "', true),"
|
||||
+ "('datatable', "
|
||||
+ createPermissionChecker
|
||||
+ ", 'CREATE', '"
|
||||
+ datatable
|
||||
+ "', false),"
|
||||
+ "('datatable', "
|
||||
+ readPermission
|
||||
+ ", 'READ', '"
|
||||
+ datatable
|
||||
+ "', false),"
|
||||
+ "('datatable', "
|
||||
+ updatePermission
|
||||
+ ", 'UPDATE', '"
|
||||
+ datatable
|
||||
+ "', true),"
|
||||
+ "('datatable', "
|
||||
+ updatePermissionChecker
|
||||
+ ", 'UPDATE', '"
|
||||
+ datatable
|
||||
+ "', false),"
|
||||
+ "('datatable', "
|
||||
+ deletePermission
|
||||
+ ", 'DELETE', '"
|
||||
+ datatable
|
||||
+ "', true),"
|
||||
+ "('datatable', "
|
||||
+ deletePermissionChecker
|
||||
+ ", 'DELETE', '"
|
||||
+ datatable
|
||||
+ "', false)";
|
||||
try {
|
||||
final String createPermission = "'CREATE_" + dataTableName + "'";
|
||||
final String createPermissionChecker = "'CREATE_" + dataTableName + "_CHECKER'";
|
||||
final String readPermission = "'READ_" + dataTableName + "'";
|
||||
final String updatePermission = "'UPDATE_" + dataTableName + "'";
|
||||
final String updatePermissionChecker = "'UPDATE_" + dataTableName + "_CHECKER'";
|
||||
final String deletePermission = "'DELETE_" + dataTableName + "'";
|
||||
final String deletePermissionChecker = "'DELETE_" + dataTableName + "_CHECKER'";
|
||||
|
||||
this.jdbcTemplate.update(permissionsSql);
|
||||
final String permissionsSql = "insert into m_permission (grouping, code, action_name, entity_name, can_maker_checker) values "
|
||||
+ "('datatable', "
|
||||
+ createPermission
|
||||
+ ", 'CREATE', '"
|
||||
+ dataTableName
|
||||
+ "', true),"
|
||||
+ "('datatable', "
|
||||
+ createPermissionChecker
|
||||
+ ", 'CREATE', '"
|
||||
+ dataTableName
|
||||
+ "', false),"
|
||||
+ "('datatable', "
|
||||
+ readPermission
|
||||
+ ", 'READ', '"
|
||||
+ dataTableName
|
||||
+ "', false),"
|
||||
+ "('datatable', "
|
||||
+ updatePermission
|
||||
+ ", 'UPDATE', '"
|
||||
+ dataTableName
|
||||
+ "', true),"
|
||||
+ "('datatable', "
|
||||
+ updatePermissionChecker
|
||||
+ ", 'UPDATE', '"
|
||||
+ dataTableName
|
||||
+ "', false),"
|
||||
+ "('datatable', "
|
||||
+ deletePermission
|
||||
+ ", 'DELETE', '"
|
||||
+ dataTableName
|
||||
+ "', true),"
|
||||
+ "('datatable', "
|
||||
+ deletePermissionChecker
|
||||
+ ", 'DELETE', '"
|
||||
+ dataTableName + "', false)";
|
||||
|
||||
this.jdbcTemplate.update(permissionsSql);
|
||||
} catch (DataIntegrityViolationException dve) {
|
||||
Throwable realCause = dve.getMostSpecificCause();
|
||||
if (realCause.getMessage().contains("Duplicate entry")) { throw new PlatformDataIntegrityException(
|
||||
"error.msg.permissions.datatable.duplicate", "Permissions for datatable `" + dataTableName + "` already exist.",
|
||||
"dataTableName", dataTableName); }
|
||||
|
||||
logAsErrorUnexpectedDataIntegrityException(dve);
|
||||
throw new PlatformDataIntegrityException("error.msg.unknown.data.integrity.issue",
|
||||
"Unknown data integrity issue with resource.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -161,29 +190,53 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
||||
final String permissionList = "('CREATE_" + datatable + "', 'CREATE_" + datatable + "_CHECKER', 'READ_" + datatable + "', 'UPDATE_"
|
||||
+ datatable + "', 'UPDATE_" + datatable + "_CHECKER', 'DELETE_" + datatable + "', 'DELETE_" + datatable + "_CHECKER')";
|
||||
|
||||
String sql = "delete from m_role_permission where m_role_permission.permission_id in (select id from m_permission where code in "
|
||||
final String deleteRolePermissionsSql = "delete from m_role_permission where m_role_permission.permission_id in (select id from m_permission where code in "
|
||||
+ permissionList + ")";
|
||||
this.jdbcTemplate.update(sql);
|
||||
this.jdbcTemplate.update(deleteRolePermissionsSql);
|
||||
|
||||
sql = "delete from m_permission where code in " + permissionList;
|
||||
this.jdbcTemplate.update(sql);
|
||||
final String deletePermissionsSql = "delete from m_permission where code in " + permissionList;
|
||||
this.jdbcTemplate.update(deletePermissionsSql);
|
||||
|
||||
sql = "delete from x_registered_table where registered_table_name = '" + datatable + "'";
|
||||
this.jdbcTemplate.update(sql);
|
||||
final String deleteRegisteredDatatableSql = "delete from x_registered_table where registered_table_name = '" + datatable + "'";
|
||||
this.jdbcTemplate.update(deleteRegisteredDatatableSql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void newDatatableEntry(final String datatable, final Long appTableId, final JsonCommand command) {
|
||||
String appTable = getWithinScopeApplicationTableName(datatable, appTableId);
|
||||
public void createNewDatatableEntry(final String dataTableName, final Long appTableId, final JsonCommand command) {
|
||||
|
||||
final List<ResultsetColumnHeaderData> columnHeaders = this.genericDataService.fillResultsetColumnHeaders(datatable);
|
||||
try {
|
||||
final String appTable = getWithinScopeApplicationTableName(dataTableName, appTableId);
|
||||
|
||||
final Type typeOfMap = new TypeToken<Map<String, String>>() {}.getType();
|
||||
final Map<String, String> dataParams = this.fromJsonHelper.extractDataMap(typeOfMap, command.json());
|
||||
final List<ResultsetColumnHeaderData> columnHeaders = this.genericDataService.fillResultsetColumnHeaders(dataTableName);
|
||||
|
||||
final String sql = getAddSql(columnHeaders, datatable, getFKField(appTable), appTableId, dataParams);
|
||||
final Type typeOfMap = new TypeToken<Map<String, String>>() {}.getType();
|
||||
final Map<String, String> dataParams = this.fromJsonHelper.extractDataMap(typeOfMap, command.json());
|
||||
|
||||
this.jdbcTemplate.update(sql);
|
||||
final String sql = getAddSql(columnHeaders, dataTableName, getFKField(appTable), appTableId, dataParams);
|
||||
|
||||
this.jdbcTemplate.update(sql);
|
||||
} catch (ConstraintViolationException dve) {
|
||||
// NOTE: jdbctemplate throws a
|
||||
// org.hibernate.exception.ConstraintViolationException even though
|
||||
// it should be a DataAccessException?
|
||||
Throwable realCause = dve.getCause();
|
||||
if (realCause.getMessage().contains("Duplicate entry")) { throw new PlatformDataIntegrityException(
|
||||
"error.msg.datatable.entry.duplicate", "An entry already exists for datatable `" + dataTableName
|
||||
+ "` and application table with identifier `" + appTableId + "`.", "dataTableName", dataTableName, appTableId); }
|
||||
|
||||
logAsErrorUnexpectedDataIntegrityException(dve);
|
||||
throw new PlatformDataIntegrityException("error.msg.unknown.data.integrity.issue",
|
||||
"Unknown data integrity issue with resource.");
|
||||
} catch (DataAccessException dve) {
|
||||
Throwable realCause = dve.getMostSpecificCause();
|
||||
if (realCause.getMessage().contains("Duplicate entry")) { throw new PlatformDataIntegrityException(
|
||||
"error.msg.datatable.entry.duplicate", "An entry already exists for datatable `" + dataTableName
|
||||
+ "` and application table with identifier `" + appTableId + "`.", "dataTableName", dataTableName, appTableId); }
|
||||
|
||||
logAsErrorUnexpectedDataIntegrityException(dve);
|
||||
throw new PlatformDataIntegrityException("error.msg.unknown.data.integrity.issue",
|
||||
"Unknown data integrity issue with resource.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -191,7 +244,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
||||
|
||||
GenericResultsetData grs = retrieveDataTableGenericResultSet(datatable, appTableId, null, null);
|
||||
|
||||
if (grs.getData().size() == 0) throw new DataTableNotFoundException(datatable, appTableId);
|
||||
if (grs.getData().size() == 0) throw new DatatableNotFoundException(datatable, appTableId);
|
||||
|
||||
if (grs.getData().size() > 1)
|
||||
throw new PlatformDataIntegrityException("error.msg.attempting.multiple.update", "Application Table: " + datatable
|
||||
@@ -223,7 +276,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
||||
|
||||
final 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);
|
||||
|
||||
final Type typeOfMap = new TypeToken<Map<String, String>>() {}.getType();
|
||||
final Map<String, String> dataParams = this.fromJsonHelper.extractDataMap(typeOfMap, command.json());
|
||||
@@ -296,7 +349,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
||||
|
||||
final SqlRowSet rs = this.jdbcTemplate.queryForRowSet(sql);
|
||||
|
||||
if (!rs.next()) { throw new DataTableNotFoundException(appTable, appTableId); }
|
||||
if (!rs.next()) { throw new DatatableNotFoundException(appTable, appTableId); }
|
||||
}
|
||||
|
||||
private String dataScopedSQL(final String unscopedSQL, final String appTable) {
|
||||
@@ -374,7 +427,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
||||
if (rs.next()) {
|
||||
applicationTableName = rs.getString("application_table_name");
|
||||
} else {
|
||||
throw new DataTableNotFoundException(datatable);
|
||||
throw new DatatableNotFoundException(datatable);
|
||||
}
|
||||
|
||||
return applicationTableName;
|
||||
|
||||
Reference in New Issue
Block a user