[Major] Made GenericReport to be auto closeable
This commit is contained in:
parent
543810c8f9
commit
0d1ab66cb9
|
@ -106,10 +106,10 @@ public class ReportResource {
|
|||
}
|
||||
|
||||
JsonArray result = new JsonArray();
|
||||
try (StrolchTransaction tx = RestfulStrolchComponent.getInstance().openTx(cert, realm, getContext())) {
|
||||
tx.getPrivilegeContext().validateAction(new SimpleRestrictable(ReportSearch.class.getName(), id));
|
||||
try (StrolchTransaction tx = RestfulStrolchComponent.getInstance().openTx(cert, realm, getContext());
|
||||
Report report = new Report(tx, id)) {
|
||||
|
||||
Report report = new Report(tx, id);
|
||||
tx.getPrivilegeContext().validateAction(new SimpleRestrictable(ReportSearch.class.getName(), id));
|
||||
|
||||
// set i18n data if possible
|
||||
if (localeJ != null)
|
||||
|
@ -160,11 +160,10 @@ public class ReportResource {
|
|||
localeJ = localesJ.get(cert.getLocale().toString()).getAsJsonObject();
|
||||
}
|
||||
|
||||
try (StrolchTransaction tx = RestfulStrolchComponent.getInstance().openTx(cert, realm, getContext())) {
|
||||
tx.getPrivilegeContext().validateAction(new SimpleRestrictable(ReportSearch.class.getName(), id));
|
||||
try (StrolchTransaction tx = RestfulStrolchComponent.getInstance().openTx(cert, realm, getContext());
|
||||
Report report = new Report(tx, id)) {
|
||||
|
||||
// get report
|
||||
Report report = new Report(tx, id);
|
||||
tx.getPrivilegeContext().validateAction(new SimpleRestrictable(ReportSearch.class.getName(), id));
|
||||
|
||||
// set i18n data if possible
|
||||
if (localeJ != null)
|
||||
|
@ -260,14 +259,13 @@ public class ReportResource {
|
|||
localeJ = localesJ.get(cert.getLocale().toString()).getAsJsonObject();
|
||||
}
|
||||
|
||||
try (StrolchTransaction tx = RestfulStrolchComponent.getInstance().openTx(cert, realm, getContext())) {
|
||||
long start = System.nanoTime();
|
||||
|
||||
try (StrolchTransaction tx = RestfulStrolchComponent.getInstance().openTx(cert, realm, getContext());
|
||||
Report report = new Report(tx, id)) {
|
||||
|
||||
tx.getPrivilegeContext().validateAction(new SimpleRestrictable(ReportSearch.class.getName(), id));
|
||||
|
||||
long start = System.nanoTime();
|
||||
|
||||
// get report
|
||||
Report report = new Report(tx, id);
|
||||
|
||||
// set i18n data if possible
|
||||
if (localeJ != null)
|
||||
report.getReportPolicy().setI18nData(localeJ);
|
||||
|
@ -354,54 +352,56 @@ public class ReportResource {
|
|||
localeJ = localesJ.get(cert.getLocale().toString()).getAsJsonObject();
|
||||
}
|
||||
|
||||
try (StrolchTransaction tx = RestfulStrolchComponent.getInstance().openTx(cert, realm, getContext())) {
|
||||
tx.getPrivilegeContext().validateAction(new SimpleRestrictable(ReportSearch.class.getName(), id));
|
||||
// create CSV printer with header
|
||||
StreamingOutput out = getOut(cert, realm, id, localeJ, filters);
|
||||
|
||||
// get report
|
||||
Report report = new Report(tx, id);
|
||||
|
||||
// set i18n data if possible
|
||||
if (localeJ != null)
|
||||
report.getReportPolicy().setI18nData(localeJ);
|
||||
|
||||
// add filters from request
|
||||
filters.keySet().forEach(f -> report.filter(f, filters.getSet(f)));
|
||||
|
||||
// get headers
|
||||
List<String> orderedColumnKeys = report.getColumnKeys();
|
||||
String[] headers = new String[orderedColumnKeys.size()];
|
||||
orderedColumnKeys.toArray(headers);
|
||||
|
||||
if (localeJ != null) {
|
||||
for (int i = 0; i < headers.length; i++) {
|
||||
if (localeJ.has(headers[i]))
|
||||
headers[i] = localeJ.get(headers[i]).getAsString();
|
||||
}
|
||||
}
|
||||
|
||||
// create CSV printer with header
|
||||
StreamingOutput out = getOut(report, headers);
|
||||
|
||||
// send
|
||||
String fileName = id + "_" + System.currentTimeMillis() + ".csv";
|
||||
return Response.ok(out, TEXT_CSV_TYPE)
|
||||
.header("Content-Disposition", "attachment; filename=\"" + fileName + "\"").build();
|
||||
}
|
||||
// send
|
||||
String fileName = id + "_" + System.currentTimeMillis() + ".csv";
|
||||
return Response.ok(out, TEXT_CSV_TYPE)
|
||||
.header("Content-Disposition", "attachment; filename=\"" + fileName + "\"").build();
|
||||
}
|
||||
|
||||
private StreamingOutput getOut(Report report, String[] headers) {
|
||||
private StreamingOutput getOut(Certificate cert, String realm, String reportId, JsonObject localeJ,
|
||||
MapOfSets<String, String> filters) {
|
||||
|
||||
return out -> {
|
||||
|
||||
// get report content and add to the buffer
|
||||
try (CSVPrinter csvP = new CSVPrinter(new OutputStreamWriter(out),
|
||||
CSVFormat.DEFAULT.withHeader(headers).withDelimiter(';'))) {
|
||||
report.doReport().forEach(row -> {
|
||||
try {
|
||||
csvP.printRecord(row.valueStream().collect(Collectors.toList())); // add to CSV
|
||||
} catch (Exception e) {
|
||||
logger.error("Could not write CSV row", e);
|
||||
try (StrolchTransaction tx = RestfulStrolchComponent.getInstance().openTx(cert, realm, getContext());
|
||||
Report report = new Report(tx, reportId)) {
|
||||
|
||||
tx.getPrivilegeContext().validateAction(new SimpleRestrictable(ReportSearch.class.getName(), reportId));
|
||||
|
||||
// set i18n data if possible
|
||||
if (localeJ != null)
|
||||
report.getReportPolicy().setI18nData(localeJ);
|
||||
|
||||
// add filters from request
|
||||
filters.keySet().forEach(f -> report.filter(f, filters.getSet(f)));
|
||||
|
||||
// get headers
|
||||
List<String> orderedColumnKeys = report.getColumnKeys();
|
||||
String[] headers = new String[orderedColumnKeys.size()];
|
||||
orderedColumnKeys.toArray(headers);
|
||||
|
||||
if (localeJ != null) {
|
||||
for (int i = 0; i < headers.length; i++) {
|
||||
if (localeJ.has(headers[i]))
|
||||
headers[i] = localeJ.get(headers[i]).getAsString();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// get report content and add to the buffer
|
||||
try (CSVPrinter csvP = new CSVPrinter(new OutputStreamWriter(out),
|
||||
CSVFormat.DEFAULT.withHeader(headers).withDelimiter(';'))) {
|
||||
|
||||
report.doReport().forEach(row -> {
|
||||
try {
|
||||
csvP.printRecord(row.valueStream().collect(Collectors.toList())); // add to CSV
|
||||
} catch (Exception e) {
|
||||
logger.error("Could not write CSV row", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ import li.strolch.report.policy.ReportPolicy;
|
|||
import li.strolch.utils.collections.DateRange;
|
||||
import li.strolch.utils.collections.MapOfSets;
|
||||
|
||||
public class Report {
|
||||
public class Report implements AutoCloseable {
|
||||
|
||||
private final ReportPolicy reportPolicy;
|
||||
|
||||
|
@ -88,4 +88,12 @@ public class Report {
|
|||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
try {
|
||||
this.reportPolicy.close();
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("Failed to close underlying policy " + this.reportPolicy.getClass(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -129,6 +129,10 @@ public class GenericReport extends ReportPolicy {
|
|||
}
|
||||
}
|
||||
|
||||
public boolean isDescending() {
|
||||
return this.descending;
|
||||
}
|
||||
|
||||
public void setI18nData(JsonObject i18nData) {
|
||||
this.i18nData = i18nData;
|
||||
}
|
||||
|
|
|
@ -44,6 +44,10 @@ public abstract class ReportPolicy extends StrolchPolicy {
|
|||
|
||||
public abstract long getCounter();
|
||||
|
||||
public void close() throws Exception {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void undo() {
|
||||
// can't be undone
|
||||
|
|
|
@ -46,10 +46,10 @@ public class GenericReportTest {
|
|||
@Test
|
||||
public void shouldGenerateJsonReport() {
|
||||
|
||||
try (StrolchTransaction tx = runtimeMock.openUserTx(certificate)) {
|
||||
try (StrolchTransaction tx = runtimeMock.openUserTx(certificate);
|
||||
Report report = new Report(tx, "stockReport")) {
|
||||
|
||||
new Report(tx, "stockReport") //
|
||||
.doReportAsJson() //
|
||||
report.doReportAsJson() //
|
||||
.forEach(e -> {
|
||||
|
||||
switch (e.get("slot").getAsString()) {
|
||||
|
@ -111,10 +111,10 @@ public class GenericReportTest {
|
|||
@Test
|
||||
public void shouldFilterReport1() {
|
||||
|
||||
try (StrolchTransaction tx = runtimeMock.openUserTx(certificate)) {
|
||||
try (StrolchTransaction tx = runtimeMock.openUserTx(certificate);
|
||||
Report report = new Report(tx, "stockReport")) {
|
||||
|
||||
new Report(tx, "stockReport") //
|
||||
.filter("Product", "product01") //
|
||||
report.filter("Product", "product01") //
|
||||
.doReportAsJson() //
|
||||
.forEach(e -> {
|
||||
|
||||
|
@ -134,10 +134,10 @@ public class GenericReportTest {
|
|||
@Test
|
||||
public void shouldFilterReport2() {
|
||||
|
||||
try (StrolchTransaction tx = runtimeMock.openUserTx(certificate)) {
|
||||
try (StrolchTransaction tx = runtimeMock.openUserTx(certificate);
|
||||
Report report = new Report(tx, "stockReport")) {
|
||||
|
||||
new Report(tx, "stockReport") //
|
||||
.filter("Product", "product01") //
|
||||
report.filter("Product", "product01") //
|
||||
.filter("Location", "location02") //
|
||||
.doReportAsJson() //
|
||||
.forEach(e -> {
|
||||
|
@ -157,15 +157,15 @@ public class GenericReportTest {
|
|||
@Test
|
||||
public void shouldFilterReportByDateRange1() {
|
||||
|
||||
try (StrolchTransaction tx = runtimeMock.openUserTx(certificate)) {
|
||||
try (StrolchTransaction tx = runtimeMock.openUserTx(certificate);
|
||||
Report report = new Report(tx, "stockReport")) {
|
||||
|
||||
Date from = new Date(LocalDate.of(2016, 1, 1).toEpochDay() * 86400000);
|
||||
Date to = new Date(LocalDate.of(2017, 1, 1).toEpochDay() * 86400000);
|
||||
DateRange dateRange = new DateRange().from(from, true).to(to, false);
|
||||
|
||||
// expect no slots as all not in date range
|
||||
List<JsonObject> result = new Report(tx, "stockReport") //
|
||||
.filter("Product", "product01") //
|
||||
List<JsonObject> result = report.filter("Product", "product01") //
|
||||
.dateRange(dateRange) //
|
||||
.doReportAsJson() //
|
||||
.collect(toList());
|
||||
|
@ -189,38 +189,48 @@ public class GenericReportTest {
|
|||
try (StrolchTransaction tx = runtimeMock.openUserTx(certificate)) {
|
||||
|
||||
Date from = new Date(LocalDate.of(2016, 1, 1).toEpochDay() * 86400000);
|
||||
Date to = new Date(LocalDate.of(2017, 1, 1).toEpochDay() * 86400000);
|
||||
DateRange dateRange = new DateRange().from(from, true).to(to, false);
|
||||
|
||||
// expect no orders as all not in date range
|
||||
Report report = new Report(tx, "fromStockReport");
|
||||
List<JsonObject> result = report.filter("Product", "product01").dateRange(dateRange).doReportAsJson()
|
||||
.collect(toList());
|
||||
assertTrue(result.isEmpty());
|
||||
try (Report report = new Report(tx, "fromStockReport")) {
|
||||
|
||||
Date to = new Date(LocalDate.of(2017, 1, 1).toEpochDay() * 86400000);
|
||||
DateRange dateRange = new DateRange().from(from, true).to(to, false);
|
||||
|
||||
List<JsonObject> result = report.filter("Product", "product01").dateRange(dateRange).doReportAsJson()
|
||||
.collect(toList());
|
||||
assertTrue(result.isEmpty());
|
||||
}
|
||||
|
||||
// expect 2 orders, as in date range
|
||||
to = new Date(LocalDate.of(2017, 3, 1).toEpochDay() * 86400000);
|
||||
dateRange = new DateRange().from(from, true).to(to, false);
|
||||
report = new Report(tx, "fromStockReport");
|
||||
result = report.filter("Product", "product01").dateRange(dateRange).doReportAsJson().collect(toList());
|
||||
assertEquals(2, result.size());
|
||||
try (Report report = new Report(tx, "fromStockReport")) {
|
||||
|
||||
Date to = new Date(LocalDate.of(2017, 3, 1).toEpochDay() * 86400000);
|
||||
DateRange dateRange = new DateRange().from(from, true).to(to, false);
|
||||
|
||||
List<JsonObject> result = report.filter("Product", "product01").dateRange(dateRange).doReportAsJson()
|
||||
.collect(toList());
|
||||
assertEquals(2, result.size());
|
||||
}
|
||||
|
||||
// expect 4 orders, as all in date range
|
||||
to = new Date(LocalDate.of(2017, 3, 2).toEpochDay() * 86400000);
|
||||
dateRange = new DateRange().from(from, true).to(to, false);
|
||||
report = new Report(tx, "fromStockReport");
|
||||
result = report.filter("Product", "product01", "product02").dateRange(dateRange).doReportAsJson()
|
||||
.collect(toList());
|
||||
assertEquals(4, result.size());
|
||||
try (Report report = new Report(tx, "fromStockReport")) {
|
||||
|
||||
Date to = new Date(LocalDate.of(2017, 3, 2).toEpochDay() * 86400000);
|
||||
DateRange dateRange = new DateRange().from(from, true).to(to, false);
|
||||
|
||||
List<JsonObject> result = report.filter("Product", "product01", "product02").dateRange(dateRange)
|
||||
.doReportAsJson().collect(toList());
|
||||
assertEquals(4, result.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCreateFilterCriteria() {
|
||||
|
||||
try (StrolchTransaction tx = runtimeMock.openUserTx(certificate)) {
|
||||
try (StrolchTransaction tx = runtimeMock.openUserTx(certificate);
|
||||
Report report = new Report(tx, "stockReport")) {
|
||||
|
||||
Report report = new Report(tx, "stockReport");
|
||||
MapOfSets<String, StrolchRootElement> filterCriteria = report.generateFilterCriteria();
|
||||
|
||||
assertFalse(filterCriteria.containsSet("Location"));
|
||||
|
@ -237,9 +247,9 @@ public class GenericReportTest {
|
|||
@Test
|
||||
public void shouldCreateFilterCriteriaFiltered1() {
|
||||
|
||||
try (StrolchTransaction tx = runtimeMock.openUserTx(certificate)) {
|
||||
try (StrolchTransaction tx = runtimeMock.openUserTx(certificate);
|
||||
Report report = new Report(tx, "stockReport")) {
|
||||
|
||||
Report report = new Report(tx, "stockReport");
|
||||
MapOfSets<String, StrolchRootElement> filterCriteria = report.filter("Product", "product01")
|
||||
.generateFilterCriteria();
|
||||
|
||||
|
@ -264,13 +274,13 @@ public class GenericReportTest {
|
|||
@Test
|
||||
public void shouldCreateFilterCriteriaFiltered2() {
|
||||
|
||||
try (StrolchTransaction tx = runtimeMock.openUserTx(certificate)) {
|
||||
try (StrolchTransaction tx = runtimeMock.openUserTx(certificate);
|
||||
Report report = new Report(tx, "stockReport")) {
|
||||
|
||||
Date from = new Date(LocalDate.of(2017, 3, 1).toEpochDay() * 86400000);
|
||||
Date to = new Date(LocalDate.of(2017, 3, 5).toEpochDay() * 86400000);
|
||||
DateRange dateRange = new DateRange().from(from, true).to(to, false);
|
||||
|
||||
Report report = new Report(tx, "stockReport");
|
||||
MapOfSets<String, StrolchRootElement> filterCriteria = report //
|
||||
.dateRange(dateRange) //
|
||||
.filter("Product", "product01") //
|
||||
|
|
Loading…
Reference in New Issue