wip mifosx-195 refactor list reports api for maintenance function use and change api-docs

This commit is contained in:
John Woodlock
2013-04-13 19:33:43 +01:00
parent 9cc6abd6c4
commit e777491d76
7 changed files with 836 additions and 1145 deletions
+66 -752
View File
@@ -10254,19 +10254,6 @@ No Request Body:
<div class="method-section">
<div class="method-description">
<h3>Reports</h3>
<p>The reports resource allows you to run and receive output
from pre-defined Mifos X reports. The default output is a JSON
formatted "Generic Resultset". The Generic Resultset contains
Column Heading as well as Data information. However, you can
export to CSV format by simply adding "&exportCSV=true" to the end
of your URL.</p>
<p>If Pentaho reports have been pre-defined, they can also be
run through this resource. Pentaho reports can return HTML, PDF or
CSV formats.</p>
<p>The Mifos X Individual Lending client application uses a
JQuery plugin called stretchyreporting which, itself, uses this
reports resource to provide a pretty flexible reporting User
Interface (UI).</p>
</div>
</div>
@@ -10276,753 +10263,67 @@ No Request Body:
<div class="method-section">
<div class="method-description">
<h4>List Reports</h4>
<p>Lists all reports and their parameters. If a report has more
than one parameter it will be listed the same number of times as
it has parameters.</p>
<p>Lists all reports and their parameters. </p>
<h5>Arguments</h5>
<dl class="argument-list">
<dt>exportCSV</dt>
<dd>
optional, <span>The only valid value is 'true'. If any
other value is provided the argument will be ignored</span>
</dd>
<dd>Output will be delivered as a CSV file instead of JSON.</dd>
</dl>
<p>Example Requests:</p>
<p>Example Request:</p>
<div class=apiClick>reports</div>
<br>
<br>
<div class=apiClick>reports?exportCSV=true</div>
</div>
<div class="method-example">
<code class="method-declaration">
GET https://DomainName/api/v1/reports
</code>
<code class="method-response">
{
"columnHeaders": [
{
"columnName": "report_id",
"columnType": "INT",
"isColumnNullable": false,
"isColumnPrimaryKey": false,
"columnValues": []
},
{
"columnName": "report_name",
"columnType": "VARCHAR",
"isColumnNullable": false,
"isColumnPrimaryKey": false,
"columnValues": []
},
{
"columnName": "report_type",
"columnType": "VARCHAR",
"isColumnNullable": false,
"isColumnPrimaryKey": false,
"columnValues": []
},
{
"columnName": "report_subtype",
"columnType": "VARCHAR",
"isColumnNullable": false,
"isColumnPrimaryKey": false,
"columnValues": []
},
{
"columnName": "report_category",
"columnType": "VARCHAR",
"isColumnNullable": false,
"isColumnPrimaryKey": false,
"columnValues": []
},
{
"columnName": "parameter_id",
"columnType": "INT",
"isColumnNullable": false,
"isColumnPrimaryKey": false,
"columnValues": []
},
{
"columnName": "report_parameter_name",
"columnType": "VARCHAR",
"isColumnNullable": false,
"isColumnPrimaryKey": false,
"columnValues": []
},
{
"columnName": "parameter_name",
"columnType": "VARCHAR",
"isColumnNullable": false,
"isColumnPrimaryKey": false,
"columnValues": []
}
],
"data": [
{
"row": [
"10",
"Active Loans Portfolio Status",
"Table",
null,
"Loan",
"5",
null,
"OfficeIdSelectOne"
]
},
{
"row": [
"10",
"Active Loans Portfolio Status",
"Table",
null,
"Loan",
"6",
null,
"loanOfficerIdSelectAll"
]
},
{
"row": [
"10",
"Active Loans Portfolio Status",
"Table",
null,
"Loan",
"10",
null,
"currencyIdSelectAll"
]
},
{
"row": [
"10",
"Active Loans Portfolio Status",
"Table",
null,
"Loan",
"20",
null,
"fundIdSelectAll"
]
},
{
"row": [
"10",
"Active Loans Portfolio Status",
"Table",
null,
"Loan",
"25",
null,
"loanProductIdSelectAll"
]
},
{
"row": [
"11",
"Active Loans Summary per Branch",
"Table",
null,
"Loan Portfolio",
"5",
null,
"OfficeIdSelectOne"
]
},
{
"row": [
"11",
"Active Loans Summary per Branch",
"Table",
null,
"Loan Portfolio",
"10",
null,
"currencyIdSelectAll"
]
},
{
"row": [
"48",
"Balance Sheet",
"Pentaho",
null,
"Accounting",
"5",
"branch",
"OfficeIdSelectOne"
]
},
{
"row": [
"48",
"Balance Sheet",
"Pentaho",
null,
"Accounting",
"41",
"date",
"endDateSelect"
]
},
{
"row": [
"1",
"Client Listing",
"Table",
null,
"Client",
"5",
null,
"OfficeIdSelectOne"
]
},
{
"row": [
"2",
"Client Loans Listing",
"Table",
null,
"Client",
"5",
null,
"OfficeIdSelectOne"
]
},
{
"row": [
"2",
"Client Loans Listing",
"Table",
null,
"Client",
"6",
null,
"loanOfficerIdSelectAll"
]
},
{
"row": [
"2",
"Client Loans Listing",
"Table",
null,
"Client",
"10",
null,
"currencyIdSelectAll"
]
},
{
"row": [
"2",
"Client Loans Listing",
"Table",
null,
"Client",
"20",
null,
"fundIdSelectAll"
]
},
{
"row": [
"2",
"Client Loans Listing",
"Table",
null,
"Client",
"25",
null,
"loanProductIdSelectAll"
]
},
{
"row": [
"20",
"Funds Disbursed Between Dates Summary",
"Table",
null,
"Fund",
"10",
null,
"currencyIdSelectAll"
]
},
{
"row": [
"20",
"Funds Disbursed Between Dates Summary",
"Table",
null,
"Fund",
"20",
null,
"fundIdSelectAll"
]
},
{
"row": [
"20",
"Funds Disbursed Between Dates Summary",
"Table",
null,
"Fund",
"40",
null,
"startDateSelect"
]
},
{
"row": [
"20",
"Funds Disbursed Between Dates Summary",
"Table",
null,
"Fund",
"41",
null,
"endDateSelect"
]
},
{
"row": [
"21",
"Funds Disbursed Between Dates Summary by Office",
"Table",
null,
"Fund",
"5",
null,
"OfficeIdSelectOne"
]
},
{
"row": [
"21",
"Funds Disbursed Between Dates Summary by Office",
"Table",
null,
"Fund",
"10",
null,
"currencyIdSelectAll"
]
},
{
"row": [
"21",
"Funds Disbursed Between Dates Summary by Office",
"Table",
null,
"Fund",
"20",
null,
"fundIdSelectAll"
]
},
{
"row": [
"21",
"Funds Disbursed Between Dates Summary by Office",
"Table",
null,
"Fund",
"40",
null,
"startDateSelect"
]
},
{
"row": [
"21",
"Funds Disbursed Between Dates Summary by Office",
"Table",
null,
"Fund",
"41",
null,
"endDateSelect"
]
},
{
"row": [
"49",
"Income Statement",
"Pentaho",
null,
"Accounting",
"5",
"branch",
"OfficeIdSelectOne"
]
},
{
"row": [
"49",
"Income Statement",
"Pentaho",
null,
"Accounting",
"40",
"fromDate",
"startDateSelect"
]
},
{
"row": [
"49",
"Income Statement",
"Pentaho",
null,
"Accounting",
"41",
"toDate",
"endDateSelect"
]
},
{
"row": [
"5",
"Loans Awaiting Disbursal",
"Table",
null,
"Loan Portfolio",
"5",
null,
"OfficeIdSelectOne"
]
},
{
"row": [
"5",
"Loans Awaiting Disbursal",
"Table",
null,
"Loan Portfolio",
"6",
null,
"loanOfficerIdSelectAll"
]
},
{
"row": [
"5",
"Loans Awaiting Disbursal",
"Table",
null,
"Loan Portfolio",
"10",
null,
"currencyIdSelectAll"
]
},
{
"row": [
"5",
"Loans Awaiting Disbursal",
"Table",
null,
"Loan Portfolio",
"20",
null,
"fundIdSelectAll"
]
},
{
"row": [
"5",
"Loans Awaiting Disbursal",
"Table",
null,
"Loan Portfolio",
"25",
null,
"loanProductIdSelectAll"
]
},
{
"row": [
"6",
"Loans Awaiting Disbursal Summary",
"Table",
null,
"Loan Portfolio",
"5",
null,
"OfficeIdSelectOne"
]
},
{
"row": [
"6",
"Loans Awaiting Disbursal Summary",
"Table",
null,
"Loan Portfolio",
"6",
null,
"loanOfficerIdSelectAll"
]
},
{
"row": [
"6",
"Loans Awaiting Disbursal Summary",
"Table",
null,
"Loan Portfolio",
"10",
null,
"currencyIdSelectAll"
]
},
{
"row": [
"6",
"Loans Awaiting Disbursal Summary",
"Table",
null,
"Loan Portfolio",
"20",
null,
"fundIdSelectAll"
]
},
{
"row": [
"6",
"Loans Awaiting Disbursal Summary",
"Table",
null,
"Loan Portfolio",
"25",
null,
"loanProductIdSelectAll"
]
},
{
"row": [
"7",
"Loans Awaiting Disbursal Summary by Month",
"Table",
null,
"Loan Portfolio",
"5",
null,
"OfficeIdSelectOne"
]
},
{
"row": [
"7",
"Loans Awaiting Disbursal Summary by Month",
"Table",
null,
"Loan Portfolio",
"6",
null,
"loanOfficerIdSelectAll"
]
},
{
"row": [
"7",
"Loans Awaiting Disbursal Summary by Month",
"Table",
null,
"Loan Portfolio",
"10",
null,
"currencyIdSelectAll"
]
},
{
"row": [
"7",
"Loans Awaiting Disbursal Summary by Month",
"Table",
null,
"Loan Portfolio",
"20",
null,
"fundIdSelectAll"
]
},
{
"row": [
"7",
"Loans Awaiting Disbursal Summary by Month",
"Table",
null,
"Loan Portfolio",
"25",
null,
"loanProductIdSelectAll"
]
},
{
"row": [
"15",
"Portfolio at Risk",
"Table",
null,
"Loan Portfolio",
"5",
null,
"OfficeIdSelectOne"
]
},
{
"row": [
"15",
"Portfolio at Risk",
"Table",
null,
"Loan Portfolio",
"6",
null,
"loanOfficerIdSelectAll"
]
},
{
"row": [
"15",
"Portfolio at Risk",
"Table",
null,
"Loan Portfolio",
"10",
null,
"currencyIdSelectAll"
]
},
{
"row": [
"15",
"Portfolio at Risk",
"Table",
null,
"Loan Portfolio",
"20",
null,
"fundIdSelectAll"
]
},
{
"row": [
"15",
"Portfolio at Risk",
"Table",
null,
"Loan Portfolio",
"25",
null,
"loanProductIdSelectAll"
]
},
{
"row": [
"16",
"Portfolio at Risk by Branch",
"Table",
null,
"Loan Portfolio",
"5",
null,
"OfficeIdSelectOne"
]
},
{
"row": [
"16",
"Portfolio at Risk by Branch",
"Table",
null,
"Loan Portfolio",
"6",
null,
"loanOfficerIdSelectAll"
]
},
{
"row": [
"16",
"Portfolio at Risk by Branch",
"Table",
null,
"Loan Portfolio",
"10",
null,
"currencyIdSelectAll"
]
},
{
"row": [
"16",
"Portfolio at Risk by Branch",
"Table",
null,
"Loan Portfolio",
"20",
null,
"fundIdSelectAll"
]
},
{
"row": [
"16",
"Portfolio at Risk by Branch",
"Table",
null,
"Loan Portfolio",
"25",
null,
"loanProductIdSelectAll"
]
},
{
"row": [
"50",
"Trial Balance",
"Pentaho",
null,
"Accounting",
"5",
"branch",
"OfficeIdSelectOne"
]
},
{
"row": [
"50",
"Trial Balance",
"Pentaho",
null,
"Accounting",
"40",
"fromDate",
"startDateSelect"
]
},
{
"row": [
"50",
"Trial Balance",
"Pentaho",
null,
"Accounting",
"41",
"toDate",
"endDateSelect"
]
}
[
{
"reportId": 1,
"reportName": "Client Listing",
"reportType": "Table",
"reportCategory": "Client",
"coreReport": true,
"useReport": true,
"reportParameters": [
{
"reportParameterId": 5,
"parameterName": "OfficeIdSelectOne"
}
]
}
</code>
},
{
"reportId": 2,
"reportName": "Client Loans Listing",
"reportType": "Table",
"reportCategory": "Client",
"coreReport": true,
"useReport": true,
"reportParameters": [
{
"reportParameterId": 5,
"parameterName": "OfficeIdSelectOne"
},
{
"reportParameterId": 6,
"parameterName": "loanOfficerIdSelectAll"
},
{
"reportParameterId": 10,
"parameterName": "currencyIdSelectAll"
},
{
"reportParameterId": 20,
"parameterName": "fundIdSelectAll"
},
{
"reportParameterId": 25,
"parameterName": "loanProductIdSelectAll"
},
{
"reportParameterId": 26,
"parameterName": "loanPurposeIdSelectAll"
}
]
},...
]
</code>
</div>
</div>
@@ -11030,7 +10331,20 @@ GET https://DomainName/api/v1/reports
<div class="method-section">
<div class="method-description">
<h4>Running a Report</h4>
<p>Runs a report and returns the report output.</p>
<p>This resource allows you to run and receive output from pre-defined Mifos X reports. </p>
<p>Reports can also be used to provide data for searching and workflow functionality.</p>
<p>
The default output is a JSON formatted "Generic Resultset". The Generic Resultset contains
Column Heading as well as Data information. However, you can
export to CSV format by simply adding "&exportCSV=true" to the end
of your URL.</p>
<p>If Pentaho reports have been pre-defined, they can also be
run through this resource. Pentaho reports can return HTML, PDF or
CSV formats.</p>
<p>The Mifos X reference application uses a
JQuery plugin called stretchyreporting which, itself, uses this
reports resource to provide a pretty flexible reporting User
Interface (UI).</p>
<h5>Arguments</h5>
<dl class="argument-list">
<dt>R_'parameter names' ...</dt>
@@ -6,6 +6,7 @@
package org.mifosplatform.infrastructure.dataqueries.api;
import java.io.File;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
@@ -26,6 +27,7 @@ import javax.ws.rs.core.UriInfo;
import org.mifosplatform.infrastructure.core.api.ApiParameterHelper;
import org.mifosplatform.infrastructure.core.serialization.ToApiJsonSerializer;
import org.mifosplatform.infrastructure.dataqueries.data.GenericResultsetData;
import org.mifosplatform.infrastructure.dataqueries.data.ReportData;
import org.mifosplatform.infrastructure.dataqueries.service.GenericDataService;
import org.mifosplatform.infrastructure.dataqueries.service.ReadReportingService;
import org.mifosplatform.infrastructure.security.exception.NoAuthorizationException;
@@ -56,32 +58,16 @@ public class ReportsApiResource {
@GET
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON, "application/x-msdownload" })
@Produces({ MediaType.APPLICATION_JSON })
public Response retrieveReportList(@Context final UriInfo uriInfo) {
Map<String, String> extractedQueryParams = new HashMap<String, String>();
boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
boolean exportCsv = ApiParameterHelper.exportCsv(uriInfo.getQueryParameters());
boolean exportPdf = ApiParameterHelper.exportPdf(uriInfo.getQueryParameters());
final Collection<ReportData> result = this.readExtraDataAndReportingService.retrieveReportList();
final String json = this.toApiJsonSerializer.serializePretty(prettyPrint, result);
if (exportPdf) {
String result = this.readExtraDataAndReportingService.retrieveReportPDF(".", ".", extractedQueryParams);
return Response.ok().entity(result).header("Content-Disposition", "attachment;filename=ReportList.pdf").build();
}
if (!exportCsv) {
GenericResultsetData result = this.readExtraDataAndReportingService.retrieveGenericResultset(".", ".", extractedQueryParams);
final String json = this.toApiJsonSerializer.serializePretty(prettyPrint, result);
return Response.ok().entity(json).build();
}
StreamingOutput result = this.readExtraDataAndReportingService.retrieveReportCSV(".", ".", extractedQueryParams);
return Response.ok().entity(result).header("Content-Disposition", "attachment;filename=ReportList.csv").build();
return Response.ok().entity(json).build();
}
@GET
@@ -0,0 +1,47 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.infrastructure.dataqueries.data;
import java.util.Collection;
final public class ReportData {
@SuppressWarnings("unused")
private final Long reportId;
@SuppressWarnings("unused")
private final String reportName;
@SuppressWarnings("unused")
private final String reportType;
@SuppressWarnings("unused")
private final String reportSubType;
@SuppressWarnings("unused")
private final String reportCategory;
@SuppressWarnings("unused")
private final String reportSql;
@SuppressWarnings("unused")
private final Boolean coreReport;
@SuppressWarnings("unused")
private final Boolean useReport;
@SuppressWarnings("unused")
private final Collection<ReportParameterData> reportParameters;
public ReportData(final Long reportId, final String reportName,
final String reportType, final String reportSubType,
final String reportCategory, final String reportSql,
final Boolean coreReport, final Boolean useReport,
final Collection<ReportParameterData> reportParameters) {
this.reportId = reportId;
this.reportName = reportName;
this.reportType = reportType;
this.reportSubType = reportSubType;
this.reportCategory = reportCategory;
this.reportParameters = reportParameters;
this.reportSql = reportSql;
this.coreReport = coreReport;
this.useReport = useReport;
}
}
@@ -0,0 +1,24 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.infrastructure.dataqueries.data;
final public class ReportParameterData {
@SuppressWarnings("unused")
private final Long reportParameterId;
@SuppressWarnings("unused")
private final String reportParameterName;
@SuppressWarnings("unused")
private final String parameterName;
public ReportParameterData(final Long reportParameterId,
final String reportParameterName, final String parameterName) {
this.reportParameterId = reportParameterId;
this.reportParameterName = reportParameterName;
this.parameterName = parameterName;
}
}
@@ -0,0 +1,86 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.infrastructure.dataqueries.data;
final public class ReportParameterJoinData {
private final Long reportId;
private final String reportName;
private final String reportType;
private final String reportSubType;
private final String reportCategory;
private final String reportSql;
private final Boolean coreReport;
private final Boolean useReport;
private final Long reportParameterId;
private final String reportParameterName;
private final String parameterName;
public ReportParameterJoinData(final Long reportId,
final String reportName, final String reportType,
final String reportSubType, final String reportCategory,
final String reportSql, final Boolean coreReport,
final Boolean useReport, final Long reportParameterId,
final String reportParameterName, final String parameterName) {
this.reportId = reportId;
this.reportName = reportName;
this.reportType = reportType;
this.reportSubType = reportSubType;
this.reportCategory = reportCategory;
this.reportSql = reportSql;
this.coreReport = coreReport;
this.useReport = useReport;
this.reportParameterId = reportParameterId;
this.reportParameterName = reportParameterName;
this.parameterName = parameterName;
}
public Long getReportId() {
return reportId;
}
public String getReportName() {
return reportName;
}
public String getReportType() {
return reportType;
}
public String getReportSubType() {
return reportSubType;
}
public String getReportCategory() {
return reportCategory;
}
public String getReportSql() {
return reportSql;
}
public Boolean getCoreReport() {
return coreReport;
}
public Boolean getUseReport() {
return useReport;
}
public Long getReportParameterId() {
return reportParameterId;
}
public String getReportParameterName() {
return reportParameterName;
}
public String getParameterName() {
return parameterName;
}
}
@@ -5,22 +5,30 @@
*/
package org.mifosplatform.infrastructure.dataqueries.service;
import java.util.Collection;
import java.util.Map;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.StreamingOutput;
import org.mifosplatform.infrastructure.dataqueries.data.GenericResultsetData;
import org.mifosplatform.infrastructure.dataqueries.data.ReportData;
public interface ReadReportingService {
StreamingOutput retrieveReportCSV(String name, String type, Map<String, String> extractedQueryParams);
StreamingOutput retrieveReportCSV(String name, String type,
Map<String, String> extractedQueryParams);
GenericResultsetData retrieveGenericResultset(String name, String type, Map<String, String> extractedQueryParams);
GenericResultsetData retrieveGenericResultset(String name, String type,
Map<String, String> extractedQueryParams);
Response processPentahoRequest(String reportName, String outputType, Map<String, String> queryParams);
Response processPentahoRequest(String reportName, String outputType,
Map<String, String> queryParams);
String retrieveReportPDF(String name, String type, Map<String, String> extractedQueryParams);
String retrieveReportPDF(String name, String type,
Map<String, String> extractedQueryParams);
String getReportType(String reportName);
String getReportType(String reportName);
Collection<ReportData> retrieveReportList();
}
@@ -13,6 +13,10 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Date;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -22,10 +26,14 @@ import javax.ws.rs.core.Response;
import javax.ws.rs.core.StreamingOutput;
import org.apache.commons.lang.StringUtils;
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException;
import org.mifosplatform.infrastructure.core.service.FileUtils;
import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource;
import org.mifosplatform.infrastructure.dataqueries.data.GenericResultsetData;
import org.mifosplatform.infrastructure.dataqueries.data.ReportData;
import org.mifosplatform.infrastructure.dataqueries.data.ReportParameterData;
import org.mifosplatform.infrastructure.dataqueries.data.ReportParameterJoinData;
import org.mifosplatform.infrastructure.dataqueries.data.ResultsetColumnHeaderData;
import org.mifosplatform.infrastructure.dataqueries.data.ResultsetRowData;
import org.mifosplatform.infrastructure.dataqueries.exception.ReportNotFoundException;
@@ -48,6 +56,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.rowset.SqlRowSet;
import org.springframework.stereotype.Service;
@@ -59,372 +68,589 @@ import com.lowagie.text.pdf.PdfWriter;
@Service
public class ReadReportingServiceImpl implements ReadReportingService {
private final static Logger logger = LoggerFactory.getLogger(ReadReportingServiceImpl.class);
private final JdbcTemplate jdbcTemplate;
private final DataSource dataSource;
private final PlatformSecurityContext context;
private final GenericDataService genericDataService;
private boolean noPentaho = false;
@Autowired
public ReadReportingServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource,
final GenericDataService genericDataService) {
// kick off pentaho reports server
ClassicEngineBoot.getInstance().start();
noPentaho = false;
this.context = context;
this.dataSource = dataSource;
this.jdbcTemplate = new JdbcTemplate(this.dataSource);
this.genericDataService = genericDataService;
}
@Override
public StreamingOutput retrieveReportCSV(final String name, final String type, final Map<String, String> queryParams) {
return new StreamingOutput() {
@Override
public void write(final OutputStream out) {
try {
GenericResultsetData result = retrieveGenericResultset(name, type, queryParams);
StringBuffer sb = generateCsvFileBuffer(result);
InputStream in = new ByteArrayInputStream(sb.toString().getBytes("UTF-8"));
byte[] outputByte = new byte[4096];
Integer readLen = in.read(outputByte, 0, 4096);
while (readLen != -1) {
out.write(outputByte, 0, readLen);
readLen = in.read(outputByte, 0, 4096);
}
// in.close();
// out.flush();
// out.close();
} catch (Exception e) {
throw new PlatformDataIntegrityException("error.msg.exception.error", e.getMessage());
}
}
};
}
private StringBuffer generateCsvFileBuffer(final GenericResultsetData result) {
StringBuffer writer = new StringBuffer();
List<ResultsetColumnHeaderData> columnHeaders = result.getColumnHeaders();
logger.info("NO. of Columns: " + columnHeaders.size());
Integer chSize = columnHeaders.size();
for (int i = 0; i < chSize; i++) {
writer.append('"' + columnHeaders.get(i).getColumnName() + '"');
if (i < (chSize - 1)) writer.append(",");
}
writer.append('\n');
List<ResultsetRowData> data = result.getData();
List<String> row;
Integer rSize;
// String currCol;
String currColType;
String currVal;
String doubleQuote = "\"";
String twoDoubleQuotes = doubleQuote + doubleQuote;
logger.info("NO. of Rows: " + data.size());
for (int i = 0; i < data.size(); i++) {
row = data.get(i).getRow();
rSize = row.size();
for (int j = 0; j < rSize; j++) {
// currCol = columnHeaders.get(j).getColumnName();
currColType = columnHeaders.get(j).getColumnType();
currVal = row.get(j);
if (currVal != null) {
if (currColType.equals("DECIMAL") || currColType.equals("DOUBLE") || currColType.equals("BIGINT")
|| currColType.equals("SMALLINT") || currColType.equals("INT"))
writer.append(currVal);
else
writer.append('"' + genericDataService.replace(currVal, doubleQuote, twoDoubleQuotes) + '"');
}
if (j < (rSize - 1)) writer.append(",");
}
writer.append('\n');
}
return writer;
}
@Override
public GenericResultsetData retrieveGenericResultset(final String name, final String type, final Map<String, String> queryParams) {
long startTime = System.currentTimeMillis();
logger.info("STARTING REPORT: " + name + " Type: " + type);
String sql;
if (name.equals(".")) {
// this is to support api /reports - which isn't an important
// call. It isn't used in the default reporting UI. But there is a
// need to provide an api that does bring back 'permitted' reports
// PERMITTED REPORTS SQL
sql = "select r.report_id, r.report_name, r.report_type, r.report_subtype, r.report_category,"
+ " rp.parameter_id, rp.report_parameter_name, p.parameter_name" + " from stretchy_report r"
+ " left join stretchy_report_parameter rp on rp.report_id = r.report_id"
+ " left join stretchy_parameter p on p.parameter_id = rp.parameter_id" + " where exists" + " (select 'f'"
+ " from m_appuser_role ur " + " join m_role r on r.id = ur.role_id"
+ " left join m_role_permission rp on rp.role_id = r.id" + " left join m_permission p on p.id = rp.permission_id"
+ " where ur.appuser_id = " + context.authenticatedUser().getId()
+ " and (p.code in ('ALL_FUNCTIONS', 'ALL_FUNCTIONS_READ') or p.code = concat('READ_', r.report_name))) "
+ " order by r.report_name, rp.parameter_id";
} else {
sql = getSQLtoRun(name, type, queryParams);
}
GenericResultsetData result = genericDataService.fillGenericResultSet(sql);
long elapsed = System.currentTimeMillis() - startTime;
logger.info("FINISHING Report/Request Name: " + name + " - " + type + " Elapsed Time: " + elapsed);
return result;
}
private String getSQLtoRun(final String name, final String type, final Map<String, String> queryParams) {
String sql = getSql(name, type);
Set<String> keys = queryParams.keySet();
for (String key : keys) {
String pValue = queryParams.get(key);
// logger.info("(" + key + " : " + pValue + ")");
sql = genericDataService.replace(sql, key, pValue);
}
AppUser currentUser = context.authenticatedUser();
// Allows sql query to restrict data by office hierarchy if required
sql = genericDataService.replace(sql, "${currentUserHierarchy}", currentUser.getOffice().getHierarchy());
// Allows sql query to restrict data by current user Id if required
// (typically used to return report lists containing only reports
// permitted to be run by the user
sql = genericDataService.replace(sql, "${currentUserId}", currentUser.getId().toString());
sql = genericDataService.wrapSQL(sql);
return sql;
}
private String getSql(final String name, final String type) {
final String inputSql = "select " + type + "_sql as the_sql from stretchy_" + type + " where " + type + "_name = '" + name + "'";
final String inputSqlWrapped = genericDataService.wrapSQL(inputSql);
final SqlRowSet rs = this.jdbcTemplate.queryForRowSet(inputSqlWrapped);
if (rs.next()) { return rs.getString("the_sql"); }
throw new ReportNotFoundException(inputSql);
}
@Override
public String getReportType(final String reportName) {
final String sql = "SELECT ifnull(report_type,'') as report_type FROM `stretchy_report` where report_name = '" + reportName + "'";
final String sqlWrapped = genericDataService.wrapSQL(sql);
final SqlRowSet rs = this.jdbcTemplate.queryForRowSet(sqlWrapped);
if (rs.next()) { return rs.getString("report_type"); }
throw new ReportNotFoundException(sql);
}
@Override
public Response processPentahoRequest(final String reportName, final String outputTypeParam, final Map<String, String> queryParams) {
String outputType = "HTML";
if (StringUtils.isNotBlank(outputTypeParam)) outputType = outputTypeParam;
if (!(outputType.equalsIgnoreCase("HTML") || outputType.equalsIgnoreCase("PDF") || outputType.equalsIgnoreCase("XLS") || outputType
.equalsIgnoreCase("CSV")))
throw new PlatformDataIntegrityException("error.msg.invalid.outputType", "No matching Output Type: " + outputType);
if (noPentaho) { throw new PlatformDataIntegrityException("error.msg.no.pentaho", "Pentaho is not enabled",
"Pentaho is not enabled"); }
// TODO - JW - use pentaho location finder like Pawel does in Mifos
// String reportPath =
// "C:\\dev\\apache-tomcat-7.0.25\\webapps\\ROOT\\PentahoReports\\"
// + reportName + ".prpt";
/*
* String reportPath = FileUtils.MIFOSX_BASE_DIR + File.separator +
* ThreadLocalContextUtil.getTenant().getName() .replaceAll(" ",
* "").trim() + File.separator + "reports" + File.separator + reportName
* + ".prpt";
*/
final String reportPath = FileUtils.MIFOSX_BASE_DIR + File.separator + "pentahoReports" + File.separator + reportName + ".prpt";
logger.info("Report path: " + reportPath);
// load report definition
ResourceManager manager = new ResourceManager();
manager.registerDefaults();
Resource res;
try {
res = manager.createDirectly(reportPath, MasterReport.class);
MasterReport masterReport = (MasterReport) res.getResource();
addParametersToReport(masterReport, queryParams);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if ("PDF".equalsIgnoreCase(outputType)) {
PdfReportUtil.createPDF(masterReport, baos);
return Response.ok().entity(baos.toByteArray()).type("application/pdf").build();
}
if ("XLS".equalsIgnoreCase(outputType)) {
ExcelReportUtil.createXLS(masterReport, baos);
return Response.ok().entity(baos.toByteArray()).type("application/vnd.ms-excel")
.header("Content-Disposition", "attachment;filename=" + reportName.replaceAll(" ", "") + ".xls").build();
}
if ("CSV".equalsIgnoreCase(outputType)) {
CSVReportUtil.createCSV(masterReport, baos, "UTF-8");
return Response.ok().entity(baos.toByteArray()).type("application/x-msdownload")
.header("Content-Disposition", "attachment;filename=" + reportName.replaceAll(" ", "") + ".csv").build();
}
if ("HTML".equalsIgnoreCase(outputType)) {
HtmlReportUtil.createStreamHTML(masterReport, baos);
return Response.ok().entity(baos.toByteArray()).type("text/html").build();
}
} catch (ResourceException e) {
throw new PlatformDataIntegrityException("error.msg.reporting.error", e.getMessage());
} catch (ReportProcessingException e) {
throw new PlatformDataIntegrityException("error.msg.reporting.error", e.getMessage());
} catch (IOException e) {
throw new PlatformDataIntegrityException("error.msg.reporting.error", e.getMessage());
}
throw new PlatformDataIntegrityException("error.msg.invalid.outputType", "No matching Output Type: " + outputType);
}
private void addParametersToReport(final MasterReport report, final Map<String, String> queryParams) {
AppUser currentUser = context.authenticatedUser();
try {
ReportParameterValues rptParamValues = report.getParameterValues();
ReportParameterDefinition paramsDefinition = report.getParameterDefinition();
/*
* only allow integer, long, date and string parameter types and
* assume all mandatory - could go more detailed like Pawel did in
* Mifos later and could match incoming and pentaho parameters
* better... currently assuming they come in ok... and if not an
* error
*/
for (ParameterDefinitionEntry paramDefEntry : paramsDefinition.getParameterDefinitions()) {
String paramName = paramDefEntry.getName();
if (!((paramName.equals("tenantdb")) || (paramName.equals("userhierarchy")))) {
logger.info("paramName:" + paramName);
String pValue = queryParams.get(paramName);
if (StringUtils.isBlank(pValue))
throw new PlatformDataIntegrityException("error.msg.reporting.error", "Pentaho Parameter: " + paramName
+ " - not Provided");
Class<?> clazz = paramDefEntry.getValueType();
logger.info("addParametersToReport(" + paramName + " : " + pValue + " : " + clazz.getCanonicalName() + ")");
if (clazz.getCanonicalName().equalsIgnoreCase("java.lang.Integer"))
rptParamValues.put(paramName, Integer.parseInt(pValue));
else if (clazz.getCanonicalName().equalsIgnoreCase("java.lang.Long"))
rptParamValues.put(paramName, Long.parseLong(pValue));
else if (clazz.getCanonicalName().equalsIgnoreCase("java.sql.Date"))
rptParamValues.put(paramName, Date.valueOf(pValue));
else
rptParamValues.put(paramName, pValue);
}
}
// tenant database name and current user's office hierarchy
// passed as parameters to allow multitenant penaho reporting
// and
// data scoping
String tenantdb = dataSource.getConnection().getCatalog();
String userhierarchy = currentUser.getOffice().getHierarchy();
logger.info("db name:" + tenantdb + " userhierarchy:" + userhierarchy);
rptParamValues.put("tenantdb", tenantdb);
rptParamValues.put("userhierarchy", userhierarchy);
} catch (Exception e) {
logger.error("error.msg.reporting.error:" + e.getMessage());
throw new PlatformDataIntegrityException("error.msg.reporting.error", e.getMessage());
}
}
@Override
public String retrieveReportPDF(final String reportName, final String type, final Map<String, String> queryParams) {
String fileLocation = FileUtils.MIFOSX_BASE_DIR + File.separator + "";
if (!new File(fileLocation).isDirectory()) {
new File(fileLocation).mkdirs();
}
String genaratePdf = fileLocation + File.separator + reportName + ".pdf";
try {
GenericResultsetData result = retrieveGenericResultset(reportName, type, queryParams);
List<ResultsetColumnHeaderData> columnHeaders = result.getColumnHeaders();
List<ResultsetRowData> data = result.getData();
List<String> row;
logger.info("NO. of Columns: " + columnHeaders.size());
Integer chSize = columnHeaders.size();
Document document = new Document(PageSize.B0.rotate());
PdfWriter.getInstance(document, new FileOutputStream(new File(fileLocation + reportName + ".pdf")));
document.open();
PdfPTable table = new PdfPTable(chSize);
table.setWidthPercentage(100);
for (int i = 0; i < chSize; i++) {
table.addCell(columnHeaders.get(i).getColumnName());
}
table.completeRow();
Integer rSize;
String currColType;
String currVal;
logger.info("NO. of Rows: " + data.size());
for (int i = 0; i < data.size(); i++) {
row = data.get(i).getRow();
rSize = row.size();
for (int j = 0; j < rSize; j++) {
currColType = columnHeaders.get(j).getColumnType();
currVal = row.get(j);
if (currVal != null) {
if (currColType.equals("DECIMAL") || currColType.equals("DOUBLE") || currColType.equals("BIGINT")
|| currColType.equals("SMALLINT") || currColType.equals("INT")) {
table.addCell(currVal.toString());
} else {
table.addCell(currVal.toString());
}
}
}
}
table.completeRow();
document.add(table);
document.close();
return genaratePdf;
} catch (Exception e) {
logger.error("error.msg.reporting.error:" + e.getMessage());
throw new PlatformDataIntegrityException("error.msg.exception.error", e.getMessage());
}
}
private final static Logger logger = LoggerFactory
.getLogger(ReadReportingServiceImpl.class);
private final JdbcTemplate jdbcTemplate;
private final DataSource dataSource;
private final PlatformSecurityContext context;
private final GenericDataService genericDataService;
private boolean noPentaho = false;
@Autowired
public ReadReportingServiceImpl(final PlatformSecurityContext context,
final TenantAwareRoutingDataSource dataSource,
final GenericDataService genericDataService) {
// kick off pentaho reports server
ClassicEngineBoot.getInstance().start();
noPentaho = false;
this.context = context;
this.dataSource = dataSource;
this.jdbcTemplate = new JdbcTemplate(this.dataSource);
this.genericDataService = genericDataService;
}
@Override
public StreamingOutput retrieveReportCSV(final String name,
final String type, final Map<String, String> queryParams) {
return new StreamingOutput() {
@Override
public void write(final OutputStream out) {
try {
GenericResultsetData result = retrieveGenericResultset(
name, type, queryParams);
StringBuffer sb = generateCsvFileBuffer(result);
InputStream in = new ByteArrayInputStream(sb.toString()
.getBytes("UTF-8"));
byte[] outputByte = new byte[4096];
Integer readLen = in.read(outputByte, 0, 4096);
while (readLen != -1) {
out.write(outputByte, 0, readLen);
readLen = in.read(outputByte, 0, 4096);
}
// in.close();
// out.flush();
// out.close();
} catch (Exception e) {
throw new PlatformDataIntegrityException(
"error.msg.exception.error", e.getMessage());
}
}
};
}
private StringBuffer generateCsvFileBuffer(final GenericResultsetData result) {
StringBuffer writer = new StringBuffer();
List<ResultsetColumnHeaderData> columnHeaders = result
.getColumnHeaders();
logger.info("NO. of Columns: " + columnHeaders.size());
Integer chSize = columnHeaders.size();
for (int i = 0; i < chSize; i++) {
writer.append('"' + columnHeaders.get(i).getColumnName() + '"');
if (i < (chSize - 1))
writer.append(",");
}
writer.append('\n');
List<ResultsetRowData> data = result.getData();
List<String> row;
Integer rSize;
// String currCol;
String currColType;
String currVal;
String doubleQuote = "\"";
String twoDoubleQuotes = doubleQuote + doubleQuote;
logger.info("NO. of Rows: " + data.size());
for (int i = 0; i < data.size(); i++) {
row = data.get(i).getRow();
rSize = row.size();
for (int j = 0; j < rSize; j++) {
// currCol = columnHeaders.get(j).getColumnName();
currColType = columnHeaders.get(j).getColumnType();
currVal = row.get(j);
if (currVal != null) {
if (currColType.equals("DECIMAL")
|| currColType.equals("DOUBLE")
|| currColType.equals("BIGINT")
|| currColType.equals("SMALLINT")
|| currColType.equals("INT"))
writer.append(currVal);
else
writer.append('"' + genericDataService.replace(currVal,
doubleQuote, twoDoubleQuotes) + '"');
}
if (j < (rSize - 1))
writer.append(",");
}
writer.append('\n');
}
return writer;
}
@Override
public GenericResultsetData retrieveGenericResultset(final String name,
final String type, final Map<String, String> queryParams) {
long startTime = System.currentTimeMillis();
logger.info("STARTING REPORT: " + name + " Type: " + type);
String sql;
if (name.equals(".")) {
// this is to support api /reports - which isn't an important
// call. It isn't used in the default reporting UI. But there is a
// need to provide an api that does bring back 'permitted' reports
// PERMITTED REPORTS SQL
sql = "select r.report_id, r.report_name, r.report_type, r.report_subtype, r.report_category,"
+ " rp.parameter_id, rp.report_parameter_name, p.parameter_name"
+ " from stretchy_report r"
+ " left join stretchy_report_parameter rp on rp.report_id = r.report_id"
+ " left join stretchy_parameter p on p.parameter_id = rp.parameter_id"
+ " where exists"
+ " (select 'f'"
+ " from m_appuser_role ur "
+ " join m_role r on r.id = ur.role_id"
+ " left join m_role_permission rp on rp.role_id = r.id"
+ " left join m_permission p on p.id = rp.permission_id"
+ " where ur.appuser_id = "
+ context.authenticatedUser().getId()
+ " and (p.code in ('ALL_FUNCTIONS', 'ALL_FUNCTIONS_READ') or p.code = concat('READ_', r.report_name))) "
+ " order by r.report_name, rp.parameter_id";
} else {
sql = getSQLtoRun(name, type, queryParams);
}
GenericResultsetData result = genericDataService
.fillGenericResultSet(sql);
long elapsed = System.currentTimeMillis() - startTime;
logger.info("FINISHING Report/Request Name: " + name + " - " + type
+ " Elapsed Time: " + elapsed);
return result;
}
private String getSQLtoRun(final String name, final String type,
final Map<String, String> queryParams) {
String sql = getSql(name, type);
Set<String> keys = queryParams.keySet();
for (String key : keys) {
String pValue = queryParams.get(key);
// logger.info("(" + key + " : " + pValue + ")");
sql = genericDataService.replace(sql, key, pValue);
}
AppUser currentUser = context.authenticatedUser();
// Allows sql query to restrict data by office hierarchy if required
sql = genericDataService.replace(sql, "${currentUserHierarchy}",
currentUser.getOffice().getHierarchy());
// Allows sql query to restrict data by current user Id if required
// (typically used to return report lists containing only reports
// permitted to be run by the user
sql = genericDataService.replace(sql, "${currentUserId}", currentUser
.getId().toString());
sql = genericDataService.wrapSQL(sql);
return sql;
}
private String getSql(final String name, final String type) {
final String inputSql = "select " + type
+ "_sql as the_sql from stretchy_" + type + " where " + type
+ "_name = '" + name + "'";
final String inputSqlWrapped = genericDataService.wrapSQL(inputSql);
final SqlRowSet rs = this.jdbcTemplate.queryForRowSet(inputSqlWrapped);
if (rs.next()) {
return rs.getString("the_sql");
}
throw new ReportNotFoundException(inputSql);
}
@Override
public String getReportType(final String reportName) {
final String sql = "SELECT ifnull(report_type,'') as report_type FROM `stretchy_report` where report_name = '"
+ reportName + "'";
final String sqlWrapped = genericDataService.wrapSQL(sql);
final SqlRowSet rs = this.jdbcTemplate.queryForRowSet(sqlWrapped);
if (rs.next()) {
return rs.getString("report_type");
}
throw new ReportNotFoundException(sql);
}
@Override
public Response processPentahoRequest(final String reportName,
final String outputTypeParam, final Map<String, String> queryParams) {
String outputType = "HTML";
if (StringUtils.isNotBlank(outputTypeParam))
outputType = outputTypeParam;
if (!(outputType.equalsIgnoreCase("HTML")
|| outputType.equalsIgnoreCase("PDF")
|| outputType.equalsIgnoreCase("XLS") || outputType
.equalsIgnoreCase("CSV")))
throw new PlatformDataIntegrityException(
"error.msg.invalid.outputType", "No matching Output Type: "
+ outputType);
if (noPentaho) {
throw new PlatformDataIntegrityException("error.msg.no.pentaho",
"Pentaho is not enabled", "Pentaho is not enabled");
}
final String reportPath = FileUtils.MIFOSX_BASE_DIR + File.separator
+ "pentahoReports" + File.separator + reportName + ".prpt";
logger.info("Report path: " + reportPath);
// load report definition
ResourceManager manager = new ResourceManager();
manager.registerDefaults();
Resource res;
try {
res = manager.createDirectly(reportPath, MasterReport.class);
MasterReport masterReport = (MasterReport) res.getResource();
addParametersToReport(masterReport, queryParams);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if ("PDF".equalsIgnoreCase(outputType)) {
PdfReportUtil.createPDF(masterReport, baos);
return Response.ok().entity(baos.toByteArray())
.type("application/pdf").build();
}
if ("XLS".equalsIgnoreCase(outputType)) {
ExcelReportUtil.createXLS(masterReport, baos);
return Response
.ok()
.entity(baos.toByteArray())
.type("application/vnd.ms-excel")
.header("Content-Disposition",
"attachment;filename="
+ reportName.replaceAll(" ", "")
+ ".xls").build();
}
if ("CSV".equalsIgnoreCase(outputType)) {
CSVReportUtil.createCSV(masterReport, baos, "UTF-8");
return Response
.ok()
.entity(baos.toByteArray())
.type("application/x-msdownload")
.header("Content-Disposition",
"attachment;filename="
+ reportName.replaceAll(" ", "")
+ ".csv").build();
}
if ("HTML".equalsIgnoreCase(outputType)) {
HtmlReportUtil.createStreamHTML(masterReport, baos);
return Response.ok().entity(baos.toByteArray())
.type("text/html").build();
}
} catch (ResourceException e) {
throw new PlatformDataIntegrityException(
"error.msg.reporting.error", e.getMessage());
} catch (ReportProcessingException e) {
throw new PlatformDataIntegrityException(
"error.msg.reporting.error", e.getMessage());
} catch (IOException e) {
throw new PlatformDataIntegrityException(
"error.msg.reporting.error", e.getMessage());
}
throw new PlatformDataIntegrityException(
"error.msg.invalid.outputType", "No matching Output Type: "
+ outputType);
}
private void addParametersToReport(final MasterReport report,
final Map<String, String> queryParams) {
AppUser currentUser = context.authenticatedUser();
try {
ReportParameterValues rptParamValues = report.getParameterValues();
ReportParameterDefinition paramsDefinition = report
.getParameterDefinition();
/*
* only allow integer, long, date and string parameter types and
* assume all mandatory - could go more detailed like Pawel did in
* Mifos later and could match incoming and pentaho parameters
* better... currently assuming they come in ok... and if not an
* error
*/
for (ParameterDefinitionEntry paramDefEntry : paramsDefinition
.getParameterDefinitions()) {
String paramName = paramDefEntry.getName();
if (!((paramName.equals("tenantdb")) || (paramName
.equals("userhierarchy")))) {
logger.info("paramName:" + paramName);
String pValue = queryParams.get(paramName);
if (StringUtils.isBlank(pValue))
throw new PlatformDataIntegrityException(
"error.msg.reporting.error",
"Pentaho Parameter: " + paramName
+ " - not Provided");
Class<?> clazz = paramDefEntry.getValueType();
logger.info("addParametersToReport(" + paramName + " : "
+ pValue + " : " + clazz.getCanonicalName() + ")");
if (clazz.getCanonicalName().equalsIgnoreCase(
"java.lang.Integer"))
rptParamValues.put(paramName, Integer.parseInt(pValue));
else if (clazz.getCanonicalName().equalsIgnoreCase(
"java.lang.Long"))
rptParamValues.put(paramName, Long.parseLong(pValue));
else if (clazz.getCanonicalName().equalsIgnoreCase(
"java.sql.Date"))
rptParamValues.put(paramName, Date.valueOf(pValue));
else
rptParamValues.put(paramName, pValue);
}
}
// tenant database name and current user's office hierarchy
// passed as parameters to allow multitenant penaho reporting
// and
// data scoping
String tenantdb = dataSource.getConnection().getCatalog();
String userhierarchy = currentUser.getOffice().getHierarchy();
logger.info("db name:" + tenantdb + " userhierarchy:"
+ userhierarchy);
rptParamValues.put("tenantdb", tenantdb);
rptParamValues.put("userhierarchy", userhierarchy);
} catch (Exception e) {
logger.error("error.msg.reporting.error:" + e.getMessage());
throw new PlatformDataIntegrityException(
"error.msg.reporting.error", e.getMessage());
}
}
@Override
public String retrieveReportPDF(final String reportName, final String type,
final Map<String, String> queryParams) {
String fileLocation = FileUtils.MIFOSX_BASE_DIR + File.separator + "";
if (!new File(fileLocation).isDirectory()) {
new File(fileLocation).mkdirs();
}
String genaratePdf = fileLocation + File.separator + reportName
+ ".pdf";
try {
GenericResultsetData result = retrieveGenericResultset(reportName,
type, queryParams);
List<ResultsetColumnHeaderData> columnHeaders = result
.getColumnHeaders();
List<ResultsetRowData> data = result.getData();
List<String> row;
logger.info("NO. of Columns: " + columnHeaders.size());
Integer chSize = columnHeaders.size();
Document document = new Document(PageSize.B0.rotate());
PdfWriter.getInstance(document, new FileOutputStream(new File(
fileLocation + reportName + ".pdf")));
document.open();
PdfPTable table = new PdfPTable(chSize);
table.setWidthPercentage(100);
for (int i = 0; i < chSize; i++) {
table.addCell(columnHeaders.get(i).getColumnName());
}
table.completeRow();
Integer rSize;
String currColType;
String currVal;
logger.info("NO. of Rows: " + data.size());
for (int i = 0; i < data.size(); i++) {
row = data.get(i).getRow();
rSize = row.size();
for (int j = 0; j < rSize; j++) {
currColType = columnHeaders.get(j).getColumnType();
currVal = row.get(j);
if (currVal != null) {
if (currColType.equals("DECIMAL")
|| currColType.equals("DOUBLE")
|| currColType.equals("BIGINT")
|| currColType.equals("SMALLINT")
|| currColType.equals("INT")) {
table.addCell(currVal.toString());
} else {
table.addCell(currVal.toString());
}
}
}
}
table.completeRow();
document.add(table);
document.close();
return genaratePdf;
} catch (Exception e) {
logger.error("error.msg.reporting.error:" + e.getMessage());
throw new PlatformDataIntegrityException(
"error.msg.exception.error", e.getMessage());
}
}
@Override
public Collection<ReportData> retrieveReportList() {
ReportParameterJoinMapper rm = new ReportParameterJoinMapper();
String sql = rm.schema(false, context.authenticatedUser().getId());
Collection<ReportParameterJoinData> rpJoins = this.jdbcTemplate.query(
sql, rm, new Object[] {});
Collection<ReportData> reportList = new ArrayList<ReportData>();
if (rpJoins == null)
return reportList;
Collection<ReportParameterData> reportParameters = null;
Long reportId = null;
String reportName = null;
String reportType = null;
String reportSubType = null;
String reportCategory = null;
Boolean coreReport = null;
Boolean useReport = null;
String reportSql = null;
Long prevReportId = (long) -1234;
Boolean firstReport = true;
for (ReportParameterJoinData rpJoin : rpJoins) {
if (rpJoin.getReportId().equals(prevReportId)) {
// more than one parameter for report
reportParameters.add(new ReportParameterData(rpJoin
.getReportParameterId(), rpJoin
.getReportParameterName(), rpJoin.getParameterName()));
} else {
if (firstReport) {
firstReport = false;
}
else
{
// write report entry
reportList
.add(new ReportData(reportId, reportName,
reportType, reportSubType, reportCategory,
reportSql, coreReport, useReport,
reportParameters));
}
prevReportId = rpJoin.getReportId();
reportId = rpJoin.getReportId();
reportName = rpJoin.getReportName();
reportType = rpJoin.getReportType();
reportSubType = rpJoin.getReportSubType();
reportCategory = rpJoin.getReportCategory();
reportSql = rpJoin.getReportSql();
coreReport = rpJoin.getCoreReport();
useReport = rpJoin.getUseReport();
if (rpJoin.getReportParameterId() != null) {
// report has at least one parameter
reportParameters = new ArrayList<ReportParameterData>();
reportParameters.add(new ReportParameterData(rpJoin
.getReportParameterId(), rpJoin
.getReportParameterName(), rpJoin
.getParameterName()));
} else {
reportParameters = null;
}
}
}
// write last report
reportList.add(new ReportData(reportId, reportName, reportType,
reportSubType, reportCategory, reportSql, coreReport,
useReport, reportParameters));
return reportList;
}
private static final class ReportParameterJoinMapper implements
RowMapper<ReportParameterJoinData> {
public String schema(boolean includeSql, Long userId) {
String sql = "select r.report_id as reportId, r.report_name as reportName, r.report_type as reportType, "
+ " r.report_subtype as reportSubType, r.report_category as reportCategory, r.core_report as coreReport, r.use_report as useReport, "
+ " rp.parameter_id as reportParameterId, rp.report_parameter_name as reportParameterName, p.parameter_name as parameterName";
if (includeSql)
sql += ", r.report_sql as reportSql ";
sql += " from stretchy_report r"
+ " left join stretchy_report_parameter rp on rp.report_id = r.report_id"
+ " left join stretchy_parameter p on p.parameter_id = rp.parameter_id"
+ " where exists"
+ " (select 'f'"
+ " from m_appuser_role ur "
+ " join m_role r on r.id = ur.role_id"
+ " left join m_role_permission rp on rp.role_id = r.id"
+ " left join m_permission p on p.id = rp.permission_id"
+ " where ur.appuser_id = "
+ userId
+ " and (p.code in ('ALL_FUNCTIONS', 'ALL_FUNCTIONS_READ') or p.code = concat('READ_', r.report_name))) "
+ " order by r.report_id, rp.parameter_id";
return sql;
}
@Override
public ReportParameterJoinData mapRow(final ResultSet rs,
@SuppressWarnings("unused") final int rowNum)
throws SQLException {
final Long reportId = rs.getLong("reportId");
final String reportName = rs.getString("reportName");
final String reportType = rs.getString("reportType");
final String reportSubType = rs.getString("reportSubType");
final String reportCategory = rs.getString("reportCategory");
final Boolean coreReport = rs.getBoolean("coreReport");
final Boolean useReport = rs.getBoolean("useReport");
String reportSql;
// reportSql might not be on the select list of columns
try {
reportSql = rs.getString("reportSql");
} catch (SQLException e) {
reportSql = null;
}
final Long reportParameterId = JdbcSupport.getLong(rs,
"reportParameterId");
final String reportParameterName = rs
.getString("reportParameterName");
final String parameterName = rs.getString("parameterName");
return new ReportParameterJoinData(reportId, reportName,
reportType, reportSubType, reportCategory, reportSql,
coreReport, useReport, reportParameterId,
reportParameterName, parameterName);
}
}
}