WIP data tables

This commit is contained in:
John Woodlock
2012-09-07 16:15:47 +10:00
parent 9649f0aba4
commit e3223536a2
8 changed files with 159 additions and 40 deletions
@@ -1,20 +1,22 @@
package org.mifosng.platform.api; package org.mifosng.platform.api;
import java.util.ArrayList;
import java.util.List;
import javax.ws.rs.Consumes; import javax.ws.rs.Consumes;
import javax.ws.rs.GET; import javax.ws.rs.GET;
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.core.Context;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriInfo;
import org.mifosng.platform.InvalidSqlException; import org.mifosng.platform.api.data.GenericResultsetData;
import org.mifosng.platform.api.data.ApiParameterError; import org.mifosng.platform.api.infrastructure.ApiJsonSerializerService;
import org.mifosng.platform.exceptions.PlatformApiDataValidationException; import org.mifosng.platform.api.infrastructure.ApiParameterHelper;
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.user.domain.AppUser;
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;
@@ -27,33 +29,58 @@ public class DataTableApiResource {
// private final static Logger logger = // private final static Logger logger =
// LoggerFactory.getLogger(DataTableApiResource.class); // LoggerFactory.getLogger(DataTableApiResource.class);
private final PlatformSecurityContext context;
@Autowired
public DataTableApiResource(final PlatformSecurityContext context) {
this.context = context;
}
@Autowired @Autowired
private ReadWriteNonCoreDataService readWriteNonCoreDataService; private ReadWriteNonCoreDataService readWriteNonCoreDataService;
@Autowired
private ApiJsonSerializerService apiJsonSerializerService;
@GET @GET
@Path("{datatable}/{id}") @Path("{datatable}/{id}")
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String extraData(@PathParam("datatable") final String datatable, public String getDatatable(@PathParam("datatable") final String datatable,
@PathParam("id") final Long id, @PathParam("id") final Long id,
@QueryParam("sqlFields") final String sqlFields, @QueryParam("sqlFields") final String sqlFields,
@QueryParam("sqlSearch") final String sqlSearch, @QueryParam("sqlSearch") final String sqlSearch,
@QueryParam("sqlOrder") final String sqlOrder) { @QueryParam("sqlOrder") final String sqlOrder,
@Context final UriInfo uriInfo) {
checkUserPermissionForDatatable(datatable, "READ");
return this.readWriteNonCoreDataService.retrieveDataTable(datatable, id,
sqlFields, sqlSearch, sqlOrder);
/* /*
* try { return this.readWriteNonCoreDataService.retrieveDataTable( * Dont use this for now... but its the code for returning data as json
* datatable, sqlFields, sqlSearch, sqlOrder); } catch * objects rather than a generic resultset String resultStr =
* (InvalidSqlException e) { List<ApiParameterError> * this.readWriteNonCoreDataService
* dataValidationErrors = new ArrayList<ApiParameterError>(); * .retrieveDataTableJSONObject(datatable, id, sqlFields, sqlSearch,
* ApiParameterError error = ApiParameterError.parameterError( * sqlOrder);
* "extradata.invalid.sql", "The sql is invalid.", "sql", e.getSql());
* dataValidationErrors.add(error); throw new
* PlatformApiDataValidationException(
* "validation.msg.validation.errors.exist", "Validation errors exist.",
* dataValidationErrors); }
*/ */
GenericResultsetData results = this.readWriteNonCoreDataService
.retrieveDataTableGenericResultSet(datatable, id, sqlFields,
sqlSearch, sqlOrder);
boolean prettyPrints = ApiParameterHelper.prettyPrint(uriInfo
.getQueryParameters());
return this.apiJsonSerializerService
.serializeGenericResultsetDataToJson(prettyPrints, results);
} }
} private void checkUserPermissionForDatatable(String datatable,
String accessType) {
AppUser currentUser = context.authenticatedUser();
if (currentUser.hasNotPermissionForDatatable(datatable, accessType)) {
throw new NoAuthorizationException("Not Authorised to "
+ accessType + " Data Table: " + datatable);
}
}
}
@@ -10,6 +10,7 @@ public class ResultsetColumnHeader {
private Integer columnLength; private Integer columnLength;
private String columnDisplayType; private String columnDisplayType;
private List<String> columnValues = new ArrayList<String>(); private List<String> columnValues = new ArrayList<String>();
private List<ResultsetColumnValue> columnValuesNew = new ArrayList<ResultsetColumnValue>();
public ResultsetColumnHeader() { public ResultsetColumnHeader() {
@@ -55,4 +56,12 @@ public class ResultsetColumnHeader {
this.columnDisplayType = columnDisplayType; this.columnDisplayType = columnDisplayType;
} }
public List<ResultsetColumnValue> getColumnValuesNew() {
return columnValuesNew;
}
public void setColumnValuesNew(List<ResultsetColumnValue> columnValuesNew) {
this.columnValuesNew = columnValuesNew;
}
} }
@@ -0,0 +1,28 @@
package org.mifosng.platform.api.data;
public class ResultsetColumnValue {
private Long id;
private String Value;
public ResultsetColumnValue() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getValue() {
return Value;
}
public void setValue(String value) {
Value = value;
}
}
@@ -16,4 +16,6 @@ public interface GenericDataService {
String wrapSQL(String sql); String wrapSQL(String sql);
String getDatabaseName();
} }
@@ -173,4 +173,14 @@ public class GenericDataServiceImpl implements GenericDataService {
e.getMessage(), "Error closing database connection"); e.getMessage(), "Error closing database connection");
} }
} }
@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");
}
}
} }
@@ -13,8 +13,12 @@ public interface ReadWriteNonCoreDataService {
GenericResultsetData retrieveExtraData(String type, String set, Long id); GenericResultsetData retrieveExtraData(String type, String set, Long id);
void updateExtraData(String type, String set, Long id, void updateExtraData(String type, String set, Long id,
Map<String, String> queryParams); Map<String, String> queryParams);
String retrieveDataTable(String datatable, Long id, String sqlFields, String sqlSearch, String sqlOrder); GenericResultsetData retrieveDataTableGenericResultSet(String datatable,
Long id, String sqlFields, String sqlSearch, String sqlOrder);
String retrieveDataTableJSONObject(String datatable, Long id,
String sqlFields, String sqlSearch, String sqlOrder);
} }
@@ -94,8 +94,8 @@ public class ReadWriteNonCoreDataServiceImpl implements
@Override @Override
public GenericResultsetData retrieveExtraData(String type, String set, public GenericResultsetData retrieveExtraData(String type, String set,
Long id) { Long id) {
long startTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis();
checkMainResourceExistsWithinScope(type, id); checkMainResourceExistsWithinScope(type, id);
@@ -475,16 +475,34 @@ public class ReadWriteNonCoreDataServiceImpl implements
} }
@Override @Override
public String retrieveDataTable(String datatable, Long id, String sqlFields, public String retrieveDataTableJSONObject(String datatable, Long id,
String sqlSearch, String sqlOrder) { String sqlFields, String sqlSearch, String sqlOrder) {
long startTime = System.currentTimeMillis();
GenericResultsetData result = retrieveDataTableGenericResultSet(
datatable, id, sqlFields, sqlSearch, sqlOrder);
String jsonString = generateJsonFromGenericResultsetData(result);
long elapsed = System.currentTimeMillis() - startTime;
logger.info("FINISHING DATATABLE JSON OBJECT: " + datatable + " Elapsed Time: "
+ elapsed);
return jsonString;
}
@Override
public GenericResultsetData retrieveDataTableGenericResultSet(
String datatable, Long id, String sqlFields, String sqlSearch,
String sqlOrder) {
long startTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis();
String applicationTableName = getApplicationTableName(datatable); String applicationTableName = getApplicationTableName(datatable);
checkMainResourceExistsWithinScope(applicationTableName, id); checkMainResourceExistsWithinScope(applicationTableName, id);
String fkField = applicationTableName.substring(2) + "_id"; String fkField = applicationTableName.substring(2) + "_id";
String sql = "select "; String sql = "select ";
if (sqlFields != null) if (sqlFields != null)
sql = sql + sqlFields; sql = sql + sqlFields;
@@ -501,24 +519,23 @@ public class ReadWriteNonCoreDataServiceImpl implements
GenericResultsetData result = genericDataService GenericResultsetData result = genericDataService
.fillGenericResultSet(sql); .fillGenericResultSet(sql);
String jsonString = generateJsonFromGenericResultsetData(result);
logger.info("JSON is: " + jsonString);
long elapsed = System.currentTimeMillis() - startTime; long elapsed = System.currentTimeMillis() - startTime;
logger.info("FINISHING DATATABLE: " + datatable + " Elapsed Time: " logger.info("FINISHING DATATABLE: " + datatable + " Elapsed Time: "
+ elapsed); + elapsed);
return jsonString;
return result;
} }
private String getApplicationTableName(String datatable) { private String getApplicationTableName(String datatable) {
String sql = "SELECT application_table_name FROM x_registered_table where registered_table_name = '" + datatable + "'"; String sql = "SELECT application_table_name FROM x_registered_table where registered_table_name = '"
+ datatable + "'";
CachedRowSet rs = genericDataService.getCachedResultSet(sql, "SQL : " CachedRowSet rs = genericDataService.getCachedResultSet(sql, "SQL : "
+ sql); + sql);
if (rs.size() == 0) if (rs.size() == 0)
throw new DataTableNotFoundException(datatable); throw new DataTableNotFoundException(datatable);
try { try {
rs.next(); rs.next();
return rs.getString("application_table_name"); return rs.getString("application_table_name");
@@ -262,7 +262,28 @@ public class AppUser extends AbstractAuditableCustom<AppUser, Long> implements
public boolean hasNotPermissionForReport(String reportName) { public boolean hasNotPermissionForReport(String reportName) {
if (hasNotPermissionForAnyOf("ALL_FUNCTIONS", "ALL_FUNCTIONS_READ", "CAN_RUN_" + reportName)) if (hasNotPermissionForAnyOf("ALL_FUNCTIONS", "ALL_FUNCTIONS_READ",
"CAN_RUN_" + reportName))
return true;
return false;
}
public boolean hasNotPermissionForDatatable(String datatable,
String accessType) {
String matchPermission = "CAN_" + accessType + "_" + datatable;
if (accessType.equalsIgnoreCase("READ")) {
if (hasNotPermissionForAnyOf("ALL_FUNCTIONS", "ALL_FUNCTIONS_READ",
matchPermission))
return true;
return false;
}
if (hasNotPermissionForAnyOf("ALL_FUNCTIONS", matchPermission))
return true; return true;
return false; return false;
@@ -275,15 +296,16 @@ public class AppUser extends AbstractAuditableCustom<AppUser, Long> implements
if (accessType.equalsIgnoreCase("READ")) { if (accessType.equalsIgnoreCase("READ")) {
if (hasNotPermissionForAnyOf("ALL_FUNCTIONS", "ALL_FUNCTIONS_READ", matchPermission)) if (hasNotPermissionForAnyOf("ALL_FUNCTIONS", "ALL_FUNCTIONS_READ",
matchPermission))
return true; return true;
return false; return false;
} }
if (hasNotPermissionForAnyOf("ALL_FUNCTIONS", matchPermission)) if (hasNotPermissionForAnyOf("ALL_FUNCTIONS", matchPermission))
return true; return true;
return false; return false;
} }