first commit

This commit is contained in:
2025-07-28 13:56:49 +05:30
commit e9eb805edb
3438 changed files with 520990 additions and 0 deletions

View File

@@ -0,0 +1,434 @@
package net.sf.jasperreports.engine.fill;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import net.sf.jasperreports.engine.JRConditionalStyle;
import net.sf.jasperreports.engine.JRElement;
import net.sf.jasperreports.engine.JRElementGroup;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRFrame;
import net.sf.jasperreports.engine.JROrigin;
import net.sf.jasperreports.engine.JRPrintElement;
import net.sf.jasperreports.engine.JRPrintElementContainer;
import net.sf.jasperreports.engine.JRReportFont;
import net.sf.jasperreports.engine.JRStyle;
import net.sf.jasperreports.engine.base.JRBaseStyle;
import net.sf.jasperreports.engine.util.JRStyleResolver;
public abstract class JRFillElementContainer extends JRFillElementGroup {
protected JRBaseFiller filler;
private JRFillElement[] ySortedElements = null;
private JRFillElement[] stretchElements = null;
private JRFillElement[] bandBottomElements = null;
private JRFillElement[] removableElements = null;
private boolean willOverflow = false;
protected boolean isOverflow = false;
private int stretchHeight = 0;
private int firstY = 0;
protected JRFillElement firstYElement = null;
protected final JRFillExpressionEvaluator expressionEvaluator;
protected JRFillElement[] deepElements;
protected Set stylesToEvaluate = new HashSet();
protected Map evaluatedStyles = new HashMap();
protected boolean hasPrintWhenOverflowElement;
protected JRFillElementContainer(JRBaseFiller filler, JRElementGroup container, JRFillObjectFactory factory) {
super(container, factory);
this.expressionEvaluator = factory.getExpressionEvaluator();
initDeepElements();
this.filler = filler;
}
protected JRFillElementContainer(JRFillElementContainer container, JRFillCloneFactory factory) {
super(container, factory);
this.expressionEvaluator = container.expressionEvaluator;
initDeepElements();
this.filler = container.filler;
}
private void initDeepElements() {
if (this.elements == null) {
this.deepElements = new JRFillElement[0];
} else {
List deepElementsList = new ArrayList(this.elements.length);
collectDeepElements((JRElement[])this.elements, deepElementsList);
this.deepElements = new JRFillElement[deepElementsList.size()];
deepElementsList.toArray((Object[])this.deepElements);
}
}
private static void collectDeepElements(JRElement[] elements, List deepElementsList) {
for (int i = 0; i < elements.length; i++) {
JRElement element = elements[i];
deepElementsList.add(element);
if (element instanceof JRFillFrame) {
JRFrame frame = (JRFrame)element;
collectDeepElements(frame.getElements(), deepElementsList);
}
}
}
protected final void initElements() {
this.hasPrintWhenOverflowElement = false;
if (this.elements != null && this.elements.length > 0) {
List sortedElemsList = new ArrayList();
List stretchElemsList = new ArrayList();
List bandBottomElemsList = new ArrayList();
List removableElemsList = new ArrayList();
for (int i = 0; i < this.elements.length; i++) {
JRFillElement element = this.elements[i];
sortedElemsList.add(element);
if (element.getPositionType() == 3)
bandBottomElemsList.add(element);
if (element.getStretchType() != 0)
stretchElemsList.add(element);
if (element.isRemoveLineWhenBlank())
removableElemsList.add(element);
if (element.isPrintWhenDetailOverflows())
this.hasPrintWhenOverflowElement = true;
}
Collections.sort(sortedElemsList, new JRYComparator());
this.ySortedElements = new JRFillElement[this.elements.length];
sortedElemsList.toArray(this.ySortedElements);
this.stretchElements = new JRFillElement[stretchElemsList.size()];
stretchElemsList.toArray(this.stretchElements);
this.bandBottomElements = new JRFillElement[bandBottomElemsList.size()];
bandBottomElemsList.toArray(this.bandBottomElements);
this.removableElements = new JRFillElement[removableElemsList.size()];
removableElemsList.toArray(this.removableElements);
}
setDependentElements();
setElementsBandBottomY();
}
protected final void setElementsBandBottomY() {
if (this.elements != null && this.elements.length > 0)
for (int i = 0; i < this.elements.length; i++)
this.elements[i].setBandBottomY(getContainerHeight() - this.elements[i].getY() - this.elements[i].getHeight());
}
private void setDependentElements() {
if (this.ySortedElements != null && this.ySortedElements.length > 0)
for (int i = 0; i < this.ySortedElements.length - 1; i++) {
JRFillElement iElem = this.ySortedElements[i];
boolean isBreakElem = iElem instanceof JRFillBreak;
for (int j = i + 1; j < this.ySortedElements.length; j++) {
JRFillElement jElem = this.ySortedElements[j];
int left = Math.min(iElem.getX(), jElem.getX());
int right = Math.max(iElem.getX() + iElem.getWidth(), jElem.getX() + jElem.getWidth());
if (((isBreakElem && jElem.getPositionType() == 2) || jElem.getPositionType() == 1) && iElem.getY() + iElem.getHeight() <= jElem.getY() && iElem.getWidth() + jElem.getWidth() > right - left)
iElem.addDependantElement(jElem);
}
}
}
protected void evaluate(byte evaluation) throws JRException {
JRElement[] allElements = getElements();
if (allElements != null && allElements.length > 0)
for (int i = 0; i < allElements.length; i++) {
JRFillElement element = (JRFillElement)allElements[i];
element.setCurrentEvaluation(evaluation);
element.evaluate(evaluation);
}
}
protected void resetElements() {
if (this.ySortedElements != null && this.ySortedElements.length > 0)
for (int i = 0; i < this.ySortedElements.length; i++) {
JRFillElement element = this.ySortedElements[i];
element.reset();
if (!this.isOverflow)
element.setAlreadyPrinted(false);
}
}
protected boolean willOverflow() {
return this.willOverflow;
}
protected void initFill() {
this.isOverflow = this.willOverflow;
this.firstY = 0;
this.firstYElement = null;
}
protected void prepareElements(int availableStretchHeight, boolean isOverflowAllowed) throws JRException {
boolean tmpWillOverflow = false;
int maxBandStretch = 0;
int bandStretch = 0;
this.firstY = this.isOverflow ? getContainerHeight() : 0;
this.firstYElement = null;
boolean isFirstYFound = false;
if (this.ySortedElements != null && this.ySortedElements.length > 0)
for (int i = 0; i < this.ySortedElements.length; i++) {
JRFillElement element = this.ySortedElements[i];
tmpWillOverflow = (element.prepare(availableStretchHeight + getElementFirstY(element), this.isOverflow) || tmpWillOverflow);
element.moveDependantElements();
if (element.isToPrint()) {
if (this.isOverflow) {
if (element.isReprinted()) {
this.firstY = 0;
} else if (!isFirstYFound) {
this.firstY = element.getY();
}
isFirstYFound = true;
}
this.firstYElement = element;
bandStretch = element.getRelativeY() + element.getStretchHeight() - getContainerHeight() + element.getBandBottomY();
if (bandStretch > maxBandStretch)
maxBandStretch = bandStretch;
}
}
if (maxBandStretch > availableStretchHeight + this.firstY)
tmpWillOverflow = true;
if (tmpWillOverflow) {
this.stretchHeight = getContainerHeight() + availableStretchHeight;
} else {
this.stretchHeight = getContainerHeight() + maxBandStretch;
}
this.willOverflow = (tmpWillOverflow && isOverflowAllowed);
}
private int getElementFirstY(JRFillElement element) {
int elemFirstY;
if (!this.isOverflow || this.hasPrintWhenOverflowElement) {
elemFirstY = 0;
} else if (element.getY() >= this.firstY) {
elemFirstY = this.firstY;
} else {
elemFirstY = element.getY();
}
return elemFirstY;
}
protected void setStretchHeight(int stretchHeight) {
if (stretchHeight > this.stretchHeight)
this.stretchHeight = stretchHeight;
}
protected void stretchElements() {
if (this.stretchElements != null && this.stretchElements.length > 0)
for (int i = 0; i < this.stretchElements.length; i++) {
JRFillElement element = this.stretchElements[i];
element.stretchElement(this.stretchHeight - getContainerHeight());
element.moveDependantElements();
}
if (this.ySortedElements != null && this.ySortedElements.length > 0)
for (int i = 0; i < this.ySortedElements.length; i++) {
JRFillElement element = this.ySortedElements[i];
element.stretchHeightFinal();
}
}
protected int getStretchHeight() {
return this.stretchHeight;
}
protected void moveBandBottomElements() {
if (this.bandBottomElements != null && this.bandBottomElements.length > 0)
for (int i = 0; i < this.bandBottomElements.length; i++) {
JRFillElement element = this.bandBottomElements[i];
element.setRelativeY(element.getY() + this.stretchHeight - getContainerHeight());
element.setToPrint((element.isToPrint() && !this.willOverflow));
}
}
protected void removeBlankElements() {
JRFillElement[] arrayOfJRFillElement = this.removableElements;
if (arrayOfJRFillElement != null && arrayOfJRFillElement.length > 0) {
JRFillElement[] arrayOfJRFillElement1 = this.ySortedElements;
for (int i = 0; i < arrayOfJRFillElement.length; i++) {
int blankHeight;
JRFillElement iElem = arrayOfJRFillElement[i];
if (iElem.isToPrint()) {
blankHeight = iElem.getHeight() - iElem.getStretchHeight();
} else {
blankHeight = iElem.getHeight();
}
if (blankHeight > 0 && iElem.getRelativeY() + iElem.getStretchHeight() <= this.stretchHeight && iElem.getRelativeY() >= this.firstY) {
int blankY = iElem.getRelativeY() + iElem.getHeight() - blankHeight;
boolean isToRemove = true;
int j;
for (j = 0; j < arrayOfJRFillElement1.length; j++) {
JRFillElement jElem = arrayOfJRFillElement1[j];
if (iElem != jElem && jElem.isToPrint()) {
int top = Math.min(blankY, jElem.getRelativeY());
int bottom = Math.max(blankY + blankHeight, jElem.getRelativeY() + jElem.getStretchHeight());
if (blankHeight + jElem.getStretchHeight() > bottom - top) {
isToRemove = false;
break;
}
}
}
if (isToRemove) {
for (j = 0; j < arrayOfJRFillElement1.length; j++) {
JRFillElement jElem = arrayOfJRFillElement1[j];
if (jElem.getRelativeY() >= blankY + blankHeight)
jElem.setRelativeY(jElem.getRelativeY() - blankHeight);
}
this.stretchHeight -= blankHeight;
}
}
}
}
}
protected void fillElements(JRPrintElementContainer printContainer) throws JRException {
JRElement[] allElements = getElements();
if (allElements != null && allElements.length > 0)
for (int i = 0; i < allElements.length; i++) {
JRFillElement element = (JRFillElement)allElements[i];
element.setRelativeY(element.getRelativeY() - this.firstY);
if (element.getRelativeY() + element.getStretchHeight() > this.stretchHeight)
element.setToPrint(false);
element.setAlreadyPrinted((element.isToPrint() || element.isAlreadyPrinted()));
if (element.isToPrint()) {
JRPrintElement printElement = element.fill();
if (printElement != null) {
printContainer.addElement(printElement);
if (element instanceof JRFillSubreport) {
JRFillSubreport subreport = (JRFillSubreport)element;
List fonts = subreport.subreportFiller.getJasperPrint().getFontsList();
for (int j = 0; j < fonts.size(); j++)
this.filler.getJasperPrint().addFont(fonts.get(j), true);
List styles = subreport.subreportFiller.getJasperPrint().getStylesList();
for (int k = 0; k < styles.size(); k++)
this.filler.addPrintStyle(styles.get(k));
List origins = subreport.subreportFiller.getJasperPrint().getOriginsList();
for (int m = 0; m < origins.size(); m++)
this.filler.getJasperPrint().addOrigin(origins.get(m));
Collection printElements = subreport.getPrintElements();
addSubElements(printContainer, element, printElements);
} else if (element instanceof JRFillCrosstab) {
List printElements = ((JRFillCrosstab)element).getPrintElements();
addSubElements(printContainer, element, printElements);
}
}
}
}
printContainer.setHeight(this.stretchHeight - this.firstY);
}
protected void addSubElements(JRPrintElementContainer printContainer, JRFillElement element, Collection printElements) {
if (printElements != null && printElements.size() > 0)
for (Iterator it = printElements.iterator(); it.hasNext(); ) {
JRPrintElement printElement = it.next();
printElement.setX(element.getX() + printElement.getX());
printElement.setY(element.getRelativeY() + printElement.getY());
printContainer.addElement(printElement);
}
}
protected void rewind() throws JRException {
if (this.ySortedElements != null && this.ySortedElements.length > 0)
for (int i = 0; i < this.ySortedElements.length; i++) {
JRFillElement element = this.ySortedElements[i];
element.rewind();
element.setAlreadyPrinted(false);
}
this.willOverflow = false;
}
protected int getFirstY() {
return this.firstY;
}
protected abstract int getContainerHeight();
protected void initConditionalStyles() {
this.filler.addDefaultStyleListener(new JRBaseFiller.DefaultStyleListener() {
private final JRFillElementContainer this$0;
public void defaultStyleSet(JRStyle style) {
JRFillElementContainer.this.collectConditionalStyle(style);
}
});
int i;
for (i = 0; i < this.deepElements.length; i++) {
JRStyle style = (this.deepElements[i]).initStyle;
collectConditionalStyle(style);
}
if (this.deepElements.length > 0)
for (i = 0; i < this.deepElements.length; i++)
this.deepElements[i].setConditionalStylesContainer(this);
}
protected void collectConditionalStyle(JRStyle style) {
if (style != null)
this.stylesToEvaluate.add(style);
}
protected void evaluateConditionalStyles(byte evaluation) throws JRException {
for (Iterator it = this.stylesToEvaluate.iterator(); it.hasNext();)
evaluateConditionalStyle(it.next(), evaluation);
}
protected JRStyle evaluateConditionalStyle(JRStyle initialStyle, byte evaluation) throws JRException {
JRBaseStyle jRBaseStyle;
JRStyle consolidatedStyle = initialStyle;
StringBuffer code = new StringBuffer();
List condStylesToApply = new ArrayList();
boolean anyTrue = buildConsolidatedStyle(initialStyle, evaluation, code, condStylesToApply);
if (anyTrue) {
String consolidatedStyleName = initialStyle.getName() + code.toString();
consolidatedStyle = (JRStyle)this.filler.getJasperPrint().getStylesMap().get(consolidatedStyleName);
if (consolidatedStyle == null) {
jRBaseStyle = new JRBaseStyle(consolidatedStyleName);
for (int j = condStylesToApply.size() - 1; j >= 0; j--)
JRStyleResolver.appendStyle((JRStyle)jRBaseStyle, condStylesToApply.get(j));
this.filler.addPrintStyle((JRStyle)jRBaseStyle);
}
}
this.evaluatedStyles.put(initialStyle, jRBaseStyle);
return (JRStyle)jRBaseStyle;
}
protected boolean buildConsolidatedStyle(JRStyle style, byte evaluation, StringBuffer code, List condStylesToApply) throws JRException {
boolean anyTrue = false;
JRConditionalStyle[] conditionalStyles = style.getConditionalStyles();
if (conditionalStyles != null && conditionalStyles.length > 0)
for (int j = 0; j < conditionalStyles.length; j++) {
boolean condition;
JRConditionalStyle conditionalStyle = conditionalStyles[j];
Boolean expressionValue = (Boolean)this.expressionEvaluator.evaluate(conditionalStyle.getConditionExpression(), evaluation);
if (expressionValue == null) {
condition = false;
} else {
condition = expressionValue.booleanValue();
}
code.append(condition ? 49 : 48);
anyTrue |= condition;
if (condition)
condStylesToApply.add(conditionalStyle);
}
condStylesToApply.add(style);
if (style.getStyle() != null)
anyTrue |= buildConsolidatedStyle(style.getStyle(), evaluation, code, condStylesToApply);
return anyTrue;
}
public JRStyle getEvaluatedConditionalStyle(JRStyle parentStyle) {
return (JRStyle)this.evaluatedStyles.get(parentStyle);
}
}