Source Code Cross Referenced for JRFillCrosstab.java in  » Report » jasperreports-2.0.1 » net » sf » jasperreports » engine » fill » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Report » jasperreports 2.0.1 » net.sf.jasperreports.engine.fill 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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.io.IOException;
0031:        import java.util.ArrayList;
0032:        import java.util.Comparator;
0033:        import java.util.HashMap;
0034:        import java.util.Iterator;
0035:        import java.util.List;
0036:        import java.util.Map;
0037:        import java.util.ResourceBundle;
0038:
0039:        import net.sf.jasperreports.crosstabs.JRCellContents;
0040:        import net.sf.jasperreports.crosstabs.JRCrosstab;
0041:        import net.sf.jasperreports.crosstabs.JRCrosstabBucket;
0042:        import net.sf.jasperreports.crosstabs.JRCrosstabCell;
0043:        import net.sf.jasperreports.crosstabs.JRCrosstabColumnGroup;
0044:        import net.sf.jasperreports.crosstabs.JRCrosstabDataset;
0045:        import net.sf.jasperreports.crosstabs.JRCrosstabGroup;
0046:        import net.sf.jasperreports.crosstabs.JRCrosstabMeasure;
0047:        import net.sf.jasperreports.crosstabs.JRCrosstabParameter;
0048:        import net.sf.jasperreports.crosstabs.JRCrosstabRowGroup;
0049:        import net.sf.jasperreports.crosstabs.base.JRBaseCrosstab;
0050:        import net.sf.jasperreports.crosstabs.design.JRDesignCrosstab;
0051:        import net.sf.jasperreports.crosstabs.fill.JRCrosstabExpressionEvaluator;
0052:        import net.sf.jasperreports.crosstabs.fill.JRFillCrosstabCell;
0053:        import net.sf.jasperreports.crosstabs.fill.JRFillCrosstabColumnGroup;
0054:        import net.sf.jasperreports.crosstabs.fill.JRFillCrosstabGroup;
0055:        import net.sf.jasperreports.crosstabs.fill.JRFillCrosstabMeasure;
0056:        import net.sf.jasperreports.crosstabs.fill.JRFillCrosstabParameter;
0057:        import net.sf.jasperreports.crosstabs.fill.JRFillCrosstabRowGroup;
0058:        import net.sf.jasperreports.crosstabs.fill.calculation.BucketDefinition;
0059:        import net.sf.jasperreports.crosstabs.fill.calculation.BucketingService;
0060:        import net.sf.jasperreports.crosstabs.fill.calculation.CrosstabCell;
0061:        import net.sf.jasperreports.crosstabs.fill.calculation.HeaderCell;
0062:        import net.sf.jasperreports.crosstabs.fill.calculation.MeasureDefinition;
0063:        import net.sf.jasperreports.crosstabs.fill.calculation.BucketDefinition.Bucket;
0064:        import net.sf.jasperreports.crosstabs.fill.calculation.MeasureDefinition.MeasureValue;
0065:        import net.sf.jasperreports.engine.JRAbstractObjectFactory;
0066:        import net.sf.jasperreports.engine.JRChild;
0067:        import net.sf.jasperreports.engine.JRElement;
0068:        import net.sf.jasperreports.engine.JRException;
0069:        import net.sf.jasperreports.engine.JRExpression;
0070:        import net.sf.jasperreports.engine.JRExpressionChunk;
0071:        import net.sf.jasperreports.engine.JRExpressionCollector;
0072:        import net.sf.jasperreports.engine.JRGraphicElement;
0073:        import net.sf.jasperreports.engine.JRParameter;
0074:        import net.sf.jasperreports.engine.JRPrintElement;
0075:        import net.sf.jasperreports.engine.JRPrintFrame;
0076:        import net.sf.jasperreports.engine.JRPrintRectangle;
0077:        import net.sf.jasperreports.engine.JRRuntimeException;
0078:        import net.sf.jasperreports.engine.JRStyle;
0079:        import net.sf.jasperreports.engine.JRVariable;
0080:        import net.sf.jasperreports.engine.JasperCompileManager;
0081:        import net.sf.jasperreports.engine.JasperReport;
0082:        import net.sf.jasperreports.engine.design.JRDesignRectangle;
0083:        import net.sf.jasperreports.engine.util.JRStyleResolver;
0084:        import net.sf.jasperreports.engine.xml.JRXmlWriter;
0085:
0086:        import org.jfree.data.general.Dataset;
0087:
0088:        /**
0089:         * Fill-time implementation of a {@link net.sf.jasperreports.crosstabs.JRCrosstab crosstab}.
0090:         * 
0091:         * @author Lucian Chirita (lucianc@users.sourceforge.net)
0092:         * @version $Id: JRFillCrosstab.java 1828 2007-08-24 13:58:43Z teodord $
0093:         */
0094:        public class JRFillCrosstab extends JRFillElement implements  JRCrosstab {
0095:            final protected JRCrosstab parentCrosstab;
0096:
0097:            protected JRFillCrosstabDataset dataset;
0098:
0099:            protected JRFillCrosstabRowGroup[] rowGroups;
0100:
0101:            protected Map rowGroupsMap;
0102:
0103:            protected JRFillCrosstabColumnGroup[] columnGroups;
0104:
0105:            protected Map columnGroupsMap;
0106:
0107:            protected JRFillCrosstabMeasure[] measures;
0108:
0109:            protected BucketingService bucketingService;
0110:
0111:            protected JRFillVariable[] variables;
0112:
0113:            protected Map variablesMap;
0114:
0115:            protected JRFillVariable[][][] totalVariables;
0116:            protected boolean[][] retrieveTotal;
0117:
0118:            protected JRFillCrosstabParameter[] parameters;
0119:
0120:            protected Map parametersMap;
0121:
0122:            protected JRCrosstabExpressionEvaluator crosstabEvaluator;
0123:
0124:            protected JRFillCrosstabCell[][] crossCells;
0125:            protected JRFillCellContents headerCell;
0126:            protected JRFillCellContents whenNoDataCell;
0127:
0128:            protected boolean hasData;
0129:            protected HeaderCell[][] columnHeadersData;
0130:            protected HeaderCell[][] rowHeadersData;
0131:            protected CrosstabCell[][] cellData;
0132:            protected MeasureValue[] grandTotals;
0133:
0134:            private boolean percentage;
0135:
0136:            private CrosstabFiller crosstabFiller;
0137:
0138:            public JRFillCrosstab(JRBaseFiller filler, JRCrosstab crosstab,
0139:                    JRFillObjectFactory factory) {
0140:                super (filler, crosstab, factory);
0141:
0142:                parentCrosstab = crosstab;
0143:
0144:                loadEvaluator(filler.getJasperReport());
0145:
0146:                JRFillObjectFactory crosstabFactory = new JRFillObjectFactory(
0147:                        factory, crosstabEvaluator);
0148:
0149:                headerCell = crosstabFactory.getCell(crosstab.getHeaderCell());
0150:
0151:                copyRowGroups(crosstab, crosstabFactory);
0152:                copyColumnGroups(crosstab, crosstabFactory);
0153:
0154:                copyMeasures(crosstab, crosstabFactory);
0155:                copyCells(crosstab, crosstabFactory);
0156:                whenNoDataCell = crosstabFactory.getCell(crosstab
0157:                        .getWhenNoDataCell());
0158:
0159:                dataset = factory.getCrosstabDataset(crosstab.getDataset(),
0160:                        this );
0161:
0162:                copyParameters(crosstab, factory);
0163:                copyVariables(crosstab, crosstabFactory);
0164:
0165:                crosstabFiller = new CrosstabFiller();
0166:            }
0167:
0168:            /**
0169:             *
0170:             */
0171:            public byte getMode() {
0172:                return JRStyleResolver.getMode(this , MODE_TRANSPARENT);
0173:            }
0174:
0175:            private void copyRowGroups(JRCrosstab crosstab,
0176:                    JRFillObjectFactory factory) {
0177:                JRCrosstabRowGroup[] groups = crosstab.getRowGroups();
0178:                rowGroups = new JRFillCrosstabRowGroup[groups.length];
0179:                rowGroupsMap = new HashMap();
0180:                for (int i = 0; i < groups.length; ++i) {
0181:                    JRFillCrosstabRowGroup group = factory
0182:                            .getCrosstabRowGroup(groups[i]);
0183:                    group.getFillHeader().setVerticalPositionType(
0184:                            groups[i].getPosition());
0185:
0186:                    rowGroups[i] = group;
0187:                    rowGroupsMap.put(group.getName(), new Integer(i));
0188:                }
0189:            }
0190:
0191:            private void copyColumnGroups(JRCrosstab crosstab,
0192:                    JRFillObjectFactory factory) {
0193:                JRCrosstabColumnGroup[] groups = crosstab.getColumnGroups();
0194:                columnGroups = new JRFillCrosstabColumnGroup[groups.length];
0195:                columnGroupsMap = new HashMap();
0196:                for (int i = 0; i < groups.length; ++i) {
0197:                    JRFillCrosstabColumnGroup group = factory
0198:                            .getCrosstabColumnGroup(groups[i]);
0199:                    columnGroups[i] = group;
0200:                    columnGroupsMap.put(group.getName(), new Integer(i));
0201:                }
0202:            }
0203:
0204:            private void copyMeasures(JRCrosstab crosstab,
0205:                    JRFillObjectFactory factory) {
0206:                JRCrosstabMeasure[] crossMeasures = crosstab.getMeasures();
0207:                measures = new JRFillCrosstabMeasure[crossMeasures.length];
0208:                for (int i = 0; i < crossMeasures.length; i++) {
0209:                    measures[i] = factory.getCrosstabMeasure(crossMeasures[i]);
0210:                }
0211:            }
0212:
0213:            private void copyParameters(JRCrosstab crosstab,
0214:                    JRFillObjectFactory factory) {
0215:                JRCrosstabParameter[] crossParams = crosstab.getParameters();
0216:                parameters = new JRFillCrosstabParameter[crossParams.length];
0217:                parametersMap = new HashMap();
0218:                for (int i = 0; i < crossParams.length; i++) {
0219:                    parameters[i] = factory
0220:                            .getCrosstabParameter(crossParams[i]);
0221:                    parametersMap.put(parameters[i].getName(), parameters[i]);
0222:                }
0223:            }
0224:
0225:            private void copyCells(JRCrosstab crosstab,
0226:                    JRFillObjectFactory factory) {
0227:                JRCrosstabCell[][] crosstabCells = crosstab.getCells();
0228:                crossCells = new JRFillCrosstabCell[rowGroups.length + 1][columnGroups.length + 1];
0229:                for (int i = 0; i <= rowGroups.length; ++i) {
0230:                    for (int j = 0; j <= columnGroups.length; ++j) {
0231:                        if (crosstabCells[i][j] != null) {
0232:                            crossCells[i][j] = factory
0233:                                    .getCrosstabCell(crosstabCells[i][j]);
0234:                        }
0235:                    }
0236:                }
0237:            }
0238:
0239:            private void copyVariables(JRCrosstab crosstab,
0240:                    JRFillObjectFactory factory) {
0241:                JRVariable[] vars = crosstab.getVariables();
0242:                variables = new JRFillVariable[vars.length];
0243:                variablesMap = new HashMap();
0244:                for (int i = 0; i < variables.length; i++) {
0245:                    variables[i] = factory.getVariable(vars[i]);
0246:                    variablesMap.put(variables[i].getName(), variables[i]);
0247:                }
0248:
0249:                Map totalVarPos = new HashMap();
0250:                totalVariables = new JRFillVariable[rowGroups.length + 1][columnGroups.length + 1][measures.length];
0251:                for (int row = 0; row <= rowGroups.length; ++row) {
0252:                    JRCrosstabRowGroup rowGroup = row == rowGroups.length ? null
0253:                            : rowGroups[row];
0254:                    for (int col = 0; col <= columnGroups.length; ++col) {
0255:                        JRCrosstabColumnGroup colGroup = col == columnGroups.length ? null
0256:                                : columnGroups[col];
0257:
0258:                        if (row < rowGroups.length || col < columnGroups.length) {
0259:                            for (int m = 0; m < measures.length; m++) {
0260:                                String totalVariableName = JRDesignCrosstab
0261:                                        .getTotalVariableName(measures[m],
0262:                                                rowGroup, colGroup);
0263:                                totalVariables[row][col][m] = (JRFillVariable) variablesMap
0264:                                        .get(totalVariableName);
0265:                                totalVarPos.put(totalVariableName, new int[] {
0266:                                        row, col });
0267:                            }
0268:                        }
0269:                    }
0270:                }
0271:
0272:                retrieveTotal = new boolean[rowGroups.length + 1][columnGroups.length + 1];
0273:
0274:                //FIXME avoid this
0275:                List expressions = JRExpressionCollector.collectExpressions(
0276:                        filler.getJasperReport(), crosstab);
0277:                for (Iterator iter = expressions.iterator(); iter.hasNext();) {
0278:                    JRExpression expression = (JRExpression) iter.next();
0279:                    JRExpressionChunk[] chunks = expression.getChunks();
0280:                    if (chunks != null) {
0281:                        for (int i = 0; i < chunks.length; i++) {
0282:                            JRExpressionChunk chunk = chunks[i];
0283:                            if (chunk.getType() == JRExpressionChunk.TYPE_VARIABLE) {
0284:                                String varName = chunk.getText();
0285:                                int[] pos = (int[]) totalVarPos.get(varName);
0286:                                if (pos != null) {
0287:                                    retrieveTotal[pos[0]][pos[1]] = true;
0288:                                }
0289:                            }
0290:                        }
0291:                    }
0292:                }
0293:            }
0294:
0295:            protected void loadEvaluator(JasperReport jasperReport) {
0296:                try {
0297:                    JREvaluator evaluator = JasperCompileManager.loadEvaluator(
0298:                            jasperReport, parentCrosstab);
0299:                    crosstabEvaluator = new JRCrosstabExpressionEvaluator(
0300:                            evaluator);
0301:                } catch (JRException e) {
0302:                    throw new JRRuntimeException(
0303:                            "Could not load evaluator for crosstab.", e);
0304:                }
0305:            }
0306:
0307:            private BucketingService createService(byte evaluation)
0308:                    throws JRException {
0309:                List rowBuckets = new ArrayList(rowGroups.length);
0310:                for (int i = 0; i < rowGroups.length; ++i) {
0311:                    rowBuckets
0312:                            .add(createServiceBucket(rowGroups[i], evaluation));
0313:                }
0314:
0315:                List colBuckets = new ArrayList(columnGroups.length);
0316:                for (int i = 0; i < columnGroups.length; ++i) {
0317:                    colBuckets.add(createServiceBucket(columnGroups[i],
0318:                            evaluation));
0319:                }
0320:
0321:                percentage = false;
0322:                List measureList = new ArrayList(measures.length);
0323:                for (int i = 0; i < measures.length; ++i) {
0324:                    measureList.add(createServiceMeasure(measures[i]));
0325:                    percentage |= measures[i].getPercentageOfType() == JRCrosstabMeasure.PERCENTAGE_TYPE_GRAND_TOTAL;
0326:                }
0327:
0328:                if (percentage) {
0329:                    ((BucketDefinition) rowBuckets.get(0)).setComputeTotal();
0330:                    ((BucketDefinition) colBuckets.get(0)).setComputeTotal();
0331:                }
0332:
0333:                return new BucketingService(rowBuckets, colBuckets,
0334:                        measureList, dataset.isDataPreSorted(), retrieveTotal);
0335:            }
0336:
0337:            private BucketDefinition createServiceBucket(JRCrosstabGroup group,
0338:                    byte evaluation) throws JRException {
0339:                JRCrosstabBucket bucket = group.getBucket();
0340:
0341:                Comparator comparator = null;
0342:                JRExpression comparatorExpression = bucket
0343:                        .getComparatorExpression();
0344:                if (comparatorExpression != null) {
0345:                    comparator = (Comparator) evaluateExpression(
0346:                            comparatorExpression, evaluation);
0347:                }
0348:
0349:                byte totalPosition = group.getTotalPosition();
0350:                return new BucketDefinition(bucket.getExpression()
0351:                        .getValueClass(), comparator, bucket.getOrder(),
0352:                        totalPosition);
0353:            }
0354:
0355:            private MeasureDefinition createServiceMeasure(
0356:                    JRFillCrosstabMeasure measure) {
0357:                return new MeasureDefinition(measure.getValueClass(), measure
0358:                        .getCalculation(), measure.getIncrementerFactory());
0359:            }
0360:
0361:            protected void reset() {
0362:                super .reset();
0363:
0364:                for (int i = 0; i < variables.length; i++) {
0365:                    variables[i].setValue(null);
0366:                    variables[i].setInitialized(true);
0367:                }
0368:            }
0369:
0370:            protected void evaluate(byte evaluation) throws JRException {
0371:                reset();
0372:
0373:                evaluatePrintWhenExpression(evaluation);
0374:
0375:                if (isPrintWhenExpressionNull() || isPrintWhenTrue()) {
0376:                    dataset.evaluateDatasetRun(evaluation);
0377:
0378:                    initEvaluator(evaluation);
0379:
0380:                    bucketingService.processData();
0381:
0382:                    hasData = bucketingService.hasData();
0383:
0384:                    if (hasData) {
0385:                        columnHeadersData = bucketingService.getColumnHeaders();
0386:                        rowHeadersData = bucketingService.getRowHeaders();
0387:                        cellData = bucketingService.getCrosstabCells();
0388:                        if (percentage) {
0389:                            grandTotals = bucketingService.getGrandTotals();
0390:                        }
0391:
0392:                        crosstabFiller.initCrosstab();
0393:                    }
0394:                }
0395:            }
0396:
0397:            protected void initEvaluator(byte evaluation) throws JRException {
0398:                Map parameterValues = JRFillSubreport.getParameterValues(
0399:                        filler, getParametersMapExpression(), getParameters(),
0400:                        evaluation, true, false,//hasResourceBundle
0401:                        false//hasFormatFactory
0402:                        );
0403:
0404:                ResourceBundle resBdl = (ResourceBundle) parameterValues
0405:                        .get(JRParameter.REPORT_RESOURCE_BUNDLE);
0406:                if (resBdl == null) {
0407:                    JRFillParameter resourceBundleParam = (JRFillParameter) filler
0408:                            .getParametersMap().get(
0409:                                    JRParameter.REPORT_RESOURCE_BUNDLE);
0410:                    parameterValues.put(JRParameter.REPORT_RESOURCE_BUNDLE,
0411:                            resourceBundleParam.getValue());
0412:                }
0413:
0414:                parameterValues.put(JRParameter.REPORT_PARAMETERS_MAP,
0415:                        parameterValues);
0416:
0417:                for (int i = 0; i < parameters.length; i++) {
0418:                    Object value = parameterValues.get(parameters[i].getName());
0419:                    parameters[i].setValue(value);
0420:                }
0421:
0422:                crosstabEvaluator.init(parametersMap, variablesMap, filler
0423:                        .getWhenResourceMissingType());
0424:            }
0425:
0426:            protected void initBucketingService() {
0427:                if (bucketingService == null) {
0428:                    try {
0429:                        bucketingService = createService(JRExpression.EVALUATION_TIME_NOW);
0430:                    } catch (JRException e) {
0431:                        throw new JRRuntimeException(
0432:                                "Could not create bucketing service", e);
0433:                    }
0434:                } else {
0435:                    bucketingService.clear();
0436:                }
0437:            }
0438:
0439:            protected boolean prepare(int availableStretchHeight,
0440:                    boolean isOverflow) throws JRException {
0441:                super .prepare(availableStretchHeight, isOverflow);
0442:
0443:                if (!isToPrint()) {
0444:                    return false;
0445:                }
0446:
0447:                if (availableStretchHeight < getRelativeY() - getY()
0448:                        - getBandBottomY()) {
0449:                    setToPrint(false);
0450:                    return true;
0451:                }
0452:
0453:                if (isOverflow && crosstabFiller.ended() && isAlreadyPrinted()) {
0454:                    if (isPrintWhenDetailOverflows()) {
0455:                        rewind();
0456:                        setReprinted(true);
0457:                    } else {
0458:                        setStretchHeight(getHeight());
0459:                        setToPrint(false);
0460:
0461:                        return false;
0462:                    }
0463:                }
0464:
0465:                if (isOverflow && isPrintWhenDetailOverflows()) {
0466:                    setReprinted(true);
0467:                }
0468:
0469:                int availableHeight = getHeight() + availableStretchHeight
0470:                        - getRelativeY() + getY() + getBandBottomY();
0471:                crosstabFiller.fill(availableHeight);
0472:
0473:                boolean willOverflow = crosstabFiller.willOverflow();
0474:                setStretchHeight(willOverflow ? availableHeight
0475:                        : crosstabFiller.getUsedHeight());
0476:
0477:                return willOverflow;
0478:            }
0479:
0480:            protected JRPrintElement fill() {
0481:                JRPrintRectangle printRectangle = null;
0482:
0483:                printRectangle = new JRTemplatePrintRectangle(
0484:                        getJRTemplateRectangle());
0485:                printRectangle.setX(getX());
0486:                printRectangle.setY(getRelativeY());
0487:                printRectangle.setWidth(getWidth());
0488:                printRectangle.setHeight(getStretchHeight());
0489:
0490:                return printRectangle;
0491:            }
0492:
0493:            protected JRTemplateRectangle getJRTemplateRectangle() {
0494:                JRStyle style = getStyle();
0495:                JRTemplateRectangle template = (JRTemplateRectangle) getTemplate(style);
0496:                if (template == null) {
0497:                    JRDesignRectangle rectangle = new JRDesignRectangle();
0498:
0499:                    rectangle.setKey(getKey());
0500:                    rectangle.setPositionType(getPositionType());
0501:                    // rectangle.setPrintRepeatedValues(isPrintRepeatedValues());
0502:                    rectangle.setMode(getMode());
0503:                    rectangle.setX(getX());
0504:                    rectangle.setY(getY());
0505:                    rectangle.setWidth(getWidth());
0506:                    rectangle.setHeight(getHeight());
0507:                    rectangle.setRemoveLineWhenBlank(isRemoveLineWhenBlank());
0508:                    rectangle
0509:                            .setPrintInFirstWholeBand(isPrintInFirstWholeBand());
0510:                    rectangle
0511:                            .setPrintWhenDetailOverflows(isPrintWhenDetailOverflows());
0512:                    rectangle
0513:                            .setPrintWhenGroupChanges(getPrintWhenGroupChanges());
0514:                    rectangle.setForecolor(getForecolor());
0515:                    rectangle.setBackcolor(getBackcolor());
0516:                    rectangle.setPen(JRGraphicElement.PEN_NONE);
0517:
0518:                    template = new JRTemplateRectangle(filler.getJasperPrint()
0519:                            .getDefaultStyleProvider(), rectangle);
0520:
0521:                    registerTemplate(style, template);
0522:                }
0523:
0524:                return template;
0525:            }
0526:
0527:            protected void rewind() {
0528:                crosstabFiller.initCrosstab();
0529:            }
0530:
0531:            protected List getPrintElements() {
0532:                List printElements = crosstabFiller.getPrintElements();
0533:
0534:                if (getRunDirection() == RUN_DIRECTION_RTL) {
0535:                    mirrorPrintElements(printElements);
0536:                }
0537:
0538:                return printElements;
0539:            }
0540:
0541:            protected void mirrorPrintElements(List printElements) {
0542:                for (Iterator it = printElements.iterator(); it.hasNext();) {
0543:                    JRPrintElement element = (JRPrintElement) it.next();
0544:                    int mirrorX = getWidth() - element.getX()
0545:                            - element.getWidth();
0546:                    element.setX(mirrorX);
0547:                }
0548:            }
0549:
0550:            protected void resolveElement(JRPrintElement element,
0551:                    byte evaluation) {
0552:                // nothing
0553:            }
0554:
0555:            public void collectExpressions(JRExpressionCollector collector) {
0556:                collector.collect(this );
0557:            }
0558:
0559:            public JRChild getCopy(JRAbstractObjectFactory factory) {
0560:                return factory.getCrosstab(this );
0561:            }
0562:
0563:            public void writeXml(JRXmlWriter writer) throws IOException {
0564:                writer.writeCrosstab(this );
0565:            }
0566:
0567:            public int getId() {
0568:                return parentCrosstab.getId();
0569:            }
0570:
0571:            public JRCrosstabDataset getDataset() {
0572:                return dataset;
0573:            }
0574:
0575:            public JRCrosstabRowGroup[] getRowGroups() {
0576:                return rowGroups;
0577:            }
0578:
0579:            public JRCrosstabColumnGroup[] getColumnGroups() {
0580:                return columnGroups;
0581:            }
0582:
0583:            public JRCrosstabMeasure[] getMeasures() {
0584:                return measures;
0585:            }
0586:
0587:            /**
0588:             * Fill-time crosstab input dataset implementation.
0589:             *  
0590:             * @author Lucian Chirita (lucianc@users.sourceforge.net)
0591:             */
0592:            public class JRFillCrosstabDataset extends JRFillElementDataset
0593:                    implements  JRCrosstabDataset {
0594:                private Object[] bucketValues;
0595:
0596:                private Object[] measureValues;
0597:
0598:                public JRFillCrosstabDataset(JRCrosstabDataset dataset,
0599:                        JRFillObjectFactory factory) {
0600:                    super (dataset, factory);
0601:
0602:                    this .bucketValues = new Object[rowGroups.length
0603:                            + columnGroups.length];
0604:                    this .measureValues = new Object[measures.length];
0605:                }
0606:
0607:                protected void customInitialize() {
0608:                    initBucketingService();
0609:                }
0610:
0611:                protected void customEvaluate(JRCalculator calculator)
0612:                        throws JRExpressionEvalException {
0613:                    for (int i = 0; i < rowGroups.length; i++) {
0614:                        bucketValues[i] = calculator.evaluate(rowGroups[i]
0615:                                .getBucket().getExpression());
0616:                    }
0617:
0618:                    for (int i = 0; i < columnGroups.length; ++i) {
0619:                        bucketValues[i + rowGroups.length] = calculator
0620:                                .evaluate(columnGroups[i].getBucket()
0621:                                        .getExpression());
0622:                    }
0623:
0624:                    for (int i = 0; i < measures.length; i++) {
0625:                        measureValues[i] = calculator.evaluate(measures[i]
0626:                                .getValueExpression());
0627:                    }
0628:                }
0629:
0630:                protected void customIncrement() {
0631:                    try {
0632:                        bucketingService.addData(bucketValues, measureValues);
0633:                    } catch (JRException e) {
0634:                        throw new JRRuntimeException(
0635:                                "Error incrementing crosstab dataset", e);
0636:                    }
0637:                }
0638:
0639:                protected Dataset getCustomDataset() {
0640:                    return null;
0641:                }
0642:
0643:                public void collectExpressions(JRExpressionCollector collector) {
0644:                }
0645:
0646:                public boolean isDataPreSorted() {
0647:                    return ((JRCrosstabDataset) parent).isDataPreSorted();
0648:                }
0649:            }
0650:
0651:            /**
0652:             * Crosstab filler class.
0653:             *  
0654:             * @author Lucian Chirita (lucianc@users.sourceforge.net)
0655:             */
0656:            protected class CrosstabFiller {
0657:                private int yOffset;
0658:                private boolean willOverflow;
0659:
0660:                private int[] rowHeadersXOffsets;
0661:
0662:                private boolean[] columnBreakable;
0663:                private boolean[] rowBreakable;
0664:                private int[] columnCount;
0665:                private int[] rowCount;
0666:                private int[] columnXOffsets;
0667:
0668:                private boolean noDataCellPrinted;
0669:
0670:                private int startRowIndex;
0671:                private int startColumnIndex;
0672:                private int lastColumnIndex;
0673:                private List columnHeaders;
0674:
0675:                private List printRows;
0676:
0677:                private HeaderCell[] spanHeaders;
0678:                private int[] spanHeadersStart;
0679:
0680:                private List rowYs = new ArrayList();
0681:                private int rowIdx;
0682:
0683:                private List preparedRow = new ArrayList();
0684:                private int preparedRowHeight;
0685:
0686:                private boolean printRowHeaders;
0687:                private boolean printColumnHeaders;
0688:
0689:                private JRFillVariable rowCountVar;
0690:                private JRFillVariable colCountVar;
0691:
0692:                protected CrosstabFiller() {
0693:                    setRowHeadersXOffsets();
0694:
0695:                    printRows = new ArrayList();
0696:
0697:                    rowCountVar = (JRFillVariable) variablesMap
0698:                            .get(JRCrosstab.VARIABLE_ROW_COUNT);
0699:                    colCountVar = (JRFillVariable) variablesMap
0700:                            .get(JRCrosstab.VARIABLE_COLUMN_COUNT);
0701:                }
0702:
0703:                protected void initCrosstab() {
0704:                    columnXOffsets = computeOffsets(columnHeadersData,
0705:                            columnGroups, true);
0706:                    columnBreakable = computeBreakableHeaders(
0707:                            columnHeadersData, columnGroups, columnXOffsets,
0708:                            true, true);
0709:                    columnCount = computeCounts(columnHeadersData);
0710:
0711:                    int[] rowYOffsets = computeOffsets(rowHeadersData,
0712:                            rowGroups, false);
0713:                    rowBreakable = computeBreakableHeaders(rowHeadersData,
0714:                            rowGroups, rowYOffsets, false, false);
0715:                    rowCount = computeCounts(rowHeadersData);
0716:
0717:                    spanHeaders = new HeaderCell[rowGroups.length - 1];
0718:                    spanHeadersStart = new int[rowGroups.length - 1];
0719:
0720:                    startRowIndex = 0;
0721:                    startColumnIndex = 0;
0722:                    lastColumnIndex = 0;
0723:                    noDataCellPrinted = false;
0724:                }
0725:
0726:                protected void setRowHeadersXOffsets() {
0727:                    rowHeadersXOffsets = new int[rowGroups.length + 1];
0728:                    rowHeadersXOffsets[0] = 0;
0729:                    for (int i = 0; i < rowGroups.length; i++) {
0730:                        rowHeadersXOffsets[i + 1] = rowHeadersXOffsets[i]
0731:                                + rowGroups[i].getWidth();
0732:                    }
0733:                }
0734:
0735:                protected int[] computeOffsets(HeaderCell[][] headersData,
0736:                        JRFillCrosstabGroup[] groups, boolean width) {
0737:                    int[] offsets = new int[headersData[0].length + 1];
0738:                    offsets[0] = 0;
0739:                    for (int i = 0; i < headersData[0].length; i++) {
0740:                        int size = 0;
0741:                        for (int j = groups.length - 1; j >= 0; --j) {
0742:                            if (headersData[j][i] != null) {
0743:                                JRFillCellContents cell = headersData[j][i]
0744:                                        .isTotal() ? groups[j]
0745:                                        .getFillTotalHeader() : groups[j]
0746:                                        .getFillHeader();
0747:                                size = cell == null ? 0 : (width ? cell
0748:                                        .getWidth() : cell.getHeight());
0749:                                break;
0750:                            }
0751:                        }
0752:
0753:                        offsets[i + 1] = offsets[i] + size;
0754:                    }
0755:
0756:                    return offsets;
0757:                }
0758:
0759:                protected boolean[] computeBreakableHeaders(
0760:                        HeaderCell[][] headersData,
0761:                        JRFillCrosstabGroup[] groups, int[] offsets,
0762:                        boolean width, boolean startHeaders) {
0763:                    boolean[] breakable = new boolean[headersData[0].length];
0764:                    for (int i = 0; i < breakable.length; i++) {
0765:                        breakable[i] = true;
0766:                    }
0767:
0768:                    for (int j = 0; j < groups.length; ++j) {
0769:                        JRFillCellContents fillHeader = groups[j]
0770:                                .getFillHeader();
0771:
0772:                        if (fillHeader != null) {
0773:                            int size = width ? fillHeader.getWidth()
0774:                                    : fillHeader.getHeight();
0775:
0776:                            for (int i = 0; i < headersData[0].length; i++) {
0777:                                HeaderCell header = headersData[j][i];
0778:                                if (header != null && !header.isTotal()
0779:                                        && header.getLevelSpan() > 1) {
0780:                                    int span = header.getLevelSpan();
0781:
0782:                                    if (startHeaders) {
0783:                                        for (int k = i + 1; k < i + span
0784:                                                && offsets[k] - offsets[i] < size; ++k) {
0785:                                            breakable[k] = false;
0786:                                        }
0787:                                    }
0788:
0789:                                    for (int k = i + span - 1; k > i
0790:                                            && offsets[i + span] - offsets[k] < size; --k) {
0791:                                        breakable[k] = false;
0792:                                    }
0793:                                }
0794:                            }
0795:                        }
0796:                    }
0797:
0798:                    return breakable;
0799:                }
0800:
0801:                private int[] computeCounts(HeaderCell[][] headersData) {
0802:                    int[] counts = new int[headersData[0].length];
0803:
0804:                    HeaderCell[] lastHeaders = headersData[headersData.length - 1];
0805:                    for (int i = 0, c = 0; i < counts.length; ++i) {
0806:                        HeaderCell lastHeader = lastHeaders[i];
0807:                        if (lastHeader != null && !lastHeader.isTotal()) {
0808:                            ++c;
0809:                        }
0810:
0811:                        counts[i] = c;
0812:                    }
0813:
0814:                    return counts;
0815:                }
0816:
0817:                protected void fill(int availableHeight) throws JRException {
0818:                    printRows.clear();
0819:
0820:                    yOffset = 0;
0821:                    willOverflow = false;
0822:
0823:                    fillVerticalCrosstab(availableHeight);
0824:                }
0825:
0826:                protected boolean willOverflow() {
0827:                    return willOverflow;
0828:                }
0829:
0830:                protected int getUsedHeight() {
0831:                    return yOffset;
0832:                }
0833:
0834:                protected boolean ended() {
0835:                    return hasData ? (startRowIndex >= rowHeadersData[0].length && startColumnIndex >= columnHeadersData[0].length)
0836:                            : noDataCellPrinted;
0837:                }
0838:
0839:                protected void fillVerticalCrosstab(int availableHeight)
0840:                        throws JRException {
0841:                    if (!hasData) {
0842:                        fillNoDataCell(availableHeight);
0843:                        return;
0844:                    }
0845:
0846:                    printRowHeaders = startColumnIndex == 0
0847:                            || isRepeatRowHeaders();
0848:                    int rowHeadersXOffset = printRowHeaders ? rowHeadersXOffsets[rowGroups.length]
0849:                            : 0;
0850:
0851:                    if (startColumnIndex == lastColumnIndex) {
0852:                        int availableWidth = getWidth();
0853:
0854:                        columnHeaders = getGroupHeaders(availableWidth
0855:                                - rowHeadersXOffset, columnXOffsets,
0856:                                columnBreakable, startColumnIndex,
0857:                                columnHeadersData, columnGroups);
0858:                        lastColumnIndex = startColumnIndex
0859:                                + columnHeaders.size();
0860:
0861:                        if (startColumnIndex == lastColumnIndex) {
0862:                            throw new JRRuntimeException(
0863:                                    "Not enough space to render the crosstab.");
0864:                        }
0865:                    }
0866:
0867:                    printColumnHeaders = startRowIndex == 0
0868:                            || isRepeatColumnHeaders();
0869:                    List columnHeaderRows = null;
0870:                    if (printColumnHeaders) {
0871:                        columnHeaderRows = fillColumnHeaders(rowHeadersXOffset,
0872:                                availableHeight - yOffset);
0873:                        if (willOverflow) {
0874:                            return;
0875:                        }
0876:                    }
0877:
0878:                    int lastRowIndex = fillRows(rowHeadersXOffset,
0879:                            availableHeight - yOffset);
0880:
0881:                    if (lastRowIndex == startRowIndex) {
0882:                        willOverflow = true;
0883:                        return;
0884:                    }
0885:
0886:                    if (columnHeaderRows != null) {
0887:                        printRows.addAll(columnHeaderRows);
0888:                    }
0889:
0890:                    if (lastRowIndex >= rowHeadersData[0].length) {
0891:                        startColumnIndex = lastColumnIndex;
0892:
0893:                        if (startColumnIndex < columnHeadersData[0].length) {
0894:                            startRowIndex = lastRowIndex = 0;
0895:
0896:                            yOffset += getColumnBreakOffset();
0897:                            fillVerticalCrosstab(availableHeight);
0898:                            return;
0899:                        }
0900:                    }
0901:
0902:                    boolean fillEnded = lastRowIndex >= rowHeadersData[0].length
0903:                            && lastColumnIndex >= columnHeadersData[0].length;
0904:                    if (fillEnded) {
0905:                        setStretchHeight(yOffset);
0906:                    } else {
0907:                        setStretchHeight(availableHeight);
0908:                    }
0909:
0910:                    startRowIndex = lastRowIndex;
0911:
0912:                    willOverflow = !fillEnded;
0913:                }
0914:
0915:                protected List getGroupHeaders(int available, int[] offsets,
0916:                        boolean[] breakable, int firstIndex,
0917:                        HeaderCell[][] headersData, JRFillCrosstabGroup[] groups) {
0918:                    List headers = new ArrayList();
0919:
0920:                    int maxOffset = available + offsets[firstIndex];
0921:                    int lastIndex;
0922:                    for (lastIndex = firstIndex; lastIndex < headersData[0].length
0923:                            && offsets[lastIndex + 1] <= maxOffset; ++lastIndex) {
0924:                        HeaderCell[] groupHeaders = new HeaderCell[groups.length];
0925:
0926:                        for (int j = 0; j < groups.length; ++j) {
0927:                            groupHeaders[j] = headersData[j][lastIndex];
0928:                        }
0929:
0930:                        headers.add(groupHeaders);
0931:                    }
0932:
0933:                    if (lastIndex < headersData[0].length) {
0934:                        while (lastIndex > firstIndex && !breakable[lastIndex]) {
0935:                            --lastIndex;
0936:                            headers.remove(headers.size() - 1);
0937:                        }
0938:                    }
0939:
0940:                    if (lastIndex > firstIndex) {
0941:                        if (firstIndex > 0) {
0942:                            HeaderCell[] firstHeaders = (HeaderCell[]) headers
0943:                                    .get(0);
0944:
0945:                            for (int j = 0; j < groups.length; ++j) {
0946:                                HeaderCell header = headersData[j][firstIndex];
0947:
0948:                                if (header == null) {
0949:                                    int spanIndex = getSpanIndex(firstIndex, j,
0950:                                            headersData);
0951:                                    if (spanIndex >= 0) {
0952:                                        HeaderCell spanCell = headersData[j][spanIndex];
0953:                                        int headerEndIdx = spanCell
0954:                                                .getLevelSpan()
0955:                                                + spanIndex;
0956:                                        if (headerEndIdx > lastIndex) {
0957:                                            headerEndIdx = lastIndex;
0958:                                        }
0959:                                        firstHeaders[j] = HeaderCell
0960:                                                .createLevelSpanCopy(spanCell,
0961:                                                        headerEndIdx
0962:                                                                - firstIndex);
0963:                                    }
0964:                                }
0965:                            }
0966:                        }
0967:
0968:                        if (lastIndex < headersData[0].length) {
0969:                            for (int j = 0; j < groups.length; ++j) {
0970:                                HeaderCell header = headersData[j][lastIndex];
0971:
0972:                                if (header == null) {
0973:                                    int spanIndex = getSpanIndex(lastIndex, j,
0974:                                            headersData);
0975:                                    if (spanIndex >= firstIndex) {
0976:                                        HeaderCell spanCell = headersData[j][spanIndex];
0977:                                        HeaderCell[] headerCells = (HeaderCell[]) headers
0978:                                                .get(spanIndex - firstIndex);
0979:                                        headerCells[j] = HeaderCell
0980:                                                .createLevelSpanCopy(spanCell,
0981:                                                        lastIndex - spanIndex);
0982:                                    }
0983:                                }
0984:                            }
0985:                        }
0986:                    }
0987:
0988:                    return headers;
0989:                }
0990:
0991:                protected int getSpanIndex(int i, int j,
0992:                        HeaderCell[][] headersData) {
0993:                    int spanIndex = i - 1;
0994:                    while (spanIndex >= 0 && headersData[j][spanIndex] == null) {
0995:                        --spanIndex;
0996:                    }
0997:
0998:                    if (spanIndex >= 0) {
0999:                        HeaderCell spanCell = headersData[j][spanIndex];
1000:                        int span = spanCell.getLevelSpan();
1001:
1002:                        if (span > i - spanIndex) {
1003:                            return spanIndex;
1004:                        }
1005:                    }
1006:
1007:                    return -1;
1008:                }
1009:
1010:                protected void fillNoDataCell(int availableHeight)
1011:                        throws JRException {
1012:                    if (whenNoDataCell == null) {
1013:                        noDataCellPrinted = true;
1014:                    } else {
1015:                        if (availableHeight < whenNoDataCell.getHeight()) {
1016:                            willOverflow = true;
1017:                        } else {
1018:                            whenNoDataCell
1019:                                    .evaluate(JRExpression.EVALUATION_DEFAULT);
1020:                            whenNoDataCell.prepare(availableHeight
1021:                                    - whenNoDataCell.getHeight());
1022:
1023:                            willOverflow = whenNoDataCell.willOverflow();
1024:
1025:                            if (!willOverflow) {
1026:                                whenNoDataCell.setX(0);
1027:                                whenNoDataCell.setY(0);
1028:
1029:                                JRPrintFrame printCell = whenNoDataCell.fill();
1030:                                List noDataRow = new ArrayList(1);
1031:                                noDataRow.add(printCell);
1032:                                addPrintRow(noDataRow);
1033:
1034:                                yOffset += whenNoDataCell.getPrintHeight();
1035:                                noDataCellPrinted = true;
1036:                            }
1037:                        }
1038:                    }
1039:                }
1040:
1041:                protected List fillColumnHeaders(int rowHeadersXOffset,
1042:                        int availableHeight) throws JRException {
1043:                    JRFillCellContents[][] columnHeaderRows = new JRFillCellContents[columnGroups.length][lastColumnIndex
1044:                            - startColumnIndex + 1];
1045:
1046:                    rowYs.clear();
1047:                    rowYs.add(new Integer(0));
1048:
1049:                    if (printRowHeaders && headerCell != null) {
1050:                        JRFillCellContents contents = fillHeader(availableHeight);
1051:
1052:                        if (willOverflow) {
1053:                            return null;
1054:                        }
1055:
1056:                        columnHeaderRows[columnGroups.length - 1][0] = contents;
1057:                    }
1058:
1059:                    rows: for (rowIdx = 0; rowIdx < columnGroups.length; rowIdx++) {
1060:                        for (int columnIdx = startColumnIndex; columnIdx < lastColumnIndex; ++columnIdx) {
1061:                            HeaderCell[] headers = (HeaderCell[]) columnHeaders
1062:                                    .get(columnIdx - startColumnIndex);
1063:                            HeaderCell cell = headers[rowIdx];
1064:
1065:                            if (cell != null) {
1066:                                JRFillCellContents contents = prepareColumnHeader(
1067:                                        cell, columnIdx, rowHeadersXOffset,
1068:                                        availableHeight);
1069:                                columnHeaderRows[rowIdx + cell.getDepthSpan()
1070:                                        - 1][columnIdx - startColumnIndex + 1] = contents;
1071:
1072:                                if (willOverflow) {
1073:                                    break rows;
1074:                                }
1075:                            }
1076:                        }
1077:
1078:                        int rowStretchHeight = stretchColumnHeadersRow(columnHeaderRows[rowIdx]);
1079:                        rowYs.add(new Integer(((Integer) rowYs.get(rowIdx))
1080:                                .intValue()
1081:                                + rowStretchHeight));
1082:                    }
1083:
1084:                    List headerRows;
1085:                    if (willOverflow) {
1086:                        headerRows = null;
1087:                        releaseColumnHeaderCells(columnHeaderRows);
1088:                    } else {
1089:                        headerRows = fillColumnHeaders(columnHeaderRows);
1090:                        yOffset += ((Integer) rowYs.get(columnGroups.length))
1091:                                .intValue();
1092:                    }
1093:
1094:                    resetVariables();
1095:
1096:                    return headerRows;
1097:                }
1098:
1099:                private void setCountVars(int rowIdx, int colIdx) {
1100:                    if (rowIdx == -1) {
1101:                        rowCountVar.setValue(null);
1102:                    } else {
1103:                        rowCountVar.setValue(new Integer(rowCount[rowIdx]));
1104:                    }
1105:
1106:                    if (colIdx == -1) {
1107:                        colCountVar.setValue(null);
1108:                    } else {
1109:                        colCountVar.setValue(new Integer(columnCount[colIdx]));
1110:                    }
1111:                }
1112:
1113:                private JRFillCellContents fillHeader(int availableHeight)
1114:                        throws JRException {
1115:                    setCountVars(-1, -1);
1116:
1117:                    JRFillCellContents contents = headerCell.getWorkingClone();
1118:                    contents.evaluate(JRExpression.EVALUATION_DEFAULT);
1119:                    contents.prepare(availableHeight - headerCell.getHeight());
1120:
1121:                    willOverflow = contents.willOverflow();
1122:
1123:                    if (!willOverflow) {
1124:                        contents.setX(0);
1125:                        contents.setY(yOffset);
1126:                        contents.setVerticalSpan(columnGroups.length);
1127:                    }
1128:                    return contents;
1129:                }
1130:
1131:                private JRFillCellContents prepareColumnHeader(HeaderCell cell,
1132:                        int columnIdx, int xOffset, int availableHeight)
1133:                        throws JRException {
1134:                    JRFillCrosstabColumnGroup group = columnGroups[rowIdx];
1135:                    JRFillCellContents contents = cell.isTotal() ? group
1136:                            .getFillTotalHeader() : group.getFillHeader();
1137:
1138:                    int width = columnXOffsets[columnIdx + cell.getLevelSpan()]
1139:                            - columnXOffsets[columnIdx];
1140:                    int height = contents.getHeight();
1141:
1142:                    if (width <= 0 || height <= 0) {
1143:                        return null;
1144:                    }
1145:
1146:                    JRFillCellContents preparedContents = null;
1147:
1148:                    int rowY = ((Integer) rowYs.get(rowIdx)).intValue();
1149:                    int cellAvailableStretch = availableHeight - rowY - height;
1150:
1151:                    if (cellAvailableStretch >= 0) {
1152:                        setCountVars(-1, columnIdx);
1153:                        setGroupVariables(columnGroups, cell.getBucketValues());
1154:
1155:                        contents = contents.getTransformedContents(width,
1156:                                height, group.getPosition(),
1157:                                JRCellContents.POSITION_Y_TOP);
1158:                        boolean firstOnRow = columnIdx == startColumnIndex
1159:                                && (!printRowHeaders || headerCell == null);
1160:                        contents = contents
1161:                                .getBoxContents(
1162:                                        firstOnRow
1163:                                                && getRunDirection() == RUN_DIRECTION_LTR,
1164:                                        firstOnRow
1165:                                                && getRunDirection() == RUN_DIRECTION_RTL,
1166:                                        false);
1167:                        contents = contents.getWorkingClone();
1168:
1169:                        contents.evaluate(JRExpression.EVALUATION_DEFAULT);
1170:                        contents.prepare(cellAvailableStretch);
1171:
1172:                        if (contents.willOverflow()) {
1173:                            willOverflow = true;
1174:                        } else {
1175:                            contents.setX(columnXOffsets[columnIdx]
1176:                                    - columnXOffsets[startColumnIndex]
1177:                                    + xOffset);
1178:                            contents.setY(rowY + yOffset);
1179:                            contents.setVerticalSpan(cell.getDepthSpan());
1180:
1181:                            preparedContents = contents;
1182:                        }
1183:                    } else {
1184:                        willOverflow = true;
1185:                    }
1186:
1187:                    return preparedContents;
1188:                }
1189:
1190:                private int stretchColumnHeadersRow(JRFillCellContents[] headers) {
1191:                    int rowY = ((Integer) rowYs.get(rowIdx)).intValue();
1192:
1193:                    int rowStretchHeight = 0;
1194:                    for (int j = 0; j < headers.length; j++) {
1195:                        JRFillCellContents contents = headers[j];
1196:
1197:                        if (contents != null) {
1198:                            int startRowY = rowY;
1199:                            if (contents.getVerticalSpan() > 1) {
1200:                                startRowY = ((Integer) rowYs.get(rowIdx
1201:                                        - contents.getVerticalSpan() + 1))
1202:                                        .intValue();
1203:                            }
1204:
1205:                            int height = contents.getPrintHeight() - rowY
1206:                                    + startRowY;
1207:
1208:                            if (height > rowStretchHeight) {
1209:                                rowStretchHeight = height;
1210:                            }
1211:                        }
1212:                    }
1213:
1214:                    for (int j = 0; j < headers.length; j++) {
1215:                        JRFillCellContents contents = headers[j];
1216:
1217:                        if (contents != null) {
1218:                            int startRowY = rowY;
1219:                            if (contents.getVerticalSpan() > 1) {
1220:                                startRowY = ((Integer) rowYs.get(rowIdx
1221:                                        - contents.getVerticalSpan() + 1))
1222:                                        .intValue();
1223:                            }
1224:
1225:                            contents.stretchTo(rowStretchHeight + rowY
1226:                                    - startRowY);
1227:                        }
1228:                    }
1229:
1230:                    return rowStretchHeight;
1231:                }
1232:
1233:                private List fillColumnHeaders(
1234:                        JRFillCellContents[][] columnHeaderRows)
1235:                        throws JRException {
1236:                    List headerRows = new ArrayList(columnGroups.length);
1237:
1238:                    for (int i = 0; i < columnHeaderRows.length; ++i) {
1239:                        List headerRow = new ArrayList(lastColumnIndex
1240:                                - startColumnIndex);
1241:                        headerRows.add(headerRow);
1242:
1243:                        for (int j = 0; j < columnHeaderRows[i].length; j++) {
1244:                            JRFillCellContents contents = columnHeaderRows[i][j];
1245:
1246:                            if (contents != null) {
1247:                                headerRow.add(contents.fill());
1248:                                contents.releaseWorkingClone();
1249:                            }
1250:                        }
1251:                    }
1252:
1253:                    return headerRows;
1254:                }
1255:
1256:                private void releaseColumnHeaderCells(
1257:                        JRFillCellContents[][] columnHeaderRows)
1258:                        throws JRException {
1259:                    for (int i = 0; i < columnHeaderRows.length; ++i) {
1260:                        for (int j = 0; j < columnHeaderRows[i].length; j++) {
1261:                            JRFillCellContents contents = columnHeaderRows[i][j];
1262:
1263:                            if (contents != null) {
1264:                                contents.rewind();
1265:                                contents.releaseWorkingClone();
1266:                            }
1267:                        }
1268:                    }
1269:                }
1270:
1271:                protected int fillRows(int xOffset, int availableHeight)
1272:                        throws JRException {
1273:                    rowYs.clear();
1274:                    rowYs.add(new Integer(0));
1275:
1276:                    for (rowIdx = 0; rowIdx < cellData.length - startRowIndex; ++rowIdx) {
1277:                        initPreparedRow();
1278:
1279:                        prepareRow(xOffset, availableHeight);
1280:
1281:                        if (willOverflow) {
1282:                            break;
1283:                        }
1284:
1285:                        fillRow();
1286:
1287:                        rowYs.add(new Integer(((Integer) rowYs.get(rowIdx))
1288:                                .intValue()
1289:                                + preparedRowHeight));
1290:                    }
1291:
1292:                    if (rowIdx < cellData.length - startRowIndex)//overflow
1293:                    {
1294:                        releasePreparedRow();
1295:
1296:                        if (printRowHeaders) {
1297:                            fillContinuingRowHeaders(xOffset, availableHeight);
1298:                        }
1299:                    }
1300:
1301:                    yOffset += ((Integer) rowYs.get(rowIdx)).intValue();
1302:
1303:                    return rowIdx + startRowIndex;
1304:                }
1305:
1306:                private void initPreparedRow() {
1307:                    preparedRow.clear();
1308:                    preparedRowHeight = 0;
1309:                }
1310:
1311:                private void removeFilledRows(int rowsToRemove) {
1312:                    if (rowsToRemove > 0) {
1313:                        for (int i = 0; i < rowsToRemove; ++i) {
1314:                            printRows.remove(printRows.size() - 1);
1315:                            rowYs.remove(rowYs.size() - 1);
1316:                        }
1317:
1318:                        rowIdx -= rowsToRemove;
1319:                    }
1320:                }
1321:
1322:                private void releasePreparedRow() throws JRException {
1323:                    for (Iterator it = preparedRow.iterator(); it.hasNext();) {
1324:                        JRFillCellContents cell = (JRFillCellContents) it
1325:                                .next();
1326:                        cell.rewind();
1327:                        cell.releaseWorkingClone();
1328:                    }
1329:
1330:                    preparedRow.clear();
1331:                }
1332:
1333:                private void fillRow() throws JRException {
1334:                    int rowY = ((Integer) rowYs.get(rowIdx)).intValue();
1335:
1336:                    List rowPrints = new ArrayList(preparedRow.size());
1337:                    for (Iterator it = preparedRow.iterator(); it.hasNext();) {
1338:                        JRFillCellContents cell = (JRFillCellContents) it
1339:                                .next();
1340:
1341:                        int spanHeight = 0;
1342:                        if (cell.getVerticalSpan() > 1) {
1343:                            spanHeight = rowY
1344:                                    - ((Integer) rowYs.get(rowIdx
1345:                                            - cell.getVerticalSpan() + 1))
1346:                                            .intValue();
1347:                        }
1348:
1349:                        cell.stretchTo(preparedRowHeight + spanHeight);
1350:                        rowPrints.add(cell.fill());
1351:
1352:                        cell.releaseWorkingClone();
1353:                    }
1354:
1355:                    addPrintRow(rowPrints);
1356:                }
1357:
1358:                private void prepareRow(int xOffset, int availableHeight)
1359:                        throws JRException {
1360:                    for (int col = startColumnIndex; col < lastColumnIndex; ++col) {
1361:                        CrosstabCell data = cellData[rowIdx + startRowIndex][col];
1362:                        boolean overflow = prepareDataCell(data, col,
1363:                                availableHeight, xOffset);
1364:
1365:                        if (overflow) {
1366:                            willOverflow = true;
1367:                            return;
1368:                        }
1369:                    }
1370:
1371:                    resetVariables();
1372:
1373:                    if (printRowHeaders) {
1374:                        for (int j = 0; j < rowGroups.length; j++) {
1375:                            HeaderCell cell = rowHeadersData[j][rowIdx
1376:                                    + startRowIndex];
1377:
1378:                            boolean overflow = false;
1379:                            if (cell == null) {
1380:                                overflow = prepareClosingRowHeader(j,
1381:                                        availableHeight);
1382:                            } else {
1383:                                if (cell.getLevelSpan() > 1) {
1384:                                    spanHeaders[j] = cell;
1385:                                    spanHeadersStart[j] = rowIdx
1386:                                            + startRowIndex;
1387:                                    continue;
1388:                                }
1389:
1390:                                overflow = prepareRowHeader(j, cell, 1,
1391:                                        availableHeight);
1392:                            }
1393:
1394:                            if (overflow) {
1395:                                willOverflow = true;
1396:                                return;
1397:                            }
1398:                        }
1399:
1400:                        resetVariables();
1401:                    }
1402:                }
1403:
1404:                private boolean prepareDataCell(CrosstabCell data, int column,
1405:                        int availableHeight, int xOffset) throws JRException {
1406:                    int rowY = ((Integer) rowYs.get(rowIdx)).intValue();
1407:
1408:                    JRFillCrosstabCell cell = crossCells[data
1409:                            .getRowTotalGroupIndex()][data
1410:                            .getColumnTotalGroupIndex()];
1411:                    JRFillCellContents contents = cell == null ? null : cell
1412:                            .getFillContents();
1413:                    if (contents == null || contents.getWidth() <= 0
1414:                            || contents.getHeight() <= 0) {
1415:                        return false;
1416:                    }
1417:
1418:                    int cellAvailableStretch = availableHeight - rowY
1419:                            - contents.getHeight();
1420:                    boolean overflow = cellAvailableStretch < 0;
1421:                    if (!overflow) {
1422:                        boolean leftEmpty = startColumnIndex != 0
1423:                                && !isRepeatRowHeaders();
1424:                        boolean topEmpty = startRowIndex != 0
1425:                                && !isRepeatColumnHeaders();
1426:
1427:                        setCountVars(rowIdx + startRowIndex, column);
1428:                        setGroupVariables(rowGroups, data.getRowBucketValues());
1429:                        setGroupVariables(columnGroups, data
1430:                                .getColumnBucketValues());
1431:                        setMeasureVariables(data);
1432:
1433:                        boolean firstOnRow = leftEmpty
1434:                                && column == startColumnIndex;
1435:                        contents = contents
1436:                                .getBoxContents(
1437:                                        firstOnRow
1438:                                                && getRunDirection() == RUN_DIRECTION_LTR,
1439:                                        firstOnRow
1440:                                                && getRunDirection() == RUN_DIRECTION_RTL,
1441:                                        topEmpty && rowIdx == 0);
1442:                        contents = contents.getWorkingClone();
1443:
1444:                        contents.evaluate(JRExpression.EVALUATION_DEFAULT);
1445:                        contents.prepare(cellAvailableStretch);
1446:
1447:                        preparedRow.add(contents);
1448:
1449:                        overflow = contents.willOverflow();
1450:
1451:                        if (!overflow) {
1452:                            contents.setX(columnXOffsets[column]
1453:                                    - columnXOffsets[startColumnIndex]
1454:                                    + xOffset);
1455:                            contents.setY(rowY + yOffset);
1456:
1457:                            int rowCellHeight = contents.getPrintHeight();
1458:                            if (rowCellHeight > preparedRowHeight) {
1459:                                preparedRowHeight = rowCellHeight;
1460:                            }
1461:                        }
1462:                    }
1463:
1464:                    return overflow;
1465:                }
1466:
1467:                private boolean prepareRowHeader(int rowGroup, HeaderCell cell,
1468:                        int vSpan, int availableHeight) throws JRException {
1469:                    JRFillCrosstabRowGroup group = rowGroups[rowGroup];
1470:                    JRFillCellContents contents = cell.isTotal() ? group
1471:                            .getFillTotalHeader() : group.getFillHeader();
1472:
1473:                    if (contents.getWidth() <= 0 || contents.getHeight() <= 0) {
1474:                        return false;
1475:                    }
1476:
1477:                    int spanHeight = 0;
1478:                    int headerY = ((Integer) rowYs.get(rowIdx - vSpan + 1))
1479:                            .intValue();
1480:                    if (vSpan > 1) {
1481:                        spanHeight += ((Integer) rowYs.get(rowIdx)).intValue()
1482:                                - headerY;
1483:                    }
1484:                    int rowHeight = spanHeight + preparedRowHeight;
1485:
1486:                    boolean stretchContents = group.getPosition() == JRCellContents.POSITION_Y_STRETCH;
1487:                    int contentsHeight = stretchContents ? rowHeight : contents
1488:                            .getHeight();
1489:
1490:                    int cellAvailableStretch = availableHeight - headerY
1491:                            - contentsHeight;
1492:                    boolean headerOverflow = cellAvailableStretch < 0
1493:                            || rowHeight < contents.getHeight();
1494:
1495:                    if (!headerOverflow) {
1496:                        setCountVars(rowIdx + startRowIndex - vSpan + 1, -1);
1497:                        setGroupVariables(rowGroups, cell.getBucketValues());
1498:
1499:                        if (stretchContents) {
1500:                            contents = contents.getTransformedContents(contents
1501:                                    .getWidth(), rowHeight,
1502:                                    JRCellContents.POSITION_X_LEFT,
1503:                                    JRCellContents.POSITION_Y_STRETCH);
1504:                        }
1505:                        contents = contents
1506:                                .getBoxContents(
1507:                                        false,
1508:                                        false,
1509:                                        rowIdx + 1 == vSpan
1510:                                                && (!printColumnHeaders || headerCell == null));
1511:                        contents.getWorkingClone();
1512:
1513:                        contents.evaluate(JRExpression.EVALUATION_DEFAULT);
1514:                        contents.prepare(cellAvailableStretch);
1515:
1516:                        preparedRow.add(contents);
1517:
1518:                        headerOverflow = contents.willOverflow();
1519:
1520:                        if (!headerOverflow) {
1521:                            contents.setX(rowHeadersXOffsets[rowGroup]);
1522:                            contents.setY(headerY + yOffset);
1523:                            contents.setVerticalSpan(vSpan);
1524:
1525:                            int rowCellHeight = contents.getPrintHeight()
1526:                                    - spanHeight;
1527:                            if (rowCellHeight > preparedRowHeight) {
1528:                                preparedRowHeight = rowCellHeight;
1529:                            }
1530:                        }
1531:                    }
1532:
1533:                    if (headerOverflow) {
1534:                        removeFilledRows(vSpan - 1);
1535:                    }
1536:
1537:                    return headerOverflow;
1538:                }
1539:
1540:                private boolean prepareClosingRowHeader(int rowGroup,
1541:                        int availableHeight) throws JRException {
1542:                    if (rowGroup < rowGroups.length - 1
1543:                            && spanHeaders[rowGroup] != null
1544:                            && spanHeaders[rowGroup].getLevelSpan()
1545:                                    + spanHeadersStart[rowGroup] == rowIdx
1546:                                    + startRowIndex + 1) {
1547:                        HeaderCell cell = spanHeaders[rowGroup];
1548:                        int vSpan = cell.getLevelSpan();
1549:                        if (spanHeadersStart[rowGroup] < startRowIndex)//continuing from the prev page
1550:                        {
1551:                            vSpan += spanHeadersStart[rowGroup] - startRowIndex;
1552:                        }
1553:                        spanHeaders[rowGroup] = null;
1554:
1555:                        return prepareRowHeader(rowGroup, cell, vSpan,
1556:                                availableHeight);
1557:                    }
1558:
1559:                    return false;
1560:                }
1561:
1562:                private void removeExceedingSpanHeaders() {
1563:                    for (int j = rowGroups.length - 2; j >= 0; --j) {
1564:                        if (spanHeaders[j] != null
1565:                                && spanHeadersStart[j] >= rowIdx
1566:                                        + startRowIndex) {
1567:                            spanHeaders[j] = null;
1568:                        }
1569:                    }
1570:                }
1571:
1572:                private void setBackSpanHeaders() {
1573:                    for (int j = rowGroups.length - 2; j >= 0
1574:                            && spanHeaders[j] == null; --j) {
1575:                        int spanIndex = getSpanIndex(rowIdx + startRowIndex, j,
1576:                                rowHeadersData);
1577:
1578:                        if (spanIndex >= 0) {
1579:                            spanHeaders[j] = rowHeadersData[j][spanIndex];
1580:                            spanHeadersStart[j] = spanIndex;
1581:                        }
1582:                    }
1583:                }
1584:
1585:                private void fillContinuingRowHeaders(int xOffset,
1586:                        int availableHeight) throws JRException {
1587:                    boolean done = false;
1588:                    breakCrosstab: do {
1589:                        removeExceedingSpanHeaders();
1590:
1591:                        if (!rowBreakable[rowIdx + startRowIndex]) {
1592:                            removeFilledRows(1);
1593:                            setBackSpanHeaders();
1594:                            continue;
1595:                        }
1596:
1597:                        initPreparedRow();
1598:
1599:                        //fill continuing headers
1600:                        for (int j = 0; j < rowGroups.length - 1; ++j) {
1601:                            if (spanHeaders[j] != null) {
1602:                                boolean headerOverflow = prepareContinuingRowHeader(
1603:                                        j, availableHeight);
1604:
1605:                                if (headerOverflow) {
1606:                                    releasePreparedRow();
1607:                                    continue breakCrosstab;
1608:                                }
1609:                            }
1610:                        }
1611:
1612:                        if (!preparedRow.isEmpty()) {
1613:                            int lastRowHeight = ((Integer) rowYs.get(rowIdx))
1614:                                    .intValue()
1615:                                    - ((Integer) rowYs.get(rowIdx - 1))
1616:                                            .intValue();
1617:
1618:                            if (preparedRowHeight > lastRowHeight)//need to stretch already filled row by refilling
1619:                            {
1620:                                refillLastRow(xOffset, availableHeight);
1621:                            } else {
1622:                                fillContinuingHeaders(lastRowHeight);
1623:                            }
1624:                        }
1625:
1626:                        done = true;
1627:                    } while (!done && rowIdx > 0);
1628:                }
1629:
1630:                private void fillContinuingHeaders(int lastRowHeight)
1631:                        throws JRException {
1632:                    int nextToLastHeaderY = ((Integer) rowYs.get(rowIdx - 1))
1633:                            .intValue();
1634:                    List lastPrintRow = getLastPrintRow();
1635:
1636:                    for (int j = 0; j < preparedRow.size(); ++j) {
1637:                        JRFillCellContents contents = (JRFillCellContents) preparedRow
1638:                                .get(j);
1639:
1640:                        int headerY = ((Integer) rowYs.get(rowIdx
1641:                                - contents.getVerticalSpan())).intValue();
1642:
1643:                        contents.stretchTo(nextToLastHeaderY - headerY
1644:                                + lastRowHeight);
1645:                        lastPrintRow.add(contents.fill());
1646:                        contents.releaseWorkingClone();
1647:                    }
1648:                }
1649:
1650:                private void refillLastRow(int xOffset, int availableHeight)
1651:                        throws JRException {
1652:                    removeFilledRows(1);
1653:                    setBackSpanHeaders();
1654:
1655:                    prepareRow(xOffset, availableHeight);
1656:                    fillRow();
1657:
1658:                    rowYs.add(new Integer(((Integer) rowYs.get(rowIdx))
1659:                            .intValue()
1660:                            + preparedRowHeight));
1661:                    ++rowIdx;
1662:                }
1663:
1664:                private boolean prepareContinuingRowHeader(int rowGroup,
1665:                        int availableHeight) throws JRException {
1666:                    HeaderCell cell = spanHeaders[rowGroup];
1667:                    int vSpan = rowIdx + startRowIndex
1668:                            - spanHeadersStart[rowGroup];
1669:
1670:                    if (spanHeadersStart[rowGroup] < startRowIndex)//continuing from the prev page
1671:                    {
1672:                        vSpan += spanHeadersStart[rowGroup] - startRowIndex;
1673:                    }
1674:
1675:                    int headerY = ((Integer) rowYs.get(rowIdx - vSpan))
1676:                            .intValue();
1677:                    int lastHeaderY = ((Integer) rowYs.get(rowIdx)).intValue();
1678:                    int headerHeight = lastHeaderY - headerY;
1679:                    int nextToLastHeaderY = ((Integer) rowYs.get(rowIdx - 1))
1680:                            .intValue();
1681:                    int stretchHeight = nextToLastHeaderY - headerY;
1682:
1683:                    JRFillCrosstabRowGroup group = rowGroups[rowGroup];
1684:                    JRFillCellContents contents = cell.isTotal() ? group
1685:                            .getFillTotalHeader() : group.getFillHeader();
1686:
1687:                    boolean stretchContents = group.getPosition() == JRCellContents.POSITION_Y_STRETCH;
1688:                    int contentsHeight = stretchContents ? headerHeight
1689:                            : contents.getHeight();
1690:
1691:                    int cellAvailableStretch = availableHeight - headerY
1692:                            - contentsHeight;
1693:                    boolean headerOverflow = cellAvailableStretch < 0
1694:                            || headerHeight < contents.getHeight();
1695:                    if (!headerOverflow) {
1696:                        setCountVars(rowIdx + startRowIndex - vSpan, -1);
1697:                        setGroupVariables(rowGroups, cell.getBucketValues());
1698:
1699:                        if (stretchContents) {
1700:                            contents = contents.getTransformedContents(contents
1701:                                    .getWidth(), headerHeight,
1702:                                    JRCellContents.POSITION_X_LEFT,
1703:                                    JRCellContents.POSITION_Y_STRETCH);
1704:                        }
1705:
1706:                        contents = contents
1707:                                .getBoxContents(
1708:                                        false,
1709:                                        false,
1710:                                        rowIdx == vSpan
1711:                                                && (!printColumnHeaders || headerCell == null));
1712:                        contents.getWorkingClone();
1713:
1714:                        contents.evaluate(JRExpression.EVALUATION_DEFAULT);
1715:                        contents.prepare(cellAvailableStretch);
1716:
1717:                        preparedRow.add(contents);
1718:
1719:                        headerOverflow = contents.willOverflow();
1720:
1721:                        if (!headerOverflow) {
1722:                            contents.setX(rowHeadersXOffsets[rowGroup]);
1723:                            contents.setY(headerY + yOffset);
1724:                            contents.setVerticalSpan(vSpan);
1725:
1726:                            int rowHeight = contents.getPrintHeight()
1727:                                    - stretchHeight;
1728:                            if (rowHeight > preparedRowHeight) {
1729:                                preparedRowHeight = rowHeight;
1730:                            }
1731:                        }
1732:                    }
1733:
1734:                    if (headerOverflow) {
1735:                        removeFilledRows(vSpan);
1736:                    }
1737:
1738:                    return headerOverflow;
1739:                }
1740:
1741:                protected void addPrintRow(List printRow) {
1742:                    printRows.add(printRow);
1743:                }
1744:
1745:                protected List getLastPrintRow() {
1746:                    return (List) printRows.get(printRows.size() - 1);
1747:                }
1748:
1749:                protected List getPrintElements() {
1750:                    List prints = new ArrayList();
1751:
1752:                    for (Iterator it = printRows.iterator(); it.hasNext();) {
1753:                        List rowPrints = (List) it.next();
1754:                        prints.addAll(rowPrints);
1755:                    }
1756:
1757:                    return prints;
1758:                }
1759:
1760:                protected void setGroupVariables(JRFillCrosstabGroup[] groups,
1761:                        Bucket[] bucketValues) {
1762:                    for (int i = 0; i < groups.length; i++) {
1763:                        Object value = null;
1764:                        if (bucketValues[i] != null
1765:                                && !bucketValues[i].isTotal()) {
1766:                            value = bucketValues[i].getValue();
1767:                        }
1768:                        groups[i].getFillVariable().setValue(value);
1769:                    }
1770:                }
1771:
1772:                protected void setMeasureVariables(CrosstabCell cell) {
1773:                    MeasureValue[] values = cell.getMesureValues();
1774:                    for (int i = 0; i < measures.length; i++) {
1775:                        Object value = measureValue(values, i);
1776:                        measures[i].getFillVariable().setValue(value);
1777:                    }
1778:
1779:                    MeasureValue[][][] totals = cell.getTotals();
1780:                    for (int row = 0; row <= rowGroups.length; row++) {
1781:                        for (int col = 0; col <= columnGroups.length; col++) {
1782:                            MeasureValue[] vals = totals[row][col];
1783:                            if (retrieveTotal[row][col]) {
1784:                                for (int m = 0; m < measures.length; m++) {
1785:                                    JRFillVariable totalVar = totalVariables[row][col][m];
1786:                                    Object value = measureValue(vals, m);
1787:                                    totalVar.setValue(value);
1788:                                }
1789:                            }
1790:                        }
1791:                    }
1792:                }
1793:
1794:                protected Object measureValue(MeasureValue[] values,
1795:                        int measureIdx) {
1796:                    Object value;
1797:                    if (measures[measureIdx].getPercentageOfType() == JRCrosstabMeasure.PERCENTAGE_TYPE_GRAND_TOTAL) {
1798:                        if (values[measureIdx].isInitialized()) {
1799:                            value = values[measureIdx].getValue();
1800:                        } else {
1801:                            value = measures[measureIdx]
1802:                                    .getPercentageCalculator()
1803:                                    .calculatePercentage(values[measureIdx],
1804:                                            grandTotals[measureIdx]);
1805:                        }
1806:                    } else {
1807:                        value = values[measureIdx].getValue();
1808:                    }
1809:                    return value;
1810:                }
1811:
1812:                protected void resetVariables() {
1813:                    for (int i = 0; i < rowGroups.length; i++) {
1814:                        rowGroups[i].getFillVariable().setValue(null);
1815:                    }
1816:
1817:                    for (int i = 0; i < columnGroups.length; i++) {
1818:                        columnGroups[i].getFillVariable().setValue(null);
1819:                    }
1820:
1821:                    for (int i = 0; i < measures.length; i++) {
1822:                        measures[i].getFillVariable().setValue(null);
1823:                    }
1824:
1825:                    for (int row = 0; row <= rowGroups.length; ++row) {
1826:                        for (int col = 0; col <= columnGroups.length; ++col) {
1827:                            if (retrieveTotal[row][col]) {
1828:                                for (int i = 0; i < measures.length; i++) {
1829:                                    totalVariables[row][col][i].setValue(null);
1830:                                }
1831:                            }
1832:                        }
1833:                    }
1834:                }
1835:            }
1836:
1837:            public int getColumnBreakOffset() {
1838:                return parentCrosstab.getColumnBreakOffset();
1839:            }
1840:
1841:            public boolean isRepeatColumnHeaders() {
1842:                return parentCrosstab.isRepeatColumnHeaders();
1843:            }
1844:
1845:            public boolean isRepeatRowHeaders() {
1846:                return parentCrosstab.isRepeatRowHeaders();
1847:            }
1848:
1849:            public JRCrosstabCell[][] getCells() {
1850:                return crossCells;
1851:            }
1852:
1853:            public JRCellContents getWhenNoDataCell() {
1854:                return whenNoDataCell;
1855:            }
1856:
1857:            public JRCrosstabParameter[] getParameters() {
1858:                return parameters;
1859:            }
1860:
1861:            public JRExpression getParametersMapExpression() {
1862:                return parentCrosstab.getParametersMapExpression();
1863:            }
1864:
1865:            public JRElement getElementByKey(String elementKey) {
1866:                return JRBaseCrosstab.getElementByKey(this , elementKey);
1867:            }
1868:
1869:            public JRCloneable createClone(JRFillCloneFactory factory) {
1870:                //not needed
1871:                return null;
1872:            }
1873:
1874:            public JRCellContents getHeaderCell() {
1875:                return headerCell;
1876:            }
1877:
1878:            public JRVariable[] getVariables() {
1879:                return variables;
1880:            }
1881:
1882:            public byte getRunDirection() {
1883:                return parentCrosstab.getRunDirection();
1884:            }
1885:
1886:            public void setRunDirection(byte direction) {
1887:                // nothing
1888:            }
1889:
1890:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.