0001: /*
0002: * ============================================================================
0003: * GNU Lesser General Public License
0004: * ============================================================================
0005: *
0006: * JasperReports - Free Java report-generating library.
0007: * Copyright (C) 2001-2006 JasperSoft Corporation http://www.jaspersoft.com
0008: *
0009: * This library is free software; you can redistribute it and/or
0010: * modify it under the terms of the GNU Lesser General Public
0011: * License as published by the Free Software Foundation; either
0012: * version 2.1 of the License, or (at your option) any later version.
0013: *
0014: * This library is distributed in the hope that it will be useful,
0015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
0016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0017: * Lesser General Public License for more details.
0018: *
0019: * You should have received a copy of the GNU Lesser General Public
0020: * License along with this library; if not, write to the Free Software
0021: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
0022: *
0023: * JasperSoft Corporation
0024: * 303 Second Street, Suite 450 North
0025: * San Francisco, CA 94107
0026: * http://www.jaspersoft.com
0027: */
0028: package net.sf.jasperreports.engine.fill;
0029:
0030: import java.awt.Color;
0031: import java.io.Serializable;
0032: import java.util.ArrayList;
0033: import java.util.Collection;
0034: import java.util.HashMap;
0035: import java.util.HashSet;
0036: import java.util.Iterator;
0037: import java.util.Map;
0038: import java.util.Set;
0039:
0040: import net.sf.jasperreports.engine.JRConstants;
0041: import net.sf.jasperreports.engine.JRDefaultStyleProvider;
0042: import net.sf.jasperreports.engine.JRElement;
0043: import net.sf.jasperreports.engine.JRElementGroup;
0044: import net.sf.jasperreports.engine.JRException;
0045: import net.sf.jasperreports.engine.JRExpression;
0046: import net.sf.jasperreports.engine.JRExpressionChunk;
0047: import net.sf.jasperreports.engine.JRGroup;
0048: import net.sf.jasperreports.engine.JRPrintElement;
0049: import net.sf.jasperreports.engine.JRStyle;
0050: import net.sf.jasperreports.engine.JRStyleSetter;
0051: import net.sf.jasperreports.engine.JRVariable;
0052: import net.sf.jasperreports.engine.util.JRStyleResolver;
0053:
0054: /**
0055: * @author Teodor Danciu (teodord@users.sourceforge.net)
0056: * @version $Id: JRFillElement.java 1765 2007-06-21 15:50:27Z lucianc $
0057: */
0058: public abstract class JRFillElement implements JRElement, JRCloneable,
0059: JRStyleSetter {
0060:
0061: /**
0062: *
0063: */
0064: protected JRElement parent = null;
0065: protected Map templates = new HashMap();
0066:
0067: /**
0068: *
0069: */
0070: protected JRBaseFiller filler = null;
0071: protected JRFillExpressionEvaluator expressionEvaluator = null;
0072:
0073: protected JRDefaultStyleProvider defaultStyleProvider;
0074:
0075: /**
0076: *
0077: */
0078: protected JRGroup printWhenGroupChanges = null;
0079: protected JRFillElementGroup elementGroup = null;
0080:
0081: /**
0082: *
0083: */
0084: protected JRFillBand band = null;
0085:
0086: /**
0087: *
0088: */
0089: private boolean isPrintWhenExpressionNull = true;
0090: private boolean isPrintWhenTrue = true;
0091: private boolean isToPrint = true;
0092: private boolean isReprinted = false;
0093: private boolean isAlreadyPrinted = false;
0094: private Collection dependantElements = new ArrayList();
0095: private int relativeY = 0;
0096: private int stretchHeight = 0;
0097: private int bandBottomY = 0;
0098:
0099: private int x;
0100: private int y;
0101: private int width;
0102: private int height;
0103:
0104: private boolean isValueRepeating = false;
0105:
0106: protected byte currentEvaluation;
0107:
0108: // used by elements that support evaluationTime=Auto
0109: protected Map delayedEvaluationsMap;
0110:
0111: protected JRFillElementContainer conditionalStylesContainer;
0112:
0113: protected JRStyle initStyle;
0114:
0115: /**
0116: * Flag indicating whether the element is shrinkable.
0117: * @see #setShrinkable(boolean)
0118: */
0119: private boolean shrinkable;
0120:
0121: /**
0122: *
0123: *
0124: private JRElement topElementInGroup = null;
0125: private JRElement bottomElementInGroup = null;
0126:
0127:
0128: /**
0129: *
0130: */
0131: protected JRFillElement(JRBaseFiller filler, JRElement element,
0132: JRFillObjectFactory factory) {
0133: factory.put(element, this );
0134:
0135: this .parent = element;
0136: this .filler = filler;
0137: this .expressionEvaluator = factory.getExpressionEvaluator();
0138: this .defaultStyleProvider = factory.getDefaultStyleProvider();
0139:
0140: /* */
0141: printWhenGroupChanges = factory.getGroup(element
0142: .getPrintWhenGroupChanges());
0143: elementGroup = (JRFillElementGroup) factory
0144: .getElementGroup(element.getElementGroup());
0145:
0146: x = element.getX();
0147: y = element.getY();
0148: width = element.getWidth();
0149: height = element.getHeight();
0150:
0151: factory.registerDelayedStyleSetter(this , parent);
0152: }
0153:
0154: protected JRFillElement(JRFillElement element,
0155: JRFillCloneFactory factory) {
0156: factory.put(element, this );
0157:
0158: this .parent = element.parent;
0159: this .filler = element.filler;
0160: this .expressionEvaluator = element.expressionEvaluator;
0161: this .defaultStyleProvider = element.defaultStyleProvider;
0162:
0163: /* */
0164: printWhenGroupChanges = element.printWhenGroupChanges;
0165: elementGroup = (JRFillElementGroup) factory
0166: .getClone((JRFillElementGroup) element
0167: .getElementGroup());
0168:
0169: x = element.getX();
0170: y = element.getY();
0171: width = element.getWidth();
0172: height = element.getHeight();
0173:
0174: templates = element.templates;
0175:
0176: initStyle = element.initStyle;
0177:
0178: shrinkable = element.shrinkable;
0179: }
0180:
0181: /**
0182: *
0183: */
0184: public JRDefaultStyleProvider getDefaultStyleProvider() {
0185: return defaultStyleProvider;
0186: }
0187:
0188: /**
0189: *
0190: */
0191: public String getKey() {
0192: return parent.getKey();
0193: }
0194:
0195: /**
0196: *
0197: */
0198: public byte getPositionType() {
0199: return parent.getPositionType();//FIXME optimize this by consolidating style properties
0200: }
0201:
0202: /**
0203: *
0204: */
0205: public void setPositionType(byte positionType) {
0206: }
0207:
0208: /**
0209: *
0210: */
0211: public byte getStretchType() {
0212: return parent.getStretchType();
0213: }
0214:
0215: /**
0216: *
0217: */
0218: public void setStretchType(byte stretchType) {
0219: }
0220:
0221: /**
0222: *
0223: */
0224: public boolean isPrintRepeatedValues() {
0225: return parent.isPrintRepeatedValues();
0226: }
0227:
0228: /**
0229: *
0230: */
0231: public void setPrintRepeatedValues(boolean isPrintRepeatedValues) {
0232: }
0233:
0234: /**
0235: *
0236: */
0237: public byte getMode() {
0238: return JRStyleResolver.getMode(this , MODE_OPAQUE);
0239: }
0240:
0241: /**
0242: *
0243: */
0244: public Byte getOwnMode() {
0245: return parent.getOwnMode();
0246: }
0247:
0248: /**
0249: *
0250: */
0251: public void setMode(byte mode) {
0252: }
0253:
0254: /**
0255: *
0256: */
0257: public void setMode(Byte mode) {
0258: }
0259:
0260: /**
0261: *
0262: */
0263: public int getX() {
0264: return x;
0265: }
0266:
0267: /**
0268: *
0269: */
0270: public void setX(int x) {
0271: this .x = x;
0272: }
0273:
0274: /**
0275: *
0276: */
0277: public void setY(int y) {
0278: this .y = y;
0279: }
0280:
0281: /**
0282: *
0283: */
0284: public int getY() {
0285: return y;
0286: }
0287:
0288: /**
0289: *
0290: */
0291: public int getWidth() {
0292: return width;
0293: }
0294:
0295: /**
0296: *
0297: */
0298: public void setWidth(int width) {
0299: this .width = width;
0300: }
0301:
0302: /**
0303: *
0304: */
0305: public void setHeight(int height) {
0306: this .height = height;
0307: }
0308:
0309: /**
0310: *
0311: */
0312: public int getHeight() {
0313: return height;
0314: }
0315:
0316: /**
0317: *
0318: */
0319: public boolean isRemoveLineWhenBlank() {
0320: return parent.isRemoveLineWhenBlank();
0321: }
0322:
0323: /**
0324: *
0325: */
0326: public void setRemoveLineWhenBlank(boolean isRemoveLine) {
0327: }
0328:
0329: /**
0330: *
0331: */
0332: public boolean isPrintInFirstWholeBand() {
0333: return parent.isPrintInFirstWholeBand();
0334: }
0335:
0336: /**
0337: *
0338: */
0339: public void setPrintInFirstWholeBand(boolean isPrint) {
0340: }
0341:
0342: /**
0343: *
0344: */
0345: public boolean isPrintWhenDetailOverflows() {
0346: return parent.isPrintWhenDetailOverflows();
0347: }
0348:
0349: /**
0350: *
0351: */
0352: public void setPrintWhenDetailOverflows(boolean isPrint) {
0353: }
0354:
0355: /**
0356: *
0357: */
0358: public Color getForecolor() {
0359: return JRStyleResolver.getForecolor(this );
0360: }
0361:
0362: public Color getOwnForecolor() {
0363: return parent.getOwnForecolor();
0364: }
0365:
0366: /**
0367: *
0368: */
0369: public void setForecolor(Color forecolor) {
0370: }
0371:
0372: /**
0373: *
0374: */
0375: public Color getBackcolor() {
0376: return JRStyleResolver.getBackcolor(this );
0377: }
0378:
0379: /**
0380: *
0381: */
0382: public Color getOwnBackcolor() {
0383: return parent.getOwnBackcolor();
0384: }
0385:
0386: /**
0387: *
0388: */
0389: public void setBackcolor(Color backcolor) {
0390: }
0391:
0392: /**
0393: *
0394: */
0395: public JRExpression getPrintWhenExpression() {
0396: return parent.getPrintWhenExpression();
0397: }
0398:
0399: /**
0400: *
0401: */
0402: public JRGroup getPrintWhenGroupChanges() {
0403: return printWhenGroupChanges;
0404: }
0405:
0406: /**
0407: *
0408: */
0409: public JRElementGroup getElementGroup() {
0410: return elementGroup;
0411: }
0412:
0413: /**
0414: *
0415: */
0416: protected boolean isPrintWhenExpressionNull() {
0417: return isPrintWhenExpressionNull;
0418: }
0419:
0420: /**
0421: *
0422: */
0423: protected void setPrintWhenExpressionNull(
0424: boolean isPrintWhenExpressionNull) {
0425: this .isPrintWhenExpressionNull = isPrintWhenExpressionNull;
0426: }
0427:
0428: /**
0429: *
0430: */
0431: protected boolean isPrintWhenTrue() {
0432: return isPrintWhenTrue;
0433: }
0434:
0435: /**
0436: *
0437: */
0438: protected void setPrintWhenTrue(boolean isPrintWhenTrue) {
0439: this .isPrintWhenTrue = isPrintWhenTrue;
0440: }
0441:
0442: /**
0443: *
0444: */
0445: protected boolean isToPrint() {
0446: return isToPrint;
0447: }
0448:
0449: /**
0450: *
0451: */
0452: protected void setToPrint(boolean isToPrint) {
0453: this .isToPrint = isToPrint;
0454: }
0455:
0456: /**
0457: *
0458: */
0459: protected boolean isReprinted() {
0460: return isReprinted;
0461: }
0462:
0463: /**
0464: *
0465: */
0466: protected void setReprinted(boolean isReprinted) {
0467: this .isReprinted = isReprinted;
0468: }
0469:
0470: /**
0471: *
0472: */
0473: protected boolean isAlreadyPrinted() {
0474: return isAlreadyPrinted;
0475: }
0476:
0477: /**
0478: *
0479: */
0480: protected void setAlreadyPrinted(boolean isAlreadyPrinted) {
0481: this .isAlreadyPrinted = isAlreadyPrinted;
0482: }
0483:
0484: /**
0485: *
0486: */
0487: protected JRElement[] getGroupElements() {
0488: JRElement[] groupElements = null;
0489:
0490: if (elementGroup != null) {
0491: groupElements = elementGroup.getElements();
0492: }
0493:
0494: return groupElements;
0495: }
0496:
0497: /**
0498: *
0499: */
0500: protected Collection getDependantElements() {
0501: return dependantElements;
0502: }
0503:
0504: /**
0505: *
0506: */
0507: protected void addDependantElement(JRElement element) {
0508: dependantElements.add(element);
0509: }
0510:
0511: /**
0512: *
0513: */
0514: protected int getRelativeY() {
0515: return relativeY;
0516: }
0517:
0518: /**
0519: *
0520: */
0521: protected void setRelativeY(int relativeY) {
0522: this .relativeY = relativeY;
0523: }
0524:
0525: /**
0526: *
0527: */
0528: protected int getStretchHeight() {
0529: return stretchHeight;
0530: }
0531:
0532: /**
0533: *
0534: */
0535: protected void setStretchHeight(int stretchHeight) {
0536: if (stretchHeight > getHeight()
0537: || (shrinkable && isRemoveLineWhenBlank())) {
0538: this .stretchHeight = stretchHeight;
0539: } else {
0540: this .stretchHeight = getHeight();
0541: }
0542: }
0543:
0544: /**
0545: *
0546: */
0547: protected int getBandBottomY() {
0548: return bandBottomY;
0549: }
0550:
0551: /**
0552: *
0553: */
0554: protected void setBandBottomY(int bandBottomY) {
0555: this .bandBottomY = bandBottomY;
0556: }
0557:
0558: /**
0559: *
0560: */
0561: protected JRFillBand getBand() {
0562: return band;
0563: }
0564:
0565: /**
0566: *
0567: */
0568: protected void setBand(JRFillBand band) {
0569: this .band = band;
0570: }
0571:
0572: /**
0573: *
0574: */
0575: protected void reset() {
0576: relativeY = y;
0577: stretchHeight = height;
0578:
0579: if (elementGroup != null) {
0580: elementGroup.reset();
0581: }
0582: }
0583:
0584: protected void setCurrentEvaluation(byte evaluation) {
0585: currentEvaluation = evaluation;
0586: }
0587:
0588: /**
0589: *
0590: */
0591: protected abstract void evaluate(byte evaluation)
0592: throws JRException;
0593:
0594: /**
0595: *
0596: */
0597: protected void evaluatePrintWhenExpression(byte evaluation)
0598: throws JRException {
0599: boolean isExprNull = true;
0600: boolean isExprTrue = false;
0601:
0602: JRExpression expression = getPrintWhenExpression();
0603: if (expression != null) {
0604: isExprNull = false;
0605: Boolean printWhenExpressionValue = (Boolean) evaluateExpression(
0606: expression, evaluation);
0607: if (printWhenExpressionValue == null) {
0608: isExprTrue = false;
0609: } else {
0610: isExprTrue = printWhenExpressionValue.booleanValue();
0611: }
0612: }
0613:
0614: setPrintWhenExpressionNull(isExprNull);
0615: setPrintWhenTrue(isExprTrue);
0616: }
0617:
0618: /**
0619: *
0620: */
0621: protected abstract void rewind() throws JRException;
0622:
0623: /**
0624: *
0625: */
0626: protected abstract JRPrintElement fill() throws JRException;
0627:
0628: /**
0629: *
0630: */
0631: protected boolean prepare(int availableStretchHeight,
0632: boolean isOverflow) throws JRException {
0633: if (isPrintWhenExpressionNull()
0634: || (!isPrintWhenExpressionNull() && isPrintWhenTrue())) {
0635: setToPrint(true);
0636: } else {
0637: setToPrint(false);
0638: }
0639:
0640: setReprinted(false);
0641:
0642: return false;
0643: }
0644:
0645: /**
0646: *
0647: */
0648: protected void stretchElement(int bandStretch) {
0649: switch (getStretchType()) {
0650: case JRElement.STRETCH_TYPE_RELATIVE_TO_BAND_HEIGHT: {
0651: setStretchHeight(getHeight() + bandStretch);
0652: break;
0653: }
0654: case JRElement.STRETCH_TYPE_RELATIVE_TO_TALLEST_OBJECT: {
0655: if (elementGroup != null) {
0656: //setStretchHeight(getHeight() + getStretchHeightDiff());
0657: setStretchHeight(getHeight()
0658: + elementGroup.getStretchHeightDiff());
0659: }
0660:
0661: break;
0662: }
0663: case JRElement.STRETCH_TYPE_NO_STRETCH:
0664: default: {
0665: break;
0666: }
0667: }
0668: }
0669:
0670: /**
0671: *
0672: */
0673: protected void moveDependantElements() {
0674: Collection elements = getDependantElements();
0675: if (elements != null && elements.size() > 0) {
0676: JRFillElement element = null;
0677: int diffY = 0;
0678: for (Iterator it = elements.iterator(); it.hasNext();) {
0679: element = (JRFillElement) it.next();
0680:
0681: diffY = element.getY()
0682: - getY()
0683: - getHeight()
0684: - (element.getRelativeY() - getRelativeY() - getStretchHeight());
0685:
0686: if (diffY < 0) {
0687: diffY = 0;
0688: }
0689:
0690: element.setRelativeY(element.getRelativeY() + diffY);
0691: }
0692: }
0693: }
0694:
0695: /**
0696: * Resolves an element.
0697: *
0698: * @param element the element
0699: * @param evaluation the evaluation type
0700: */
0701: protected abstract void resolveElement(JRPrintElement element,
0702: byte evaluation) throws JRException;
0703:
0704: /**
0705: * Evaluates an expression.
0706: *
0707: * @param expression the expression
0708: * @param evaluation the evaluation type
0709: * @return the evaluation result
0710: * @throws JRException
0711: */
0712: protected final Object evaluateExpression(JRExpression expression,
0713: byte evaluation) throws JRException {
0714: return expressionEvaluator.evaluate(expression, evaluation);
0715: }
0716:
0717: /**
0718: * Decides whether the value for this element is repeating.
0719: * <p>
0720: * Dynamic elements should call {@link #setValueRepeating(boolean) setValueRepeating(boolean)} on
0721: * {@link #evaluate(byte) evaluate(byte)}. Static elements don't have to do anything, this method
0722: * will return <code>true</code> by default.
0723: *
0724: * @return whether the value for this element is repeating
0725: * @see #setValueRepeating(boolean)
0726: */
0727: protected boolean isValueRepeating() {
0728: return isValueRepeating;
0729: }
0730:
0731: /**
0732: * Sets the repeating flag for this element.
0733: * <p>
0734: * This method should be called by dynamic elements on {@link #evaluate(byte) evaluate(byte)}.
0735: *
0736: * @param isValueRepeating whether the value of the element is repeating
0737: * @see #isValueRepeating()
0738: */
0739: protected void setValueRepeating(boolean isValueRepeating) {
0740: this .isValueRepeating = isValueRepeating;
0741: }
0742:
0743: protected JRFillVariable getVariable(String variableName) {
0744: return filler.getVariable(variableName);
0745: }
0746:
0747: protected JRFillField getField(String fieldName) {
0748: return filler.getField(fieldName);
0749: }
0750:
0751: // default for elements not supporting evaluationTime
0752: protected byte getEvaluationTime() {
0753: return JRExpression.EVALUATION_TIME_NOW;
0754: }
0755:
0756: /**
0757: * Resolves an element.
0758: *
0759: * @param element the element
0760: * @param evaluation the evaluation type
0761: * @param evaluationTime the current evaluation time
0762: */
0763: protected void resolveElement(JRPrintElement element,
0764: byte evaluation, JREvaluationTime evaluationTime)
0765: throws JRException {
0766: byte evaluationTimeType = getEvaluationTime();
0767: switch (evaluationTimeType) {
0768: case JRExpression.EVALUATION_TIME_NOW:
0769: break;
0770: case JRExpression.EVALUATION_TIME_AUTO:
0771: delayedEvaluate((JRRecordedValuesPrintElement) element,
0772: evaluationTime, evaluation);
0773: break;
0774: default:
0775: resolveElement(element, evaluation);
0776: break;
0777: }
0778: }
0779:
0780: private static class DelayedEvaluations implements Serializable {
0781: private static final long serialVersionUID = JRConstants.SERIAL_VERSION_UID;
0782:
0783: final Set fields;
0784: final Set variables;
0785:
0786: DelayedEvaluations() {
0787: fields = new HashSet();
0788: variables = new HashSet();
0789: }
0790: }
0791:
0792: protected void initDelayedEvaluations() {
0793: if (getEvaluationTime() == JRExpression.EVALUATION_TIME_AUTO
0794: && delayedEvaluationsMap == null) {
0795: delayedEvaluationsMap = new HashMap();
0796: collectDelayedEvaluations();
0797: }
0798: }
0799:
0800: protected void collectDelayedEvaluations() {
0801: //to be overridden by elements that support "Auto" evaluation
0802: }
0803:
0804: protected void collectDelayedEvaluations(JRExpression expression) {
0805: if (expression != null) {
0806: JRExpressionChunk[] chunks = expression.getChunks();
0807: if (chunks != null) {
0808: for (int i = 0; i < chunks.length; i++) {
0809: JRExpressionChunk chunk = chunks[i];
0810: switch (chunk.getType()) {
0811: case JRExpressionChunk.TYPE_FIELD: {
0812: DelayedEvaluations delayedEvaluations = getDelayedEvaluations(JREvaluationTime.EVALUATION_TIME_NOW);
0813: delayedEvaluations.fields.add(chunk.getText());
0814: break;
0815: }
0816: case JRExpressionChunk.TYPE_VARIABLE: {
0817: JREvaluationTime time = autogetVariableEvaluationTime(chunk
0818: .getText());
0819: DelayedEvaluations delayedEvaluations = getDelayedEvaluations(time);
0820: delayedEvaluations.variables.add(chunk
0821: .getText());
0822: break;
0823: }
0824: }
0825: }
0826: }
0827: }
0828: }
0829:
0830: private DelayedEvaluations getDelayedEvaluations(
0831: JREvaluationTime time) {
0832: DelayedEvaluations delayedEvaluations = (DelayedEvaluations) delayedEvaluationsMap
0833: .get(time);
0834: if (delayedEvaluations == null) {
0835: delayedEvaluations = new DelayedEvaluations();
0836: delayedEvaluationsMap.put(time, delayedEvaluations);
0837: }
0838: return delayedEvaluations;
0839: }
0840:
0841: private JREvaluationTime autogetVariableEvaluationTime(
0842: String variableName) {
0843: JRFillVariable variable = getVariable(variableName);
0844: JREvaluationTime evaluationTime;
0845: switch (variable.getResetType()) {
0846: case JRVariable.RESET_TYPE_REPORT:
0847: evaluationTime = JREvaluationTime.EVALUATION_TIME_REPORT;
0848: break;
0849: case JRVariable.RESET_TYPE_PAGE:
0850: evaluationTime = JREvaluationTime.EVALUATION_TIME_PAGE;
0851: break;
0852: case JRVariable.RESET_TYPE_COLUMN:
0853: evaluationTime = JREvaluationTime.EVALUATION_TIME_COLUMN;
0854: break;
0855: case JRVariable.RESET_TYPE_GROUP:
0856: evaluationTime = JREvaluationTime
0857: .getGroupEvaluationTime(variable.getResetGroup()
0858: .getName());
0859: break;
0860: default:
0861: evaluationTime = JREvaluationTime.EVALUATION_TIME_NOW;
0862: break;
0863: }
0864:
0865: if (!evaluationTime
0866: .equals(JREvaluationTime.EVALUATION_TIME_NOW)
0867: && band.isNowEvaluationTime(evaluationTime)) {
0868: evaluationTime = JREvaluationTime.EVALUATION_TIME_NOW;
0869: }
0870:
0871: if (variable.getCalculation() == JRVariable.CALCULATION_SYSTEM
0872: && evaluationTime
0873: .equals(JREvaluationTime.EVALUATION_TIME_NOW)
0874: && band.isVariableUsedInSubreportReturns(variableName)) {
0875: evaluationTime = JREvaluationTime
0876: .getBandEvaluationTime(band);
0877: }
0878:
0879: return evaluationTime;
0880: }
0881:
0882: protected void initDelayedEvaluationPrint(
0883: JRRecordedValuesPrintElement printElement)
0884: throws JRException {
0885: for (Iterator it = delayedEvaluationsMap.keySet().iterator(); it
0886: .hasNext();) {
0887: JREvaluationTime evaluationTime = (JREvaluationTime) it
0888: .next();
0889: if (!evaluationTime
0890: .equals(JREvaluationTime.EVALUATION_TIME_NOW)) {
0891: filler.addBoundElement(this , printElement,
0892: evaluationTime);
0893: }
0894: }
0895:
0896: printElement.initRecordedValues(delayedEvaluationsMap.keySet());
0897:
0898: if (delayedEvaluationsMap
0899: .containsKey(JREvaluationTime.EVALUATION_TIME_NOW)) {
0900: delayedEvaluate(printElement,
0901: JREvaluationTime.EVALUATION_TIME_NOW,
0902: currentEvaluation);
0903: }
0904: }
0905:
0906: protected void delayedEvaluate(
0907: JRRecordedValuesPrintElement printElement,
0908: JREvaluationTime evaluationTime, byte evaluation)
0909: throws JRException {
0910: JRRecordedValues recordedValues = printElement
0911: .getRecordedValues();
0912: if (!recordedValues.lastEvaluationTime()) {
0913: DelayedEvaluations delayedEvaluations = (DelayedEvaluations) delayedEvaluationsMap
0914: .get(evaluationTime);
0915:
0916: for (Iterator it = delayedEvaluations.fields.iterator(); it
0917: .hasNext();) {
0918: String fieldName = (String) it.next();
0919: JRFillField field = getField(fieldName);
0920: recordedValues.recordFieldValue(fieldName, field
0921: .getValue(evaluation));
0922: }
0923:
0924: for (Iterator it = delayedEvaluations.variables.iterator(); it
0925: .hasNext();) {
0926: String variableName = (String) it.next();
0927: JRFillVariable variable = getVariable(variableName);
0928: recordedValues.recordVariableValue(variableName,
0929: variable.getValue(evaluation));
0930: }
0931: }
0932:
0933: recordedValues.doneEvaluation(evaluationTime);
0934:
0935: if (recordedValues.finishedEvaluations()) {
0936: overwriteWithRecordedValues(recordedValues, evaluation);
0937: resolveElement(printElement, evaluation);
0938: restoreValues(recordedValues, evaluation);
0939: printElement.deleteRecordedValues();
0940: }
0941: }
0942:
0943: private void overwriteWithRecordedValues(
0944: JRRecordedValues recordedValues, byte evaluation) {
0945: Map fieldValues = recordedValues.getRecordedFieldValues();
0946: if (fieldValues != null) {
0947: for (Iterator it = fieldValues.entrySet().iterator(); it
0948: .hasNext();) {
0949: Map.Entry entry = (Map.Entry) it.next();
0950: String fieldName = (String) entry.getKey();
0951: Object fieldValue = entry.getValue();
0952: JRFillField field = getField(fieldName);
0953: field.overwriteValue(fieldValue, evaluation);
0954: }
0955: }
0956:
0957: Map variableValues = recordedValues.getRecordedVariableValues();
0958: if (variableValues != null) {
0959: for (Iterator it = variableValues.entrySet().iterator(); it
0960: .hasNext();) {
0961: Map.Entry entry = (Map.Entry) it.next();
0962: String variableName = (String) entry.getKey();
0963: Object variableValue = entry.getValue();
0964: JRFillVariable variable = getVariable(variableName);
0965: variable.overwriteValue(variableValue, evaluation);
0966: }
0967: }
0968: }
0969:
0970: private void restoreValues(JRRecordedValues recordedValues,
0971: byte evaluation) {
0972: Map fieldValues = recordedValues.getRecordedFieldValues();
0973: if (fieldValues != null) {
0974: for (Iterator it = fieldValues.keySet().iterator(); it
0975: .hasNext();) {
0976: String fieldName = (String) it.next();
0977: JRFillField field = getField(fieldName);
0978: field.restoreValue(evaluation);
0979: }
0980: }
0981:
0982: Map variableValues = recordedValues.getRecordedVariableValues();
0983: if (variableValues != null) {
0984: for (Iterator it = variableValues.keySet().iterator(); it
0985: .hasNext();) {
0986: String variableName = (String) it.next();
0987: JRFillVariable variable = getVariable(variableName);
0988: variable.restoreValue(evaluation);
0989: }
0990: }
0991: }
0992:
0993: /**
0994: *
0995: */
0996: protected void setConditionalStylesContainer(
0997: JRFillElementContainer conditionalStylesContainer) {
0998: this .conditionalStylesContainer = conditionalStylesContainer;
0999: }
1000:
1001: /**
1002: *
1003: */
1004: public JRStyle getStyle() {
1005: JRStyle crtStyle = initStyle;
1006:
1007: boolean isUsingDefaultStyle = false;
1008:
1009: if (crtStyle == null) {
1010: crtStyle = filler.getDefaultStyle();
1011: isUsingDefaultStyle = true;
1012: }
1013:
1014: JRStyle evalStyle = crtStyle;
1015:
1016: if (conditionalStylesContainer != null)
1017: evalStyle = conditionalStylesContainer
1018: .getEvaluatedConditionalStyle(crtStyle);
1019:
1020: if (isUsingDefaultStyle && evalStyle == crtStyle)
1021: evalStyle = null;
1022:
1023: return evalStyle;
1024: }
1025:
1026: /**
1027: *
1028: */
1029: protected JRTemplateElement getTemplate(JRStyle style) {
1030: return (JRTemplateElement) templates.get(style);
1031: }
1032:
1033: /**
1034: *
1035: */
1036: protected void registerTemplate(JRStyle style,
1037: JRTemplateElement template) {
1038: templates.put(style, template);
1039: }
1040:
1041: /**
1042: * Indicates whether an element is shrinkable.
1043: * <p>
1044: * This flag is only effective when {@link #isRemoveLineWhenBlank() isRemoveLineWhenBlank} is also set.
1045: *
1046: * @param shrinkable whether the element is shrinkable
1047: */
1048: protected final void setShrinkable(boolean shrinkable) {
1049: this .shrinkable = shrinkable;
1050: }
1051:
1052: /**
1053: * Called when the stretch height of an element is final so that
1054: * the element can perform any adjustments.
1055: */
1056: protected void stretchHeightFinal() {
1057: // nothing
1058: }
1059:
1060: protected boolean isEvaluateNow() {
1061: boolean evaluateNow;
1062: switch (getEvaluationTime()) {
1063: case JRExpression.EVALUATION_TIME_NOW:
1064: evaluateNow = true;
1065: break;
1066:
1067: case JRExpression.EVALUATION_TIME_AUTO:
1068: evaluateNow = isAutoEvaluateNow();
1069: break;
1070:
1071: default:
1072: evaluateNow = false;
1073: break;
1074: }
1075: return evaluateNow;
1076: }
1077:
1078: protected boolean isAutoEvaluateNow() {
1079: return delayedEvaluationsMap == null
1080: || delayedEvaluationsMap.isEmpty()
1081: || (delayedEvaluationsMap.size() == 1 && delayedEvaluationsMap
1082: .containsKey(JREvaluationTime.EVALUATION_TIME_NOW));
1083: }
1084:
1085: protected boolean isEvaluateAuto() {
1086: return getEvaluationTime() == JRExpression.EVALUATION_TIME_AUTO
1087: && !isAutoEvaluateNow();
1088: }
1089:
1090: public String getStyleNameReference() {
1091: return null;
1092: }
1093:
1094: public void setStyle(JRStyle style) {
1095: initStyle = style;
1096: conditionalStylesContainer.collectConditionalStyle(style);
1097: }
1098:
1099: public void setStyleNameReference(String name) {
1100: throw new UnsupportedOperationException(
1101: "Style name references not allowed at fill time");
1102: }
1103:
1104: }
|