/*
|
* Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
|
* Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
|
*/
|
package com.megatim.reporting.adhoc.process;
|
|
import com.megatim.dynamic.reports.pojo.LargestWidth;
|
import com.megatim.reporting.adhoc.pojo.Constantes;
|
import com.megatim.reporting.adhoc.pojo.components.Component;
|
import com.megatim.reporting.adhoc.pojo.CustomField;
|
import com.megatim.reporting.adhoc.pojo.ProcessorElements;
|
import com.megatim.reporting.adhoc.pojo.components.Label;
|
import com.megatim.reporting.adhoc.pojo.components.TextComponent;
|
import com.megatim.reporting.adhoc.pojo.components.TextField;
|
import com.megatim.reporting.adhoc.pojo.components.ValueElement;
|
import com.megatim.reporting.adhoc.pojo.enums.ElementType;
|
import com.megatim.reporting.adhoc.pojo.enums.Position;
|
import com.megatim.reporting.adhoc.pojo.enums.Section;
|
import com.megatim.reporting.adhoc.pojo.enums.ValueElementType;
|
import com.megatim.reporting.adhoc.pojo.ElementToDisplay;
|
import com.megatim.reporting.adhoc.pojo.MainReportDefinition;
|
import com.megatim.reporting.adhoc.pojo.ReportDefinition;
|
import com.megatim.reporting.adhoc.pojo.SubReportDefinition;
|
import com.megatim.reporting.adhoc.pojo.layouts.MainReport;
|
import com.megatim.reporting.adhoc.pojo.layouts.Report;
|
import com.megatim.reporting.adhoc.pojo.layouts.SubReport;
|
import com.megatim.reporting.adhoc.pojo.layouts.Title;
|
import java.nio.file.Paths;
|
import java.time.LocalDateTime;
|
import java.time.format.DateTimeFormatter;
|
import java.util.ArrayList;
|
import java.util.Collections;
|
import java.util.List;
|
import java.util.Optional;
|
import java.util.stream.Collectors;
|
import net.sf.jasperreports.engine.JRException;
|
import net.sf.jasperreports.engine.JasperCompileManager;
|
|
/**
|
*
|
* @author ASUS
|
*/
|
public class SecondProcessor {
|
|
/**
|
* Point de de début des traitements en vue de générer le .jrxml et le
|
* .jasper
|
*
|
* @param elements
|
* @return : retourne le chemin absolu du fichier .jasper
|
* @throws Exception
|
*/
|
public String generateJasperFile(ProcessorElements elements) throws Exception {
|
//Parcours du template .xml afin d'extraire certaines propriétés de l'état
|
Report report = (new ParseXMLTemplate()).parse(elements.getTemplateFile());
|
|
//Ajout des éléments provenant de l'interface
|
addReportElements(report, elements.getReportDefinition());
|
|
(new GenerateJRXML()).generateJrxml(report, elements.getJrxmlFolder());
|
|
//Compilation des sous-rapports
|
for (SubReport sub : report.getSubReports()) {
|
compileJrxmlToJasper(Paths.get(elements.getJrxmlFolder(), sub.getName() + ".jrxml").toString(),
|
Paths.get(elements.getJasperFolder(), sub.getName() + ".jasper").toString());
|
}
|
|
//Compilation du rapport parent
|
compileJrxmlToJasper(Paths.get(elements.getJrxmlFolder(), report.getName() + ".jrxml").toString(),
|
Paths.get(elements.getJasperFolder(), report.getName() + ".jasper").toString());
|
|
return Paths.get(elements.getJasperFolder(), report.getName() + ".jasper").toString();
|
}
|
|
/**
|
* Méthode qui compile le .jrxml en . jasper
|
*
|
* @param jrxmlPath
|
* @param jasperPath
|
* @throws JRException
|
*/
|
private void compileJrxmlToJasper(String jrxmlPath, String jasperPath) throws JRException {
|
|
JasperCompileManager.compileReportToFile(jrxmlPath, jasperPath);
|
}
|
|
/**
|
* Méthode qui ajoute les éléments provenant de la vue
|
*
|
* @param report
|
* @param reportDefinition
|
*/
|
private void addReportElements(MainReport report, MainReportDefinition reportDefinition) {
|
report.setDetail(reportDefinition.isDetail());
|
|
//Ajout des colonnes de données et leurs entêtes
|
addColumnsHeaderAndColumnsData(report, reportDefinition);
|
|
//Ajout des labels de l'entête
|
addElementsToDisplayToHeader(report, reportDefinition.getElementsToDisplay());
|
|
if (reportDefinition.getReportName() != null && !reportDefinition.getReportName().isEmpty()) {
|
report.setName(reportDefinition.getReportName());
|
}
|
|
for (CustomField f : reportDefinition.getCustomFields()) {
|
ValueElement valueElt = new ValueElement(f.getName(), f.getClasse(), ValueElementType.FIELD);
|
report.getFields().putIfAbsent(valueElt.getName(), valueElt);
|
}
|
|
//Ajout des sous-états
|
if ((report instanceof Report) && (reportDefinition instanceof ReportDefinition)) {
|
Report rep = (Report) report;
|
ReportDefinition repDef = (ReportDefinition) reportDefinition;
|
|
if (!repDef.getSubReportDefs().isEmpty() && !rep.getSubReports().isEmpty()) {
|
addSubReportsElelements(rep, repDef.getSubReportDefs());
|
|
} else {
|
//Retirer la description de subReport provenant du xml, afin de ne pas l'afficher car il n'ya pas de sous-rapport
|
//provenant de l'interface
|
rep.getSubReports().clear();
|
}
|
}
|
|
}
|
|
/**
|
* .
|
* @param report
|
* @param reportDefinition
|
*/
|
private void addColumnsHeaderAndColumnsData(MainReport report, MainReportDefinition reportDefinition) {
|
//Filter afin de ne garder que les champs qui sont des nombres, chaines de caractères, date ou booleen
|
List<CustomField> fields = reportDefinition.getCustomFields().stream()
|
.filter(f -> String.class.isAssignableFrom(f.getClasse())
|
|| Number.class.isAssignableFrom(f.getClasse())
|
|| Boolean.class.isAssignableFrom(f.getClasse())
|
|| java.util.Date.class.isAssignableFrom(f.getClasse())
|
|| java.time.temporal.Temporal.class.isAssignableFrom(f.getClasse())
|
).collect(Collectors.toList());
|
|
Collections.sort(fields, (CustomField f1, CustomField f2) -> Integer.valueOf(f1.getRang()).compareTo(f2.getRang()));
|
|
if (report.isDetail()) {
|
addDetailColumnsHeaderAndColumnsData(report, fields);
|
|
} else {
|
addListeColumnsHeaderAndColumnsData(report, reportDefinition.isHaveLineNumber(), fields);
|
}
|
|
}
|
|
private void addListeColumnsHeaderAndColumnsData(MainReport report, boolean isHaveLineNumber, List<CustomField> fields) {
|
int x = 0;
|
int i = 1;
|
|
String columnDataStyle = report.getColumnData().getColumnStyle();
|
String columnHeaderStyle = report.getColumnHeader().getColumnStyle();
|
|
if (isHaveLineNumber) {
|
x = 38;
|
|
TextField textField = new TextField();
|
textField.setLineNumber(true);
|
|
Label label = new Label();
|
label.setValue("N°");
|
|
setTextComponentStyle(textField, columnDataStyle);
|
setTextComponentStyle(label, columnHeaderStyle);
|
|
textField.setX(0);
|
label.setX(0);
|
|
textField.setWidth(x);
|
label.setWidth(x);
|
|
report.getColumnData().getComponents().add(textField);
|
report.getColumnHeader().getComponents().add(label);
|
|
}
|
int totalWidth = report.getPageWidth() - report.getRightMargin() - report.getLeftMargin() - x - 10;
|
int nbFieldsWithoutWidth = fields.size();
|
|
for (CustomField f : fields) {
|
if (f.getWidth() > 0) {
|
totalWidth -= f.getWidth();
|
nbFieldsWithoutWidth--;
|
}
|
}
|
|
for (CustomField f : fields) {
|
int width = f.getWidth() > 0 ? f.getWidth() : totalWidth / nbFieldsWithoutWidth;
|
f.setWidth(width);
|
|
TextField textField = new TextField();
|
Label label = new Label();
|
|
setTextComponentStyle(textField, columnDataStyle);
|
setTextComponentStyle(label, columnHeaderStyle);
|
|
ValueElement valueElement = new ValueElement(f.getName(), f.getClasse(), ValueElementType.FIELD);
|
|
textField.setValueElement(valueElement);
|
label.setValue(f.getLibelle());
|
|
textField.setX(x);
|
label.setX(x);
|
|
textField.setWidth(f.getWidth());
|
label.setWidth(f.getWidth());
|
|
textField.setPattern(f.getPattern());
|
|
report.getColumnData().getComponents().add(textField);
|
report.getColumnHeader().getComponents().add(label);
|
|
x = x + f.getWidth();
|
|
i++;
|
}
|
|
}
|
|
private void addDetailColumnsHeaderAndColumnsData(MainReport report, List<CustomField> fields) {
|
final int xColumnHeader = 10;
|
|
String columnDataStyle = report.getColumnData().getColumnStyle();
|
String columnHeaderStyle = report.getColumnHeader().getColumnStyle();
|
|
int totalWidth = report.getPageWidth() - report.getRightMargin() - report.getLeftMargin() - xColumnHeader - 20;
|
|
//Recherche du champ ayant le libellé le plus long
|
Optional<CustomField> optionalCustomField = fields.stream().max((c1, c2) -> Integer.valueOf(c1.getLibelle().length()).compareTo(c2.getLibelle().length()));
|
final int columnHeaderLength = (optionalCustomField.isPresent() ? optionalCustomField.get().getLibelle().length() : 0) * 7;
|
final int columnDataLength = totalWidth - columnHeaderLength;
|
|
final int xColumnData = xColumnHeader + columnHeaderLength;
|
|
int y = 10;
|
int columnDataHeight = y;
|
|
for (CustomField f : fields) {
|
|
TextField textField = new TextField();
|
Label label = new Label();
|
|
setTextComponentStyle(textField, columnDataStyle);
|
setTextComponentStyle(label, columnHeaderStyle);
|
|
ValueElement valueElement = new ValueElement(f.getName(), f.getClasse(), ValueElementType.FIELD);
|
|
textField.setValueElement(valueElement);
|
label.setValue(f.getLibelle());
|
|
label.setX(xColumnHeader);
|
textField.setX(xColumnData);
|
textField.setY(y);
|
label.setY(y);
|
|
textField.setWidth(columnDataLength);
|
label.setWidth(columnHeaderLength);
|
|
textField.setPattern(f.getPattern());
|
|
columnDataHeight += textField.getHeight();
|
y += textField.getHeight();
|
|
report.getColumnData().getComponents().add(textField);
|
report.getColumnHeader().getComponents().add(label);
|
|
}
|
|
report.getColumnData().setHeight(columnDataHeight);
|
report.getColumnHeader().setHeight(columnDataHeight);
|
}
|
|
/**
|
* Méthode qui applique la mise en forme sur les composants
|
*
|
* @param component
|
* @param attributeValue
|
*/
|
private void setTextComponentStyle(TextComponent component, String attributeValue) {
|
|
if (attributeValue != null && !attributeValue.isEmpty()) {
|
|
ParseXMLTemplate.getComponentAttributes(attributeValue, component);
|
ParseXMLTemplate.getTextComponentAttributes(attributeValue, component);
|
}
|
|
}
|
|
private void addSubReportsElelements(Report report, List<SubReportDefinition> subReportDefs) {
|
List<SubReport> subReports = new ArrayList<>();
|
|
for (SubReportDefinition subReportDef : subReportDefs) {
|
SubReport subReport = report.getSubReports().get(0);
|
String pageTitleStyle = subReport.getPageTitleStyle();
|
|
Label label = new Label();
|
label.setValue(subReportDef.getTitle());
|
|
ParseXMLTemplate.getComponentAttributes(pageTitleStyle, label);
|
ParseXMLTemplate.getTextComponentAttributes(pageTitleStyle, label);
|
|
subReport.getPageHeader().getComponents().add(label);
|
subReport.setDataSource(subReportDef.getDataSource());
|
|
addReportElements(subReport, subReportDef);
|
|
subReports.add(subReport);
|
|
}
|
report.getSubReports().clear();
|
report.getSubReports().addAll(subReports);
|
}
|
|
private void addElementsToDisplayToHeader(MainReport report, List<ElementToDisplay> elementsToDisplay) {
|
List<ElementToDisplay> liste = elementsToDisplay.stream().filter(e -> e.getSection().equals(Section.TITLE))
|
.collect(Collectors.toList());
|
|
if (!liste.isEmpty()) {
|
|
if (report.getTitle() == null) {
|
report.setTitle(new Title());
|
}
|
List<Component> components = new ArrayList<>();
|
int y = 0;
|
|
for (Component c : report.getTitle().getComponents()) {
|
if (c != null) {
|
y += c.getY();
|
}
|
}
|
//Ajouter un espace avant les labels à ajouter
|
y += y > 0 ? 50 : 10;
|
|
LargestWidth largestWidth = getLargestWidth(elementsToDisplay);
|
|
int yLeft = y;
|
int yRight = y;
|
|
for (ElementToDisplay e : elementsToDisplay) {
|
int xLeft = 0;
|
int xRight = 0;
|
|
if (report.isDetail()) {
|
Component columnData = !report.getColumnData().getComponents().isEmpty() ? report.getColumnData().getComponents().get(0) : null;
|
|
xRight = report.getRightMargin() + report.getLeftMargin() + (columnData != null ? columnData.getWidth() + columnData.getX() : 0) + 10;
|
} else {
|
xRight = report.getRightMargin() + report.getLeftMargin() + report.getColumnData().getComponents().stream().mapToInt(c -> c.getWidth()).sum() + 10;
|
}
|
|
Label keyLabel = new Label();
|
Component labelValue = new Component();
|
Label deuxPointsLabel = new Label();
|
|
keyLabel.setValue(e.getLibelle());
|
deuxPointsLabel.setValue(":");
|
|
switch (e.getElementType()) {
|
|
case PARAMETRE:
|
ValueElement valueElt = new ValueElement(e.getValue(), java.lang.String.class, ValueElementType.PARAMETER);
|
try {
|
report.getParameters().put(e.getValue(), valueElt);
|
} catch (Exception ex) {
|
}
|
TextField textField = new TextField();
|
textField.setValueElement(valueElt);
|
textField.setSize(10);
|
labelValue = textField;
|
break;
|
|
case DATE_GENERE:
|
valueElt = new ValueElement(e.getValue(), java.util.Date.class, ValueElementType.GENERATE);
|
textField = new TextField();
|
textField.setValueElement(valueElt);
|
textField.setSize(10);
|
textField.setPattern("dd/MM/yyyy HH:mm:ss");
|
labelValue = textField;
|
break;
|
|
default:
|
Label label = new Label();
|
label.setValue(e.getValue());
|
label.setSize(10);
|
labelValue = label;
|
break;
|
}
|
|
keyLabel.setSize(10);
|
deuxPointsLabel.setSize(10);
|
|
keyLabel.setHeight(Constantes.LABEL_HEIGHT);
|
labelValue.setHeight(Constantes.LABEL_HEIGHT);
|
deuxPointsLabel.setHeight(Constantes.LABEL_HEIGHT);
|
|
deuxPointsLabel.setWidth(Constantes.DEUX_POINTS_WIDTH);
|
|
keyLabel.setvAlign(Constantes.V_ALIGN_MIDDLE);
|
labelValue.setvAlign(Constantes.V_ALIGN_MIDDLE);
|
deuxPointsLabel.setvAlign(Constantes.V_ALIGN_MIDDLE);
|
|
keyLabel.setBold(true);
|
deuxPointsLabel.setBold(true);
|
|
keyLabel.sethAlign(Constantes.H_ALIGN_LEFT);
|
labelValue.sethAlign(Constantes.H_ALIGN_LEFT);
|
deuxPointsLabel.sethAlign(Constantes.H_ALIGN_CENTER);
|
|
if (e.getPosition() == null) {
|
e.setPosition(Position.LEFT);
|
}
|
|
switch (e.getPosition()) {
|
|
case LEFT:
|
keyLabel.setY(yLeft);
|
labelValue.setY(yLeft);
|
deuxPointsLabel.setY(yLeft);
|
|
keyLabel.setX(xLeft);
|
deuxPointsLabel.setX(xLeft + largestWidth.getLeftLargestKey());
|
labelValue.setX(xLeft + largestWidth.getLeftLargestKey() + 2 * Constantes.DEUX_POINTS_WIDTH);
|
|
keyLabel.setWidth(largestWidth.getLeftLargestKey());
|
labelValue.setWidth(largestWidth.getLeftLargestValue());
|
|
keyLabel.setX(0);
|
|
yLeft += Constantes.LABEL_HEIGHT;
|
|
break;
|
|
case RIGHT:
|
keyLabel.setY(yRight);
|
labelValue.setY(yRight);
|
deuxPointsLabel.setY(yRight);
|
|
labelValue.setX(xRight - largestWidth.getRightLargestValue() - Constantes.DEUX_POINTS_WIDTH);
|
deuxPointsLabel.setX(xRight - largestWidth.getRightLargestValue() - Constantes.DEUX_POINTS_WIDTH * 3);
|
keyLabel.setX(xRight - largestWidth.getRightLargestValue() - Constantes.DEUX_POINTS_WIDTH * 3 - largestWidth.getRightLargestKey());
|
|
keyLabel.setWidth(largestWidth.getRightLargestKey());
|
labelValue.setWidth(largestWidth.getRightLargestValue());
|
|
yRight += Constantes.LABEL_HEIGHT;
|
|
break;
|
}
|
components.add(keyLabel);
|
components.add(labelValue);
|
components.add(deuxPointsLabel);
|
|
}
|
y = yLeft > yRight ? yLeft : yRight;
|
|
report.getTitle().getComponents().addAll(components);
|
report.getTitle().setHeight(y);
|
}
|
}
|
|
private LargestWidth getLargestWidth(List<ElementToDisplay> elementsToDisplay) {
|
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss");
|
Integer leftLargestKey = 0;
|
Integer leftLargestValue = 0;
|
Integer rightLargestKey = 0;
|
Integer rightLargestValue = 0;
|
|
for (ElementToDisplay e : elementsToDisplay) {
|
//Fixer des valeurs qui permettront de calculer la longueur de chaque label
|
if (e.getElementType().equals(ElementType.DATE_GENERE)) {
|
e.setValue(dtf.format(LocalDateTime.now()));
|
}
|
|
if (e.getPosition() != null) {
|
|
if (e.getPosition().equals(Position.RIGHT)) {
|
rightLargestValue = e.getValue() != null && e.getValue().length() > rightLargestValue ? e.getValue().length() : rightLargestValue;
|
rightLargestKey = e.getLibelle() != null && e.getLibelle().length() > rightLargestKey ? e.getLibelle().length() : rightLargestKey;
|
|
} else if (e.getPosition().equals(Position.LEFT)) {
|
leftLargestValue = e.getValue() != null && e.getValue().length() > leftLargestValue ? e.getValue().length() : leftLargestValue;
|
leftLargestKey = e.getLibelle() != null && e.getLibelle().length() > leftLargestKey ? e.getLibelle().length() : leftLargestKey;
|
}
|
}
|
|
}
|
|
leftLargestKey = leftLargestKey * 6;
|
leftLargestValue = leftLargestValue * 6;
|
rightLargestValue = rightLargestValue * 6;
|
rightLargestKey = rightLargestKey * 6;
|
|
return new LargestWidth(leftLargestKey, leftLargestValue, rightLargestKey, rightLargestValue);
|
}
|
}
|