SuperX-Kernmodul
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

278 lines
13 KiB

package de.superx.bianalysis.rest;
import java.io.ByteArrayOutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Base64;
import java.util.Date;
import org.apache.log4j.Logger;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import de.superx.bianalysis.ExcelSheetBuilder;
import de.superx.bianalysis.ReportDefinition;
import de.superx.bianalysis.StoredReport;
import de.superx.bianalysis.metadata.Identifier;
import de.superx.bianalysis.models.Dimension;
import de.superx.bianalysis.models.DimensionAttribute;
import de.superx.bianalysis.models.FactTable;
import de.superx.bianalysis.models.Measure;
import de.superx.bianalysis.models.Right;
import de.superx.bianalysis.service.BiAnalysisManager;
import de.superx.bianalysis.service.BiAnalysisRightService;
import de.superx.bianalysis.service.DbMetaAdapter;
import de.superx.common.NotYetImplementedException;
import de.superx.rest.RestControllerBase;
import de.superx.rest.model.Download;
import de.superx.rest.model.Result;
import de.superx.rest.model.ResultType;
import de.superx.rest.model.Row;
@RestController
@RequestMapping("/api/reportwizard")
public class BiAnalysisApi extends RestControllerBase {
/* Autor: Robin Wübbeling
* Achtung: Code ist schnell und unschön zusammengestellt, für einen ersten Entwurf
* TODO: Filter
* TODO: Berechnete Kennzahlen
* TODO: Kennzahlenfilter momentan nur über 1 Dimensionsattribut möglich
* TODO: Strings schöner durch "Platzhalter"
* */
static Logger logger = Logger.getLogger(BiAnalysisApi.class);
@Autowired
DbMetaAdapter dbAdapter;
@Autowired
BiAnalysisRightService rightsService;
@Autowired
BiAnalysisManager biAnalysisManager;
@Override
protected Logger getLogger() {
return logger;
}
@RequestMapping(method = RequestMethod.GET, path = "/facttables")
public List<FactTable> listFactTables() throws NotYetImplementedException {
List<Integer> sachgebiete = rightsService.getSachgebiete(Right.CREATE_ANALYSIS, Right.VIEW_REPORT);
List<Identifier> factTables = rightsService.getFactTables(Right.CREATE_ANALYSIS, Right.VIEW_REPORT);
List<FactTable> facts = dbAdapter.getFactTables(sachgebiete, factTables);
return facts;
}
@RequestMapping(method = RequestMethod.GET, path = "/dimensions")
public List<Dimension> listDimensions(@RequestParam(value = "facttable_id") String facttable_id) {
int sachgebietTid = dbAdapter.getSachgebietByFactTableId(facttable_id);
rightsService.checkSachgebiet(sachgebietTid, Right.CREATE_ANALYSIS);
rightsService.checkFactTable(new Identifier(facttable_id), Right.CREATE_ANALYSIS);
return dbAdapter.getDimensionsWithoutHidden(new Identifier(facttable_id));
}
// TODO: zeig in benamung does es sich vllt. um eine reduzierte liste handelt
// granted vs allowed
// umstellen auf camel case
@RequestMapping(method = RequestMethod.GET, path = "/dimensionAttributeValues")
public List<String> listAttributeValues (@RequestParam(value = "attribute_id") List<Identifier> attribute_id, @RequestParam(value = "facts") List<Identifier> facts) {
List<Integer> tids = rightsService.getSachgebiete(Right.CREATE_ANALYSIS);
List<Identifier> factTables = rightsService.getFactTables(Right.CREATE_ANALYSIS);
List<DimensionAttribute> attributes = dbAdapter.getAllowedDimensionAttributes(attribute_id, tids, factTables);
return dbAdapter.getDimensionAttributeValues(attributes, facts);
}
@RequestMapping(method = RequestMethod.GET, path = "/dimensionAttributeValuesHierarchy")
public List<List<Object>> listAttributeValuesHierarchy(@RequestParam(value = "attribute_id") String attribute_id) {
rightsService.checkCreateRights();
return dbAdapter.getDimensionAttributeValuesHierarchy(new Identifier(attribute_id));
}
@RequestMapping(method = RequestMethod.GET, path = "/measures")
public List<Measure> listMeasures(@RequestParam(value = "facttable_id") String facttable_id) {
rightsService.checkSachgebiet(dbAdapter.getSachgebietByFactTableId(facttable_id), Right.CREATE_ANALYSIS, Right.VIEW_REPORT);
rightsService.checkFactTable(new Identifier(facttable_id), Right.CREATE_ANALYSIS, Right.VIEW_REPORT);
return dbAdapter.getMeasures(new Identifier(facttable_id));
}
@RequestMapping(method = RequestMethod.GET, path = "/findReportDefinition")
public List<StoredReport> findReportDefinition(
@RequestParam(value = "title") Optional<String> title,
@RequestParam(value = "sach") Optional<Integer> sach,
@RequestParam(value = "facts") Optional<List<String>> facts) {
List<Integer> allowedSachgebiete = rightsService.getSachgebiete(Right.CREATE_ANALYSIS, Right.VIEW_REPORT);
List<Identifier> allowedFacts = rightsService.getFactTables(Right.CREATE_ANALYSIS, Right.VIEW_REPORT);
List<StoredReport> result = new ArrayList<>();
for (StoredReport report : dbAdapter.findAllStoredReports()) {
List<Integer> sachgebieteOfReport = dbAdapter.getSachgebieteForReport(report.reportDefinition);
if (!allowedSachgebiete.isEmpty() && !allowedSachgebiete.containsAll(sachgebieteOfReport)) {
continue;
}
if (title.isPresent()) {
if (!report.name.toLowerCase().contains(title.get().toLowerCase())) {
continue;
}
}
if (sach.isPresent()) {
if (!sachgebieteOfReport.contains(sach.get())) {
continue;
}
}
if(allowedFacts != null && allowedFacts.size() > 0) {
boolean isFactAllowed = true;
for (Identifier reportFactId : report.reportDefinition.factTableIds) {
if(!allowedFacts.isEmpty() && !allowedFacts.contains(reportFactId)) {
isFactAllowed = false;
}
}
if (!isFactAllowed) {
continue;
}
}
if (facts.isPresent()) {
boolean isFactMissing = false;
for (Identifier reportFactId : report.reportDefinition.factTableIds) {
if (!facts.get().contains(reportFactId.composedId)) {
isFactMissing = true;
break;
}
}
if (isFactMissing) {
continue;
}
}
result.add(report);
}
return result;
}
@RequestMapping(method = RequestMethod.GET, path = "/getStoredReport")
public StoredReport getStoredReport(@RequestParam(value = "id") int id) {
Optional<StoredReport> storedReportOpt = dbAdapter.findById(id);
if(storedReportOpt.isPresent()) {
StoredReport storedReport = storedReportOpt.get();
checkCreateOrViewRightForFactTables(storedReport.reportDefinition.factTableIds);
try {
storedReport.exportedResult = biAnalysisManager.createResult(storedReport.reportDefinition, dbAdapter);
} catch (Exception e) {
logger.error("Couldn't create report", e);
e.printStackTrace();
}
storedReport.isReadOnly = Boolean.valueOf(!this.rightsService.isCreateRight());
return storedReport;
}
return null;
}
@RequestMapping(method = RequestMethod.POST, path = "/report")
public Result getReport(@RequestBody final ReportDefinition reportDefinition) throws Exception {
List<Identifier> factTableIds = reportDefinition.factTableIds;
checkCreateRightForFactTables(factTableIds);
return biAnalysisManager.createResult(reportDefinition, dbAdapter);
}
@RequestMapping(method = RequestMethod.POST, path = "/persistReportDefinition")
public int persistReportDefinition(@RequestBody final StoredReport storedReport) throws Exception {
StoredReport.setReportDefinitionJson(storedReport);
List<Identifier> factTableIds = storedReport.reportDefinition.factTableIds;
checkCreateRightForFactTables(factTableIds);
return dbAdapter.saveReportDefinition(storedReport);
}
@RequestMapping(value = "/report/download", method = RequestMethod.POST)
public Download getFile(@RequestBody final StoredReport storedReport) throws Exception {
checkCreateOrViewRightForFactTables(storedReport.reportDefinition.factTableIds);
Date date = new Date();
String fileName = "BI-Analyse_";
if(storedReport.id != 0) {
fileName += dbAdapter.findById(storedReport.id).get().name + "_";
if(fileName.length() > 206) {
fileName = fileName.substring(0, 160);
}
fileName = fileName.replaceAll("[^a-zA-Z0-9äöüÄÖÜß_]+", "_");
}
fileName += new SimpleDateFormat("yyyyMMdd_HHmmss").format(date);
if(!storedReport.exportedResult.resultType.equals(ResultType.FlatTable)) {
Row totalRow = storedReport.exportedResult.getTotalRow();
storedReport.exportedResult.rows = (BiAnalysisManager.hierarchyToRows(storedReport.hierarchy));
storedReport.exportedResult.rows.add(totalRow);
}
XSSFWorkbook workbook = new ExcelSheetBuilder(storedReport.exportedResult)
.withFileName(fileName)
.withReportName(storedReport.name)
.withDescription(storedReport.description)
.withDate(date)
.build();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
workbook.write(bos);
String base64String = Base64.getEncoder().encodeToString(bos.toByteArray());
String contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
return new Download(fileName, contentType, base64String);
}
@RequestMapping(method = RequestMethod.POST, path = "/deleteReportDefinition")
public boolean deleteReportDefinition(@RequestBody final int id) throws Exception {
try {
Optional<StoredReport> reportOpt = dbAdapter.findById(id);
if(reportOpt.isEmpty()) {
throw new Exception("FEHLER: Berichtskonfiguration konnte nicht gefunden werden.");
}
checkCreateRightForFactTables(reportOpt.get().reportDefinition.factTableIds);
rightsService.checkDeleteRights();
dbAdapter.deleteById(id);
return true;
} catch(Exception e) {
throw new Exception("FEHLER: Berichtskonfiguration konnte nicht gelöscht werden.", e);
}
}
@RequestMapping(method = RequestMethod.GET, path = "/reportDefinitions")
public List<StoredReport> listReportDefinitions() throws Exception {
rightsService.checkCreateOrViewRights();
List<StoredReport> storedReports = null;
try {
storedReports = dbAdapter.findAllStoredReports();
// TODO mit Marnie abklären, für überschreiben notwendig?
} catch (Exception e) {
e.printStackTrace();
if (e.getCause().getMessage().contains("FEHLER: Relation »metadata.rw_report_definitions« existiert nicht")) {
throw new NotYetImplementedException("Bitte installieren Sie zuerst die Komponente 'BI-Analyse-Daten' und führen Sie anschließend den Konnektor aus.");
}
throw e;
}
return storedReports;
}
private void checkCreateOrViewRightForFactTables(List<Identifier> factTableIds) {
for (Identifier factId : factTableIds) {
int sachgebiet = dbAdapter.getSachgebietByFactTableId(factId.composedId);
rightsService.checkSachgebiet(sachgebiet, Right.CREATE_ANALYSIS, Right.VIEW_REPORT);
rightsService.checkFactTable(factId, Right.CREATE_ANALYSIS, Right.VIEW_REPORT);
}
}
private void checkCreateRightForFactTables(List<Identifier> factTableIds) {
for (Identifier factId : factTableIds) {
int sachgebiet = dbAdapter.getSachgebietByFactTableId(factId.composedId);
rightsService.checkSachgebiet(sachgebiet, Right.CREATE_ANALYSIS);
rightsService.checkFactTable(factId, Right.CREATE_ANALYSIS);
}
}
}