WIP data tables
This commit is contained in:
@@ -1,18 +1,28 @@
|
|||||||
package org.mifosng.platform.api;
|
package org.mifosng.platform.api;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.PathParam;
|
||||||
import javax.ws.rs.Produces;
|
import javax.ws.rs.Produces;
|
||||||
import javax.ws.rs.QueryParam;
|
import javax.ws.rs.QueryParam;
|
||||||
|
import javax.ws.rs.WebApplicationException;
|
||||||
import javax.ws.rs.core.Context;
|
import javax.ws.rs.core.Context;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
import javax.ws.rs.core.Response.Status;
|
||||||
import javax.ws.rs.core.UriInfo;
|
import javax.ws.rs.core.UriInfo;
|
||||||
|
|
||||||
|
import org.codehaus.jettison.json.JSONArray;
|
||||||
|
import org.codehaus.jettison.json.JSONException;
|
||||||
|
import org.codehaus.jettison.json.JSONObject;
|
||||||
import org.mifosng.platform.api.data.DatatableData;
|
import org.mifosng.platform.api.data.DatatableData;
|
||||||
|
import org.mifosng.platform.api.data.EntityIdentifier;
|
||||||
import org.mifosng.platform.api.data.GenericResultsetData;
|
import org.mifosng.platform.api.data.GenericResultsetData;
|
||||||
import org.mifosng.platform.api.infrastructure.ApiJsonSerializerService;
|
import org.mifosng.platform.api.infrastructure.ApiJsonSerializerService;
|
||||||
import org.mifosng.platform.api.infrastructure.ApiParameterHelper;
|
import org.mifosng.platform.api.infrastructure.ApiParameterHelper;
|
||||||
@@ -20,6 +30,8 @@ import org.mifosng.platform.exceptions.NoAuthorizationException;
|
|||||||
import org.mifosng.platform.noncore.ReadWriteNonCoreDataService;
|
import org.mifosng.platform.noncore.ReadWriteNonCoreDataService;
|
||||||
import org.mifosng.platform.security.PlatformSecurityContext;
|
import org.mifosng.platform.security.PlatformSecurityContext;
|
||||||
import org.mifosng.platform.user.domain.AppUser;
|
import org.mifosng.platform.user.domain.AppUser;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.annotation.Scope;
|
import org.springframework.context.annotation.Scope;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@@ -29,8 +41,8 @@ import org.springframework.stereotype.Component;
|
|||||||
@Scope("singleton")
|
@Scope("singleton")
|
||||||
public class DataTableApiResource {
|
public class DataTableApiResource {
|
||||||
|
|
||||||
// private final static Logger logger =
|
private final static Logger logger = LoggerFactory
|
||||||
// LoggerFactory.getLogger(DataTableApiResource.class);
|
.getLogger(DataTableApiResource.class);
|
||||||
|
|
||||||
private final PlatformSecurityContext context;
|
private final PlatformSecurityContext context;
|
||||||
|
|
||||||
@@ -90,6 +102,58 @@ public class DataTableApiResource {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("{datatable}/{id}")
|
||||||
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
|
public Response newDatatableEntry(
|
||||||
|
@PathParam("datatable") final String datatable,
|
||||||
|
@PathParam("id") final Long id, final String jsonRequestBody) {
|
||||||
|
|
||||||
|
checkUserPermissionForDatatable(datatable, "CREATE");
|
||||||
|
Map<String, String> queryParams = getQueryParamsFromJsonRequestBody(jsonRequestBody);
|
||||||
|
|
||||||
|
this.readWriteNonCoreDataService.newDatatableEntry(datatable, id,
|
||||||
|
queryParams);
|
||||||
|
|
||||||
|
EntityIdentifier entityIdentifier = new EntityIdentifier(
|
||||||
|
Long.valueOf(id));
|
||||||
|
|
||||||
|
return Response.ok().entity(entityIdentifier).build();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, String> getQueryParamsFromJsonRequestBody(
|
||||||
|
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(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(String datatable,
|
private void checkUserPermissionForDatatable(String datatable,
|
||||||
String accessType) {
|
String accessType) {
|
||||||
AppUser currentUser = context.authenticatedUser();
|
AppUser currentUser = context.authenticatedUser();
|
||||||
|
|||||||
+3
@@ -24,4 +24,7 @@ public interface ReadWriteNonCoreDataService {
|
|||||||
String retrieveDataTableJSONObject(String datatable, Long id,
|
String retrieveDataTableJSONObject(String datatable, Long id,
|
||||||
String sqlFields, String sqlOrder);
|
String sqlFields, String sqlOrder);
|
||||||
|
|
||||||
|
void newDatatableEntry(String datatable, Long id,
|
||||||
|
Map<String, String> queryParams);
|
||||||
|
|
||||||
}
|
}
|
||||||
+116
-39
@@ -477,6 +477,29 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
|||||||
return type + "_x" + set;
|
return type + "_x" + set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// only exclusively datatable functions below here
|
||||||
|
@Override
|
||||||
|
public void newDatatableEntry(String datatable, Long id,
|
||||||
|
Map<String, String> queryParams) {
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
String applicationTableName = getApplicationTableName(datatable);
|
||||||
|
|
||||||
|
checkMainResourceExistsWithinScope(applicationTableName, id);
|
||||||
|
|
||||||
|
List<ResultsetColumnHeader> columnHeaders = getDatatableResultsetColumnHeaders(datatable);
|
||||||
|
|
||||||
|
String sql = getAddSql(columnHeaders, datatable, getFKField(applicationTableName), id, queryParams);
|
||||||
|
|
||||||
|
String sqlErrorMsg = "SQL: " + sql;
|
||||||
|
genericDataService.updateSQL(sql, sqlErrorMsg);
|
||||||
|
|
||||||
|
long elapsed = System.currentTimeMillis() - startTime;
|
||||||
|
logger.info("FINISHING newDatatableEntry: Elapsed Time: "
|
||||||
|
+ elapsed + " - datatable: " + datatable + " id: " + id);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<DatatableData> retrieveDatatableNames(String appTable) {
|
public List<DatatableData> retrieveDatatableNames(String appTable) {
|
||||||
|
|
||||||
@@ -500,9 +523,10 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
|||||||
+ " where ur.appuser_id = "
|
+ " where ur.appuser_id = "
|
||||||
+ context.authenticatedUser().getId()
|
+ context.authenticatedUser().getId()
|
||||||
+ " and (p.code in ('ALL_FUNCTIONS', 'ALL_FUNCTIONS_READ') or p.code = concat('CAN_READ_', registered_table_name))) "
|
+ " and (p.code in ('ALL_FUNCTIONS', 'ALL_FUNCTIONS_READ') or p.code = concat('CAN_READ_', registered_table_name))) "
|
||||||
+ andClause + " order by application_table_name, registered_table_name";
|
+ andClause
|
||||||
|
+ " order by application_table_name, registered_table_name";
|
||||||
|
|
||||||
//sql = genericDataService.wrapSQL(sql);
|
// sql = genericDataService.wrapSQL(sql);
|
||||||
String sqlErrorMsg = "Application Table Name: " + appTable + " sql: "
|
String sqlErrorMsg = "Application Table Name: " + appTable + " sql: "
|
||||||
+ sql;
|
+ sql;
|
||||||
CachedRowSet rs = genericDataService.getCachedResultSet(sql,
|
CachedRowSet rs = genericDataService.getCachedResultSet(sql,
|
||||||
@@ -512,7 +536,8 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
|||||||
try {
|
try {
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
datatables.add(new DatatableData(rs
|
datatables.add(new DatatableData(rs
|
||||||
.getString("application_table_name"), rs.getString("registered_table_name"), rs
|
.getString("application_table_name"), rs
|
||||||
|
.getString("registered_table_name"), rs
|
||||||
.getString("registered_table_label")));
|
.getString("registered_table_label")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -539,15 +564,14 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
|||||||
String jsonString = generateJsonFromGenericResultsetData(result);
|
String jsonString = generateJsonFromGenericResultsetData(result);
|
||||||
|
|
||||||
long elapsed = System.currentTimeMillis() - startTime;
|
long elapsed = System.currentTimeMillis() - startTime;
|
||||||
logger.info("FINISHING DATATABLE JSON OBJECT: " + datatable + " Elapsed Time: "
|
logger.info("FINISHING DATATABLE JSON OBJECT: " + datatable
|
||||||
+ elapsed);
|
+ " Elapsed Time: " + elapsed);
|
||||||
return jsonString;
|
return jsonString;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GenericResultsetData retrieveDataTableGenericResultSet(
|
public GenericResultsetData retrieveDataTableGenericResultSet(
|
||||||
String datatable, Long id, String sqlFields,
|
String datatable, Long id, String sqlFields, String sqlOrder) {
|
||||||
String sqlOrder) {
|
|
||||||
|
|
||||||
long startTime = System.currentTimeMillis();
|
long startTime = System.currentTimeMillis();
|
||||||
|
|
||||||
@@ -555,19 +579,16 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
|||||||
|
|
||||||
checkMainResourceExistsWithinScope(applicationTableName, id);
|
checkMainResourceExistsWithinScope(applicationTableName, id);
|
||||||
|
|
||||||
CachedRowSet columnDefinitions = getDatatableMetaData(datatable);
|
List<ResultsetColumnHeader> columnHeaders = getDatatableResultsetColumnHeaders(datatable);
|
||||||
|
|
||||||
List<ResultsetColumnHeader> columnHeaders = getDatatableResultsetColumnHeaders(
|
|
||||||
columnDefinitions);
|
|
||||||
|
|
||||||
String fkField = applicationTableName.substring(2) + "_id";
|
|
||||||
String sql = "select ";
|
String sql = "select ";
|
||||||
if (sqlFields != null)
|
if (sqlFields != null)
|
||||||
sql = sql + sqlFields;
|
sql = sql + sqlFields;
|
||||||
else
|
else
|
||||||
sql = sql + " * ";
|
sql = sql + " * ";
|
||||||
|
|
||||||
sql = sql + " from " + datatable + " where " + fkField + " = " + id;
|
sql = sql + " from " + datatable + " where "
|
||||||
|
+ getFKField(applicationTableName) + " = " + id;
|
||||||
if (sqlOrder != null)
|
if (sqlOrder != null)
|
||||||
sql = sql + " order by " + sqlOrder;
|
sql = sql + " order by " + sqlOrder;
|
||||||
logger.info(sql);
|
logger.info(sql);
|
||||||
@@ -582,11 +603,12 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<ResultsetDataRow> fillDatatableResultSetDataRows(
|
||||||
private List<ResultsetDataRow> fillDatatableResultSetDataRows(final String sql) {
|
final String sql) {
|
||||||
|
|
||||||
String sqlErrorMsg = "Sql: " + sql;
|
String sqlErrorMsg = "Sql: " + sql;
|
||||||
CachedRowSet rs = genericDataService.getCachedResultSet(sql, sqlErrorMsg);
|
CachedRowSet rs = genericDataService.getCachedResultSet(sql,
|
||||||
|
sqlErrorMsg);
|
||||||
|
|
||||||
List<ResultsetDataRow> resultsetDataRows = new ArrayList<ResultsetDataRow>();
|
List<ResultsetDataRow> resultsetDataRows = new ArrayList<ResultsetDataRow>();
|
||||||
|
|
||||||
@@ -636,6 +658,10 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getFKField(String applicationTableName) {
|
||||||
|
|
||||||
|
return applicationTableName.substring(2) + "_id";
|
||||||
|
}
|
||||||
|
|
||||||
private CachedRowSet getDatatableMetaData(String datatable) {
|
private CachedRowSet getDatatableMetaData(String datatable) {
|
||||||
|
|
||||||
@@ -654,7 +680,9 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
private List<ResultsetColumnHeader> getDatatableResultsetColumnHeaders(
|
private List<ResultsetColumnHeader> getDatatableResultsetColumnHeaders(
|
||||||
CachedRowSet columnDefinitions) {
|
String datatable) {
|
||||||
|
|
||||||
|
CachedRowSet columnDefinitions = getDatatableMetaData(datatable);
|
||||||
|
|
||||||
List<ResultsetColumnHeader> columnHeaders = new ArrayList<ResultsetColumnHeader>();
|
List<ResultsetColumnHeader> columnHeaders = new ArrayList<ResultsetColumnHeader>();
|
||||||
|
|
||||||
@@ -666,15 +694,22 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
|||||||
rsch.setColumnName(columnDefinitions.getString("COLUMN_NAME"));
|
rsch.setColumnName(columnDefinitions.getString("COLUMN_NAME"));
|
||||||
|
|
||||||
String isNullable = columnDefinitions.getString("IS_NULLABLE");
|
String isNullable = columnDefinitions.getString("IS_NULLABLE");
|
||||||
if (isNullable.equalsIgnoreCase("YES")) rsch.setColumnNullable(true);
|
if (isNullable.equalsIgnoreCase("YES"))
|
||||||
else rsch.setColumnNullable(false);
|
rsch.setColumnNullable(true);
|
||||||
|
else
|
||||||
|
rsch.setColumnNullable(false);
|
||||||
|
|
||||||
String isPrimaryKey = columnDefinitions.getString("COLUMN_KEY");
|
String isPrimaryKey = columnDefinitions.getString("COLUMN_KEY");
|
||||||
if (isPrimaryKey.equalsIgnoreCase("PRI")) rsch.setColumnPrimaryKey(true);
|
if (isPrimaryKey.equalsIgnoreCase("PRI"))
|
||||||
else rsch.setColumnPrimaryKey(false);
|
rsch.setColumnPrimaryKey(true);
|
||||||
|
else
|
||||||
|
rsch.setColumnPrimaryKey(false);
|
||||||
|
|
||||||
Long columnLength = columnDefinitions.getLong("CHARACTER_MAXIMUM_LENGTH");
|
Long columnLength = columnDefinitions
|
||||||
if (columnLength > 0 ) rsch.setColumnLength(columnDefinitions.getLong("CHARACTER_MAXIMUM_LENGTH"));
|
.getLong("CHARACTER_MAXIMUM_LENGTH");
|
||||||
|
if (columnLength > 0)
|
||||||
|
rsch.setColumnLength(columnDefinitions
|
||||||
|
.getLong("CHARACTER_MAXIMUM_LENGTH"));
|
||||||
|
|
||||||
rsch.setColumnType(columnDefinitions.getString("DATA_TYPE"));
|
rsch.setColumnType(columnDefinitions.getString("DATA_TYPE"));
|
||||||
|
|
||||||
@@ -699,24 +734,25 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addCodesValueIfNecessary(ResultsetColumnHeader rsch,
|
||||||
|
String code_suffix) {
|
||||||
|
|
||||||
private void addCodesValueIfNecessary(ResultsetColumnHeader rsch, String code_suffix) {
|
|
||||||
int codePosition = rsch.getColumnName().indexOf(code_suffix);
|
int codePosition = rsch.getColumnName().indexOf(code_suffix);
|
||||||
if (codePosition > 0){
|
if (codePosition > 0) {
|
||||||
String codeName = rsch.getColumnName().substring(0, codePosition);
|
String codeName = rsch.getColumnName().substring(0, codePosition);
|
||||||
|
|
||||||
String sql = "select v.id, v.code_value from m_code m "
|
String sql = "select v.id, v.code_value from m_code m "
|
||||||
+ " join m_code_value v on v.code_id = m.id "
|
+ " join m_code_value v on v.code_id = m.id "
|
||||||
+ " where m.code_name = '" + codeName + "' order by v.order_position, v.id";
|
+ " where m.code_name = '" + codeName
|
||||||
|
+ "' order by v.order_position, v.id";
|
||||||
|
|
||||||
CachedRowSet rsValues = genericDataService
|
CachedRowSet rsValues = genericDataService.getCachedResultSet(sql,
|
||||||
.getCachedResultSet(sql, "SQL: " + sql);
|
"SQL: " + sql);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
while (rsValues.next()) {
|
while (rsValues.next()) {
|
||||||
rsch.getColumnValuesNew().add( new ResultsetColumnValue(rsValues.getInt("id"), rsValues.getString("code_value")));
|
rsch.getColumnValuesNew().add(
|
||||||
|
new ResultsetColumnValue(rsValues.getInt("id"),
|
||||||
|
rsValues.getString("code_value")));
|
||||||
}
|
}
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw new PlatformDataIntegrityException("error.msg.sql.error",
|
throw new PlatformDataIntegrityException("error.msg.sql.error",
|
||||||
@@ -778,14 +814,55 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
|||||||
writer.append("\n]");
|
writer.append("\n]");
|
||||||
return writer.toString();
|
return writer.toString();
|
||||||
|
|
||||||
/*
|
}
|
||||||
* JSONObject js = null; try { js = new JSONObject(writer.toString()); }
|
|
||||||
* catch (JSONException e) { throw new WebApplicationException(Response
|
|
||||||
* .status(Status.BAD_REQUEST).entity("JSON body is wrong") .build()); }
|
|
||||||
*
|
|
||||||
* return js.toString();
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
private String getAddSql(List<ResultsetColumnHeader> columnHeaders,
|
||||||
|
String datatable, String FKField, Long id, Map<String, String> queryParams) {
|
||||||
|
|
||||||
|
Set<String> keys = queryParams.keySet();
|
||||||
|
|
||||||
|
String underscore = "_";
|
||||||
|
String space = " ";
|
||||||
|
String pValue = null;
|
||||||
|
String keyUpdated = null;
|
||||||
|
|
||||||
|
Map<String, String> updatedColumns = new HashMap<String, String>();
|
||||||
|
|
||||||
|
for (String key : keys) {
|
||||||
|
if (!(key.equalsIgnoreCase("id"))) {
|
||||||
|
//keyUpdated = genericDataService.replace(key, underscore, space);
|
||||||
|
keyUpdated = key;
|
||||||
|
pValue = queryParams.get(key);
|
||||||
|
updatedColumns.put(keyUpdated, pValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String pValueWrite = "";
|
||||||
|
String saveSql = "";
|
||||||
|
String singleQuote = "'";
|
||||||
|
|
||||||
|
String insertColumns = "";
|
||||||
|
String selectColumns = "";
|
||||||
|
String columnName = "";
|
||||||
|
for (String key : updatedColumns.keySet()) {
|
||||||
|
pValue = updatedColumns.get(key);
|
||||||
|
|
||||||
|
if (StringUtils.isEmpty(pValue)) {
|
||||||
|
pValueWrite = "null";
|
||||||
|
} else {
|
||||||
|
pValueWrite = singleQuote
|
||||||
|
+ genericDataService.replace(pValue, singleQuote,
|
||||||
|
singleQuote + singleQuote) + singleQuote;
|
||||||
|
}
|
||||||
|
columnName = "`" + key + "`";
|
||||||
|
insertColumns += ", " + columnName;
|
||||||
|
selectColumns += "," + pValueWrite + " as " + columnName;
|
||||||
|
}
|
||||||
|
|
||||||
|
saveSql = "insert into `" + datatable + "` (" + FKField + insertColumns + ")"
|
||||||
|
+ " select " + id + " as id" + selectColumns;
|
||||||
|
|
||||||
|
return saveSql;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user