diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/DataTableApiResource.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/DataTableApiResource.java index 39aeb54fc..837c4aed6 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/DataTableApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/DataTableApiResource.java @@ -1,18 +1,28 @@ package org.mifosng.platform.api; +import java.util.HashMap; import java.util.List; +import java.util.Map; import javax.ws.rs.Consumes; import javax.ws.rs.GET; +import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; +import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Context; 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 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.EntityIdentifier; import org.mifosng.platform.api.data.GenericResultsetData; import org.mifosng.platform.api.infrastructure.ApiJsonSerializerService; 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.security.PlatformSecurityContext; 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.context.annotation.Scope; import org.springframework.stereotype.Component; @@ -29,8 +41,8 @@ import org.springframework.stereotype.Component; @Scope("singleton") 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; @@ -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 queryParams = getQueryParamsFromJsonRequestBody(jsonRequestBody); + + this.readWriteNonCoreDataService.newDatatableEntry(datatable, id, + queryParams); + + EntityIdentifier entityIdentifier = new EntityIdentifier( + Long.valueOf(id)); + + return Response.ok().entity(entityIdentifier).build(); + + } + + private Map getQueryParamsFromJsonRequestBody( + String jsonRequestBody) { + + Map queryParams = new HashMap(); + + 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, String accessType) { AppUser currentUser = context.authenticatedUser(); diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/noncore/ReadWriteNonCoreDataService.java b/mifosng-provider/src/main/java/org/mifosng/platform/noncore/ReadWriteNonCoreDataService.java index 58611fc15..6043e5295 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/noncore/ReadWriteNonCoreDataService.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/noncore/ReadWriteNonCoreDataService.java @@ -24,4 +24,7 @@ public interface ReadWriteNonCoreDataService { String retrieveDataTableJSONObject(String datatable, Long id, String sqlFields, String sqlOrder); + void newDatatableEntry(String datatable, Long id, + Map queryParams); + } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/noncore/ReadWriteNonCoreDataServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/noncore/ReadWriteNonCoreDataServiceImpl.java index bbad7a568..b80173a4a 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/noncore/ReadWriteNonCoreDataServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/noncore/ReadWriteNonCoreDataServiceImpl.java @@ -477,6 +477,29 @@ public class ReadWriteNonCoreDataServiceImpl implements return type + "_x" + set; } + // only exclusively datatable functions below here + @Override + public void newDatatableEntry(String datatable, Long id, + Map queryParams) { + long startTime = System.currentTimeMillis(); + + String applicationTableName = getApplicationTableName(datatable); + + checkMainResourceExistsWithinScope(applicationTableName, id); + + List 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 public List retrieveDatatableNames(String appTable) { @@ -500,9 +523,10 @@ public class ReadWriteNonCoreDataServiceImpl implements + " where ur.appuser_id = " + context.authenticatedUser().getId() + " 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: " + sql; CachedRowSet rs = genericDataService.getCachedResultSet(sql, @@ -512,7 +536,8 @@ public class ReadWriteNonCoreDataServiceImpl implements try { while (rs.next()) { 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"))); } @@ -539,15 +564,14 @@ public class ReadWriteNonCoreDataServiceImpl implements String jsonString = generateJsonFromGenericResultsetData(result); long elapsed = System.currentTimeMillis() - startTime; - logger.info("FINISHING DATATABLE JSON OBJECT: " + datatable + " Elapsed Time: " - + elapsed); + logger.info("FINISHING DATATABLE JSON OBJECT: " + datatable + + " Elapsed Time: " + elapsed); return jsonString; } @Override public GenericResultsetData retrieveDataTableGenericResultSet( - String datatable, Long id, String sqlFields, - String sqlOrder) { + String datatable, Long id, String sqlFields, String sqlOrder) { long startTime = System.currentTimeMillis(); @@ -555,23 +579,20 @@ public class ReadWriteNonCoreDataServiceImpl implements checkMainResourceExistsWithinScope(applicationTableName, id); - CachedRowSet columnDefinitions = getDatatableMetaData(datatable); + List columnHeaders = getDatatableResultsetColumnHeaders(datatable); - List columnHeaders = getDatatableResultsetColumnHeaders( - columnDefinitions); - - String fkField = applicationTableName.substring(2) + "_id"; String sql = "select "; if (sqlFields != null) sql = sql + sqlFields; else sql = sql + " * "; - sql = sql + " from " + datatable + " where " + fkField + " = " + id; + sql = sql + " from " + datatable + " where " + + getFKField(applicationTableName) + " = " + id; if (sqlOrder != null) sql = sql + " order by " + sqlOrder; logger.info(sql); - + List result = fillDatatableResultSetDataRows(sql); long elapsed = System.currentTimeMillis() - startTime; @@ -579,14 +600,15 @@ public class ReadWriteNonCoreDataServiceImpl implements + elapsed); return new GenericResultsetData(columnHeaders, result); - + } - - - private List fillDatatableResultSetDataRows(final String sql) { + + private List fillDatatableResultSetDataRows( + final String sql) { String sqlErrorMsg = "Sql: " + sql; - CachedRowSet rs = genericDataService.getCachedResultSet(sql, sqlErrorMsg); + CachedRowSet rs = genericDataService.getCachedResultSet(sql, + sqlErrorMsg); List resultsetDataRows = new ArrayList(); @@ -594,7 +616,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ResultSetMetaData rsmd = rs.getMetaData(); int columnCount = rsmd.getColumnCount(); - + ResultsetDataRow resultsetDataRow; String columnName = null; String columnValue = null; @@ -636,6 +658,10 @@ public class ReadWriteNonCoreDataServiceImpl implements } } + private String getFKField(String applicationTableName) { + + return applicationTableName.substring(2) + "_id"; + } private CachedRowSet getDatatableMetaData(String datatable) { @@ -643,7 +669,7 @@ public class ReadWriteNonCoreDataServiceImpl implements + " from INFORMATION_SCHEMA.COLUMNS " + " where TABLE_SCHEMA = schema() and TABLE_NAME = '" + datatable + "'order by ORDINAL_POSITION"; - + CachedRowSet columnDefinitions = genericDataService.getCachedResultSet( sql, "SQL: " + sql); @@ -654,7 +680,9 @@ public class ReadWriteNonCoreDataServiceImpl implements } private List getDatatableResultsetColumnHeaders( - CachedRowSet columnDefinitions) { + String datatable) { + + CachedRowSet columnDefinitions = getDatatableMetaData(datatable); List columnHeaders = new ArrayList(); @@ -662,31 +690,38 @@ public class ReadWriteNonCoreDataServiceImpl implements while (columnDefinitions.next()) { ResultsetColumnHeader rsch = new ResultsetColumnHeader(); - + rsch.setColumnName(columnDefinitions.getString("COLUMN_NAME")); String isNullable = columnDefinitions.getString("IS_NULLABLE"); - if (isNullable.equalsIgnoreCase("YES")) rsch.setColumnNullable(true); - else rsch.setColumnNullable(false); - + if (isNullable.equalsIgnoreCase("YES")) + rsch.setColumnNullable(true); + else + rsch.setColumnNullable(false); + String isPrimaryKey = columnDefinitions.getString("COLUMN_KEY"); - if (isPrimaryKey.equalsIgnoreCase("PRI")) rsch.setColumnPrimaryKey(true); - else rsch.setColumnPrimaryKey(false); + if (isPrimaryKey.equalsIgnoreCase("PRI")) + rsch.setColumnPrimaryKey(true); + else + rsch.setColumnPrimaryKey(false); + + Long columnLength = columnDefinitions + .getLong("CHARACTER_MAXIMUM_LENGTH"); + if (columnLength > 0) + rsch.setColumnLength(columnDefinitions + .getLong("CHARACTER_MAXIMUM_LENGTH")); - Long columnLength = columnDefinitions.getLong("CHARACTER_MAXIMUM_LENGTH"); - if (columnLength > 0 ) rsch.setColumnLength(columnDefinitions.getLong("CHARACTER_MAXIMUM_LENGTH")); - rsch.setColumnType(columnDefinitions.getString("DATA_TYPE")); rsch.setColumnDisplayType(null); - + /* look for codes */ - if (rsch.getColumnType().equalsIgnoreCase("varchar")) + if (rsch.getColumnType().equalsIgnoreCase("varchar")) addCodesValueIfNecessary(rsch, "_cv"); - - if (rsch.getColumnType().equalsIgnoreCase("int")) + + if (rsch.getColumnType().equalsIgnoreCase("int")) addCodesValueIfNecessary(rsch, "_cd"); - + columnHeaders.add(rsch); } ; @@ -699,31 +734,32 @@ 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); - if (codePosition > 0){ + if (codePosition > 0) { String codeName = rsch.getColumnName().substring(0, codePosition); - + String sql = "select v.id, v.code_value from m_code m " + " join m_code_value v on v.code_id = m.id " - + " where m.code_name = '" + codeName + "' order by v.order_position, v.id"; - - CachedRowSet rsValues = genericDataService - .getCachedResultSet(sql, "SQL: " + sql); - + + " where m.code_name = '" + codeName + + "' order by v.order_position, v.id"; + + CachedRowSet rsValues = genericDataService.getCachedResultSet(sql, + "SQL: " + sql); + try { 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) { throw new PlatformDataIntegrityException("error.msg.sql.error", e.getMessage()); } } - + } private static String generateJsonFromGenericResultsetData( @@ -778,14 +814,55 @@ public class ReadWriteNonCoreDataServiceImpl implements writer.append("\n]"); 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 columnHeaders, + String datatable, String FKField, Long id, Map queryParams) { + + Set keys = queryParams.keySet(); + + String underscore = "_"; + String space = " "; + String pValue = null; + String keyUpdated = null; + + Map updatedColumns = new HashMap(); + + 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; } } \ No newline at end of file