1 28 package net.sf.jasperreports.crosstabs.design; 29 30 import java.beans.PropertyChangeEvent ; 31 import java.beans.PropertyChangeListener ; 32 import java.io.IOException ; 33 import java.io.Serializable ; 34 import java.net.URLStreamHandlerFactory ; 35 import java.util.ArrayList ; 36 import java.util.HashMap ; 37 import java.util.Iterator ; 38 import java.util.List ; 39 import java.util.ListIterator ; 40 import java.util.Locale ; 41 import java.util.Map ; 42 import java.util.ResourceBundle ; 43 import java.util.TimeZone ; 44 45 import net.sf.jasperreports.crosstabs.JRCellContents; 46 import net.sf.jasperreports.crosstabs.JRCrosstab; 47 import net.sf.jasperreports.crosstabs.JRCrosstabBucket; 48 import net.sf.jasperreports.crosstabs.JRCrosstabCell; 49 import net.sf.jasperreports.crosstabs.JRCrosstabColumnGroup; 50 import net.sf.jasperreports.crosstabs.JRCrosstabDataset; 51 import net.sf.jasperreports.crosstabs.JRCrosstabGroup; 52 import net.sf.jasperreports.crosstabs.JRCrosstabMeasure; 53 import net.sf.jasperreports.crosstabs.JRCrosstabParameter; 54 import net.sf.jasperreports.crosstabs.JRCrosstabRowGroup; 55 import net.sf.jasperreports.crosstabs.base.JRBaseCrosstab; 56 import net.sf.jasperreports.engine.JRAbstractObjectFactory; 57 import net.sf.jasperreports.engine.JRChild; 58 import net.sf.jasperreports.engine.JRConstants; 59 import net.sf.jasperreports.engine.JRDefaultStyleProvider; 60 import net.sf.jasperreports.engine.JRElement; 61 import net.sf.jasperreports.engine.JRException; 62 import net.sf.jasperreports.engine.JRExpression; 63 import net.sf.jasperreports.engine.JRExpressionCollector; 64 import net.sf.jasperreports.engine.JRParameter; 65 import net.sf.jasperreports.engine.JRVariable; 66 import net.sf.jasperreports.engine.design.JRDesignElement; 67 import net.sf.jasperreports.engine.design.JRDesignVariable; 68 import net.sf.jasperreports.engine.util.FormatFactory; 69 import net.sf.jasperreports.engine.util.JRStyleResolver; 70 import net.sf.jasperreports.engine.xml.JRXmlWriter; 71 72 import org.apache.commons.collections.SequencedHashMap; 73 74 80 public class JRDesignCrosstab extends JRDesignElement implements JRCrosstab 81 { 82 private static final long serialVersionUID = JRConstants.SERIAL_VERSION_UID; 83 84 protected List parametersList; 85 protected Map parametersMap; 86 protected Map variablesList; 87 protected JRExpression parametersMapExpression; 88 protected JRDesignCrosstabDataset dataset; 89 protected List rowGroups; 90 protected List columnGroups; 91 protected List measures; 92 protected Map rowGroupsMap; 93 protected Map columnGroupsMap; 94 protected Map measuresMap; 95 protected int columnBreakOffset = DEFAULT_COLUMN_BREAK_OFFSET; 96 protected boolean repeatColumnHeaders = true; 97 protected boolean repeatRowHeaders = true; 98 protected List cellsList; 99 protected Map cellsMap; 100 protected JRDesignCrosstabCell[][] crossCells; 101 protected JRDesignCellContents whenNoDataCell; 102 protected JRDesignCellContents headerCell; 103 104 105 private class MeasureClassChangeListener implements PropertyChangeListener , Serializable 106 { 107 private static final long serialVersionUID = JRConstants.SERIAL_VERSION_UID; 108 109 public void propertyChange(PropertyChangeEvent evt) 110 { 111 measureClassChanged((JRDesignCrosstabMeasure) evt.getSource(), (String ) evt.getNewValue()); 112 } 113 } 114 115 private PropertyChangeListener measureClassChangeListener = new MeasureClassChangeListener(); 116 117 private static final Object [] BUILT_IN_PARAMETERS = new Object [] { 118 JRParameter.REPORT_PARAMETERS_MAP, java.util.Map .class, 119 JRParameter.REPORT_LOCALE, Locale .class, 120 JRParameter.REPORT_RESOURCE_BUNDLE, ResourceBundle .class, 121 JRParameter.REPORT_TIME_ZONE, TimeZone .class, 122 JRParameter.REPORT_FORMAT_FACTORY, FormatFactory.class, 123 JRParameter.REPORT_CLASS_LOADER, ClassLoader .class, 124 JRParameter.REPORT_URL_HANDLER_FACTORY, URLStreamHandlerFactory .class}; 125 126 private static final Object [] BUILT_IN_VARIABLES = new Object [] { 127 JRCrosstab.VARIABLE_ROW_COUNT, Integer .class, 128 JRCrosstab.VARIABLE_COLUMN_COUNT, Integer .class}; 129 130 131 136 public JRDesignCrosstab(JRDefaultStyleProvider defaultStyleProvider) 137 { 138 super(defaultStyleProvider); 139 140 parametersList = new ArrayList (); 141 parametersMap = new HashMap (); 142 143 rowGroupsMap = new HashMap (); 144 rowGroups = new ArrayList (); 145 columnGroupsMap = new HashMap (); 146 columnGroups = new ArrayList (); 147 measuresMap = new HashMap (); 148 measures = new ArrayList (); 149 150 cellsMap = new HashMap (); 151 cellsList = new ArrayList (); 152 153 addBuiltinParameters(); 154 155 variablesList = new SequencedHashMap(); 156 addBuiltinVariables(); 157 158 dataset = new JRDesignCrosstabDataset(); 159 } 160 161 private void addBuiltinParameters() 162 { 163 for (int i = 0; i < BUILT_IN_PARAMETERS.length; i++) 164 { 165 JRDesignCrosstabParameter parameter = new JRDesignCrosstabParameter(); 166 parameter.setName((String ) BUILT_IN_PARAMETERS[i++]); 167 parameter.setValueClass((Class ) BUILT_IN_PARAMETERS[i]); 168 parameter.setSystemDefined(true); 169 try 170 { 171 addParameter(parameter); 172 } 173 catch (JRException e) 174 { 175 } 177 } 178 } 179 180 private void addBuiltinVariables() 181 { 182 for (int i = 0; i < BUILT_IN_VARIABLES.length; ++i) 183 { 184 JRDesignVariable variable = new JRDesignVariable(); 185 variable.setName((String ) BUILT_IN_VARIABLES[i]); 186 variable.setValueClass((Class ) BUILT_IN_VARIABLES[++i]); 187 variable.setCalculation(JRVariable.CALCULATION_SYSTEM); 188 variable.setSystemDefined(true); 189 addVariable(variable); 190 } 191 } 192 193 196 public JRDesignCrosstab() 197 { 198 this(null); 199 } 200 201 202 205 public int getId() 206 { 207 return 0; 208 } 209 210 public JRCrosstabDataset getDataset() 211 { 212 return dataset; 213 } 214 215 216 221 public JRDesignCrosstabDataset getDesignDataset() 222 { 223 return dataset; 224 } 225 226 public JRCrosstabRowGroup[] getRowGroups() 227 { 228 JRCrosstabRowGroup[] groups = new JRCrosstabRowGroup[rowGroups.size()]; 229 rowGroups.toArray(groups); 230 return groups; 231 } 232 233 public JRCrosstabColumnGroup[] getColumnGroups() 234 { 235 JRCrosstabColumnGroup[] groups = new JRCrosstabColumnGroup[columnGroups.size()]; 236 columnGroups.toArray(groups); 237 return groups; 238 } 239 240 public JRCrosstabMeasure[] getMeasures() 241 { 242 JRCrosstabMeasure[] measureArray = new JRCrosstabMeasure[measures.size()]; 243 measures.toArray(measureArray); 244 return measureArray; 245 } 246 247 public void collectExpressions(JRExpressionCollector collector) 248 { 249 collector.collect(this); 250 } 251 252 public JRChild getCopy(JRAbstractObjectFactory factory) 253 { 254 return factory.getCrosstab(this); 255 } 256 257 public void writeXml(JRXmlWriter writer) throws IOException 258 { 259 writer.writeCrosstab(this); 260 } 261 262 263 269 public void setDataset(JRDesignCrosstabDataset dataset) 270 { 271 this.dataset = dataset; 272 } 273 274 275 284 public void addRowGroup(JRDesignCrosstabRowGroup group) throws JRException 285 { 286 String groupName = group.getName(); 287 if (rowGroupsMap.containsKey(groupName) || 288 columnGroupsMap.containsKey(groupName) || 289 measuresMap.containsKey(groupName)) 290 { 291 throw new JRException("A group or measure having the same name already exists in the crosstab."); 292 } 293 294 rowGroupsMap.put(groupName, new Integer (rowGroups.size())); 295 rowGroups.add(group); 296 297 addRowGroupVars(group); 298 } 299 300 301 protected void addRowGroupVars(JRDesignCrosstabRowGroup rowGroup) 302 { 303 addVariable(rowGroup.getVariable()); 304 305 for (Iterator measureIt = measures.iterator(); measureIt.hasNext();) 306 { 307 JRCrosstabMeasure measure = (JRCrosstabMeasure) measureIt.next(); 308 addTotalVar(measure, rowGroup, null); 309 310 for (Iterator colIt = columnGroups.iterator(); colIt.hasNext();) 311 { 312 JRCrosstabColumnGroup colGroup = (JRCrosstabColumnGroup) colIt.next(); 313 addTotalVar(measure, rowGroup, colGroup); 314 } 315 } 316 } 317 318 319 328 public void addColumnGroup(JRDesignCrosstabColumnGroup group) throws JRException 329 { 330 String groupName = group.getName(); 331 if (rowGroupsMap.containsKey(groupName) || 332 columnGroupsMap.containsKey(groupName) || 333 measuresMap.containsKey(groupName)) 334 { 335 throw new JRException("A group or measure having the same name already exists in the crosstab."); 336 } 337 338 columnGroupsMap.put(groupName, new Integer (columnGroups.size())); 339 columnGroups.add(group); 340 341 addColGroupVars(group); 342 } 343 344 345 protected void addColGroupVars(JRDesignCrosstabColumnGroup colGroup) 346 { 347 addVariable(colGroup.getVariable()); 348 349 for (Iterator measureIt = measures.iterator(); measureIt.hasNext();) 350 { 351 JRCrosstabMeasure measure = (JRCrosstabMeasure) measureIt.next(); 352 addTotalVar(measure, null, colGroup); 353 354 for (Iterator rowIt = rowGroups.iterator(); rowIt.hasNext();) 355 { 356 JRCrosstabRowGroup rowGroup = (JRCrosstabRowGroup) rowIt.next(); 357 addTotalVar(measure, rowGroup, colGroup); 358 } 359 } 360 } 361 362 369 public void addMeasure(JRDesignCrosstabMeasure measure) throws JRException 370 { 371 String measureName = measure.getName(); 372 if (rowGroupsMap.containsKey(measureName) || 373 columnGroupsMap.containsKey(measureName) || 374 measuresMap.containsKey(measureName)) 375 { 376 throw new JRException("A group or measure having the same name already exists in the crosstab."); 377 } 378 379 measure.addPropertyChangeListener(JRDesignCrosstabMeasure.PROPERTY_VALUE_CLASS, measureClassChangeListener); 380 381 measuresMap.put(measureName, new Integer (measures.size())); 382 measures.add(measure); 383 384 addMeasureVars(measure); 385 } 386 387 protected void addMeasureVars(JRDesignCrosstabMeasure measure) 388 { 389 addVariable(measure.getVariable()); 390 391 for (Iterator colIt = columnGroups.iterator(); colIt.hasNext();) 392 { 393 JRCrosstabColumnGroup colGroup = (JRCrosstabColumnGroup) colIt.next(); 394 addTotalVar(measure, null, colGroup); 395 } 396 397 for (Iterator rowIt = rowGroups.iterator(); rowIt.hasNext();) 398 { 399 JRCrosstabRowGroup rowGroup = (JRCrosstabRowGroup) rowIt.next(); 400 addTotalVar(measure, rowGroup, null); 401 402 for (Iterator colIt = columnGroups.iterator(); colIt.hasNext();) 403 { 404 JRCrosstabColumnGroup colGroup = (JRCrosstabColumnGroup) colIt.next(); 405 addTotalVar(measure, rowGroup, colGroup); 406 } 407 } 408 } 409 410 411 protected void addTotalVar(JRCrosstabMeasure measure, JRCrosstabRowGroup rowGroup, JRCrosstabColumnGroup colGroup) 412 { 413 JRDesignVariable var = new JRDesignVariable(); 414 var.setCalculation(JRVariable.CALCULATION_SYSTEM); 415 var.setSystemDefined(true); 416 var.setName(getTotalVariableName(measure, rowGroup, colGroup)); 417 var.setValueClassName(measure.getValueClassName()); 418 addVariable(var); 419 } 420 421 422 protected void removeTotalVar(JRCrosstabMeasure measure, JRCrosstabRowGroup rowGroup, JRCrosstabColumnGroup colGroup) 423 { 424 String varName = getTotalVariableName(measure, rowGroup, colGroup); 425 removeVariable(varName); 426 } 427 428 429 public static String getTotalVariableName(JRCrosstabMeasure measure, JRCrosstabRowGroup rowGroup, JRCrosstabColumnGroup colGroup) 430 { 431 StringBuffer name = new StringBuffer (); 432 name.append(measure.getName()); 433 if (rowGroup != null) 434 { 435 name.append('_'); 436 name.append(rowGroup.getName()); 437 } 438 if (colGroup != null) 439 { 440 name.append('_'); 441 name.append(colGroup.getName()); 442 } 443 name.append("_ALL"); 444 return name.toString(); 445 } 446 447 448 454 public JRCrosstabRowGroup removeRowGroup(String groupName) 455 { 456 JRCrosstabRowGroup removed = null; 457 458 Integer idx = (Integer ) rowGroupsMap.remove(groupName); 459 if (idx != null) 460 { 461 removed = (JRCrosstabRowGroup) rowGroups.remove(idx.intValue()); 462 463 for (ListIterator it = rowGroups.listIterator(idx.intValue()); it.hasNext();) 464 { 465 JRCrosstabRowGroup group = (JRCrosstabRowGroup) it.next(); 466 rowGroupsMap.put(group.getName(), new Integer (it.previousIndex())); 467 } 468 469 for (Iterator it = cellsList.iterator(); it.hasNext();) 470 { 471 JRCrosstabCell cell = (JRCrosstabCell) it.next(); 472 String rowTotalGroup = cell.getRowTotalGroup(); 473 if (rowTotalGroup != null && rowTotalGroup.equals(groupName)) 474 { 475 it.remove(); 476 cellsMap.remove(new Pair(rowTotalGroup, cell.getColumnTotalGroup())); 477 } 478 } 479 480 removeRowGroupVars(removed); 481 } 482 483 return removed; 484 } 485 486 protected void removeRowGroupVars(JRCrosstabRowGroup rowGroup) 487 { 488 removeVariable(rowGroup.getVariable()); 489 490 for (Iterator measureIt = measures.iterator(); measureIt.hasNext();) 491 { 492 JRCrosstabMeasure measure = (JRCrosstabMeasure) measureIt.next(); 493 removeTotalVar(measure, rowGroup, null); 494 495 for (Iterator colIt = columnGroups.iterator(); colIt.hasNext();) 496 { 497 JRCrosstabColumnGroup colGroup = (JRCrosstabColumnGroup) colIt.next(); 498 removeTotalVar(measure, rowGroup, colGroup); 499 } 500 } 501 } 502 503 504 510 public JRCrosstabRowGroup removeRowGroup(JRCrosstabRowGroup group) 511 { 512 return removeRowGroup(group.getName()); 513 } 514 515 516 522 public JRCrosstabColumnGroup removeColumnGroup(String groupName) 523 { 524 JRCrosstabColumnGroup removed = null; 525 526 Integer idx = (Integer ) columnGroupsMap.remove(groupName); 527 if (idx != null) 528 { 529 removed = (JRCrosstabColumnGroup) columnGroups.remove(idx.intValue()); 530 531 for (ListIterator it = columnGroups.listIterator(idx.intValue()); it.hasNext();) 532 { 533 JRCrosstabColumnGroup group = (JRCrosstabColumnGroup) it.next(); 534 columnGroupsMap.put(group.getName(), new Integer (it.previousIndex())); 535 } 536 537 for (Iterator it = cellsList.iterator(); it.hasNext();) 538 { 539 JRCrosstabCell cell = (JRCrosstabCell) it.next(); 540 String columnTotalGroup = cell.getColumnTotalGroup(); 541 if (columnTotalGroup != null && columnTotalGroup.equals(groupName)) 542 { 543 it.remove(); 544 cellsMap.remove(new Pair(cell.getRowTotalGroup(), columnTotalGroup)); 545 } 546 } 547 548 removeColGroupVars(removed); 549 } 550 551 return removed; 552 } 553 554 555 protected void removeColGroupVars(JRCrosstabColumnGroup colGroup) 556 { 557 removeVariable(colGroup.getVariable()); 558 559 for (Iterator measureIt = measures.iterator(); measureIt.hasNext();) 560 { 561 JRCrosstabMeasure measure = (JRCrosstabMeasure) measureIt.next(); 562 removeTotalVar(measure, null, colGroup); 563 564 for (Iterator rowIt = rowGroups.iterator(); rowIt.hasNext();) 565 { 566 JRCrosstabRowGroup rowGroup = (JRCrosstabRowGroup) rowIt.next(); 567 removeTotalVar(measure, rowGroup, colGroup); 568 } 569 } 570 } 571 572 573 579 public JRCrosstabColumnGroup removeColumnGroup(JRCrosstabColumnGroup group) 580 { 581 return removeColumnGroup(group.getName()); 582 } 583 584 585 591 public JRCrosstabMeasure removeMeasure(String measureName) 592 { 593 JRDesignCrosstabMeasure removed = null; 594 595 Integer idx = (Integer ) measuresMap.remove(measureName); 596 if (idx != null) 597 { 598 removed = (JRDesignCrosstabMeasure) measures.remove(idx.intValue()); 599 600 for (ListIterator it = measures.listIterator(idx.intValue()); it.hasNext();) 601 { 602 JRCrosstabMeasure group = (JRCrosstabMeasure) it.next(); 603 measuresMap.put(group.getName(), new Integer (it.previousIndex())); 604 } 605 606 removeMeasureVars(removed); 607 608 removed.removePropertyChangeListener(JRDesignCrosstabMeasure.PROPERTY_VALUE_CLASS, measureClassChangeListener); 609 } 610 611 return removed; 612 } 613 614 protected void removeMeasureVars(JRDesignCrosstabMeasure measure) 615 { 616 removeVariable(measure.getVariable()); 617 618 for (Iterator colIt = columnGroups.iterator(); colIt.hasNext();) 619 { 620 JRCrosstabColumnGroup colGroup = (JRCrosstabColumnGroup) colIt.next(); 621 removeTotalVar(measure, null, colGroup); 622 } 623 624 for (Iterator rowIt = rowGroups.iterator(); rowIt.hasNext();) 625 { 626 JRCrosstabRowGroup rowGroup = (JRCrosstabRowGroup) rowIt.next(); 627 removeTotalVar(measure, rowGroup, null); 628 629 for (Iterator colIt = columnGroups.iterator(); colIt.hasNext();) 630 { 631 JRCrosstabColumnGroup colGroup = (JRCrosstabColumnGroup) colIt.next(); 632 removeTotalVar(measure, rowGroup, colGroup); 633 } 634 } 635 } 636 637 638 644 public JRCrosstabMeasure removeMeasure(JRCrosstabMeasure measure) 645 { 646 return removeMeasure(measure.getName()); 647 } 648 649 public boolean isRepeatColumnHeaders() 650 { 651 return repeatColumnHeaders; 652 } 653 654 655 661 public void setRepeatColumnHeaders(boolean repeatColumnHeaders) 662 { 663 this.repeatColumnHeaders = repeatColumnHeaders; 664 } 665 666 public boolean isRepeatRowHeaders() 667 { 668 return repeatRowHeaders; 669 } 670 671 672 678 public void setRepeatRowHeaders(boolean repeatRowHeaders) 679 { 680 this.repeatRowHeaders = repeatRowHeaders; 681 } 682 683 public JRCrosstabCell[][] getCells() 684 { 685 return crossCells; 686 } 687 688 689 695 public List getCellsList() 696 { 697 return cellsList; 698 } 699 700 701 708 public void addCell(JRDesignCrosstabCell cell) throws JRException 709 { 710 String rowTotalGroup = cell.getRowTotalGroup(); 711 if (rowTotalGroup != null && !rowGroupsMap.containsKey(rowTotalGroup)) 712 { 713 throw new JRException("Row group " + rowTotalGroup + " does not exist."); 714 } 715 716 String columnTotalGroup = cell.getColumnTotalGroup(); 717 if (columnTotalGroup != null && !columnGroupsMap.containsKey(columnTotalGroup)) 718 { 719 throw new JRException("Row group " + columnTotalGroup + " does not exist."); 720 } 721 722 Object cellKey = new Pair(rowTotalGroup, columnTotalGroup); 723 if (cellsMap.containsKey(cellKey)) 724 { 725 throw new JRException("Duplicate cell in crosstab."); 726 } 727 728 cellsMap.put(cellKey, cell); 729 cellsList.add(cell); 730 } 731 732 733 740 public JRCrosstabCell removeCell(String rowTotalGroup, String columnTotalGroup) 741 { 742 Object cellKey = new Pair(rowTotalGroup, columnTotalGroup); 743 744 JRCrosstabCell cell = (JRCrosstabCell) cellsMap.remove(cellKey); 745 if (cell != null) 746 { 747 cellsList.remove(cell); 748 } 749 750 return cell; 751 } 752 753 754 760 public JRCrosstabCell removeCell(JRCrosstabCell cell) 761 { 762 Object cellKey = new Pair(cell.getRowTotalGroup(), cell.getColumnTotalGroup()); 763 JRCrosstabCell removedCell = (JRCrosstabCell) cellsMap.remove(cellKey); 764 if (removedCell != null) 765 { 766 cellsList.remove(removedCell); 767 } 768 769 return removedCell; 770 } 771 772 private static class Pair implements Serializable 773 { 774 private static final long serialVersionUID = 1L; 775 776 final Object o1; 777 final Object o2; 778 779 Pair(Object o1, Object o2) 780 { 781 this.o1 = o1; 782 this.o2 = o2; 783 } 784 785 public boolean equals(Object o) 786 { 787 if (o == this) 788 { 789 return true; 790 } 791 792 if (o == null || !(o instanceof Pair)) 793 { 794 return false; 795 } 796 797 Pair p = (Pair) o; 798 799 return (p.o1 == null ? o1 == null : (o1 != null && p.o1.equals(o1))) && 800 (p.o2 == null ? o2 == null : (o2 != null && p.o2.equals(o2))); 801 } 802 803 public int hashCode() 804 { 805 int hash = o1 == null ? 0 : o1.hashCode(); 806 807 hash *= 31; 808 809 hash += o2 == null ? 0 : o2.hashCode(); 810 811 return hash; 812 } 813 } 814 815 public JRCrosstabParameter[] getParameters() 816 { 817 JRCrosstabParameter[] parameters = new JRCrosstabParameter[parametersList.size()]; 818 parametersList.toArray(parameters); 819 return parameters; 820 } 821 822 823 828 public List getParametersList() 829 { 830 return parametersList; 831 } 832 833 834 839 public Map getParametersMap() 840 { 841 return parametersMap; 842 } 843 844 public JRExpression getParametersMapExpression() 845 { 846 return parametersMapExpression; 847 } 848 849 850 857 public void addParameter(JRCrosstabParameter parameter) throws JRException 858 { 859 if (parametersMap.containsKey(parameter.getName())) 860 { 861 if (parametersMap.containsKey(parameter.getName())) 862 { 863 throw new JRException("Duplicate declaration of parameter : " + parameter.getName()); 864 } 865 } 866 867 parametersMap.put(parameter.getName(), parameter); 868 parametersList.add(parameter); 869 } 870 871 872 878 public JRCrosstabParameter removeParameter(String parameterName) 879 { 880 JRCrosstabParameter param = (JRCrosstabParameter) parametersMap.remove(parameterName); 881 882 if (param != null) 883 { 884 parametersList.remove(param); 885 } 886 887 return param; 888 } 889 890 891 897 public JRCrosstabParameter removeParameter(JRCrosstabParameter parameter) 898 { 899 return removeParameter(parameter.getName()); 900 } 901 902 903 909 public void setParametersMapExpression(JRExpression expression) 910 { 911 this.parametersMapExpression = expression; 912 } 913 914 915 920 public Map getVariablesMap() 921 { 922 JRVariable[] variables = getVariables(); 923 Map variablesMap = new HashMap (); 924 925 for (int i = 0; i < variables.length; i++) 926 { 927 variablesMap.put(variables[i].getName(), variables[i]); 928 } 929 930 return variablesMap; 931 } 932 933 934 943 public JRVariable[] getVariables() 944 { 945 JRVariable[] variables = new JRVariable[variablesList.size()]; 946 variablesList.values().toArray(variables); 947 return variables; 948 } 949 950 951 public int getColumnBreakOffset() 952 { 953 return columnBreakOffset; 954 } 955 956 957 963 public void setColumnBreakOffset(int columnBreakOffset) 964 { 965 this.columnBreakOffset = columnBreakOffset; 966 } 967 968 969 972 public void preprocess() 973 { 974 setGroupVariablesClass(rowGroups); 975 setGroupVariablesClass(columnGroups); 976 977 calculateSizes(); 978 } 979 980 981 protected void setGroupVariablesClass(List groups) 982 { 983 for (Iterator it = groups.iterator(); it.hasNext();) 984 { 985 JRDesignCrosstabGroup group = (JRDesignCrosstabGroup) it.next(); 986 JRCrosstabBucket bucket = group.getBucket(); 987 if (bucket != null) 988 { 989 JRExpression expression = bucket.getExpression(); 990 if (expression != null) 991 { 992 group.designVariable.setValueClassName(expression.getValueClassName()); 993 } 994 } 995 } 996 } 997 998 protected void calculateSizes() 999 { 1000 setWhenNoDataCellSize(); 1001 1002 createCellMatrix(); 1003 1004 int rowHeadersWidth = calculateRowHeadersSizes(); 1005 int colHeadersHeight = calculateColumnHeadersSizes(); 1006 1007 if (headerCell != null) 1008 { 1009 headerCell.setWidth(rowHeadersWidth); 1010 headerCell.setHeight(colHeadersHeight); 1011 } 1012 } 1013 1014 protected void setWhenNoDataCellSize() 1015 { 1016 if (whenNoDataCell != null) 1017 { 1018 whenNoDataCell.setWidth(getWidth()); 1019 whenNoDataCell.setHeight(getHeight()); 1020 } 1021 } 1022 1023 protected void createCellMatrix() 1024 { 1025 crossCells = new JRDesignCrosstabCell[rowGroups.size() + 1][columnGroups.size() + 1]; 1026 for (Iterator it = cellsList.iterator(); it.hasNext();) 1027 { 1028 JRDesignCrosstabCell crosstabCell = (JRDesignCrosstabCell) it.next(); 1029 JRDesignCellContents contents = (JRDesignCellContents) crosstabCell.getContents(); 1030 1031 String rowTotalGroup = crosstabCell.getRowTotalGroup(); 1032 int rowGroupIndex = rowTotalGroup == null ? rowGroupIndex = rowGroups.size() : ((Integer ) rowGroupsMap.get(rowTotalGroup)).intValue(); 1033 1034 Integer cellWidth = crosstabCell.getWidth(); 1035 if (cellWidth != null) 1036 { 1037 contents.setWidth(cellWidth.intValue()); 1038 } 1039 1040 String columnTotalGroup = crosstabCell.getColumnTotalGroup(); 1041 int columnGroupIndex = columnTotalGroup == null ? columnGroupIndex = columnGroups.size() : ((Integer ) columnGroupsMap.get(columnTotalGroup)).intValue(); 1042 Integer cellHeight = crosstabCell.getHeight(); 1043 if (cellHeight != null) 1044 { 1045 contents.setHeight(cellHeight.intValue()); 1046 } 1047 1048 crossCells[rowGroupIndex][columnGroupIndex] = crosstabCell; 1049 } 1050 1051 inheritCells(); 1052 } 1053 1054 protected JRDesignCrosstabRowGroup getRowGroup(int rowGroupIndex) 1055 { 1056 return (JRDesignCrosstabRowGroup) rowGroups.get(rowGroupIndex); 1057 } 1058 1059 protected JRDesignCrosstabColumnGroup getColumnGroup(int columnGroupIndex) 1060 { 1061 return (JRDesignCrosstabColumnGroup) columnGroups.get(columnGroupIndex); 1062 } 1063 1064 protected void inheritCells() 1065 { 1066 for (int i = rowGroups.size(); i >= 0 ; --i) 1067 { 1068 for (int j = columnGroups.size(); j >= 0 ; --j) 1069 { 1070 boolean used = (i == rowGroups.size() || getRowGroup(i).hasTotal()) && 1071 (j == columnGroups.size() || getColumnGroup(j).hasTotal()); 1072 1073 if (used) 1074 { 1075 if (crossCells[i][j] == null) 1076 { 1077 inheritCell(i, j); 1078 1079 if (crossCells[i][j] == null) 1080 { 1081 crossCells[i][j] = emptyCell(i, j); 1082 inheritCellSize(i, j); 1083 } 1084 } 1085 else 1086 { 1087 inheritCellSize(i, j); 1088 } 1089 } 1090 else 1091 { 1092 crossCells[i][j] = null; 1093 } 1094 } 1095 } 1096 } 1097 1098 private JRDesignCrosstabCell emptyCell(int i, int j) 1099 { 1100 JRDesignCrosstabCell emptyCell = new JRDesignCrosstabCell(); 1101 if (i < rowGroups.size()) 1102 { 1103 emptyCell.setRowTotalGroup(((JRCrosstabRowGroup) rowGroups.get(i)).getName()); 1104 } 1105 if (j < columnGroups.size()) 1106 { 1107 emptyCell.setColumnTotalGroup(((JRCrosstabColumnGroup) columnGroups.get(j)).getName()); 1108 } 1109 return emptyCell; 1110 } 1111 1112 protected void inheritCellSize(int i, int j) 1113 { 1114 JRDesignCrosstabCell cell = crossCells[i][j]; 1115 1116 JRDesignCellContents contents = (JRDesignCellContents) cell.getContents(); 1117 1118 if (contents.getWidth() == JRCellContents.NOT_CALCULATED) 1119 { 1120 if (i < rowGroups.size()) 1121 { 1122 JRDesignCrosstabCell rowCell = crossCells[rowGroups.size()][j]; 1123 if (rowCell != null) 1124 { 1125 contents.setWidth(rowCell.getContents().getWidth()); 1126 } 1127 } 1128 else 1129 { 1130 for (int k = j + 1; k <= columnGroups.size(); ++k) 1131 { 1132 if (crossCells[i][k] != null) 1133 { 1134 contents.setWidth(crossCells[i][k].getContents().getWidth()); 1135 break; 1136 } 1137 } 1138 } 1139 } 1140 1141 if (contents.getHeight() == JRCellContents.NOT_CALCULATED) 1142 { 1143 if (j < columnGroups.size()) 1144 { 1145 JRDesignCrosstabCell colCell = crossCells[i][columnGroups.size()]; 1146 if (colCell != null) 1147 { 1148 contents.setHeight(colCell.getContents().getHeight()); 1149 } 1150 } 1151 else 1152 { 1153 for (int k = i + 1; k <= rowGroups.size(); ++k) 1154 { 1155 if (crossCells[k][j] != null) 1156 { 1157 contents.setHeight(crossCells[k][j].getContents().getHeight()); 1158 } 1159 } 1160 } 1161 } 1162 } 1163 1164 1165 protected void inheritCell(int i, int j) 1166 { 1167 JRDesignCrosstabCell inheritedCell = null; 1168 1169 if (j < columnGroups.size()) 1170 { 1171 JRDesignCrosstabCell colCell = crossCells[rowGroups.size()][j]; 1172 JRDesignCellContents colContents = colCell == null ? null : (JRDesignCellContents) colCell.getContents(); 1173 for (int k = j + 1; inheritedCell == null && k <= columnGroups.size(); ++k) 1174 { 1175 JRDesignCrosstabCell cell = crossCells[i][k]; 1176 if (cell != null) 1177 { 1178 JRDesignCellContents contents = (JRDesignCellContents) cell.getContents(); 1179 if (colContents == null || contents.getWidth() == colContents.getWidth()) 1180 { 1181 inheritedCell = cell; 1182 } 1183 } 1184 } 1185 } 1186 1187 if (inheritedCell == null && i < rowGroups.size()) 1188 { 1189 JRDesignCrosstabCell rowCell = crossCells[i][columnGroups.size()]; 1190 JRDesignCellContents rowContents = rowCell == null ? null : (JRDesignCellContents) rowCell.getContents(); 1191 for (int k = i + 1; inheritedCell == null && k <= rowGroups.size(); ++k) 1192 { 1193 JRDesignCrosstabCell cell = crossCells[k][j]; 1194 if (cell != null) 1195 { 1196 JRDesignCellContents contents = (JRDesignCellContents) cell.getContents(); 1197 if (rowContents == null || contents.getHeight() == rowContents.getHeight()) 1198 { 1199 inheritedCell = cell; 1200 } 1201 } 1202 } 1203 } 1204 1205 crossCells[i][j] = inheritedCell; 1206 } 1207 1208 protected int calculateRowHeadersSizes() 1209 { 1210 int widthSum = 0; 1211 for (int i = rowGroups.size() - 1, heightSum = 0; i >= 0; --i) 1212 { 1213 JRDesignCrosstabRowGroup group = (JRDesignCrosstabRowGroup) rowGroups.get(i); 1214 1215 widthSum += group.getWidth(); 1216 1217 JRDesignCrosstabCell cell = crossCells[i + 1][columnGroups.size()]; 1218 if (cell != null) 1219 { 1220 heightSum += cell.getContents().getHeight(); 1221 } 1222 1223 JRDesignCellContents header = (JRDesignCellContents) group.getHeader(); 1224 header.setHeight(heightSum); 1225 header.setWidth(group.getWidth()); 1226 1227 if (group.hasTotal()) 1228 { 1229 JRDesignCellContents totalHeader = (JRDesignCellContents) group.getTotalHeader(); 1230 totalHeader.setWidth(widthSum); 1231 JRDesignCrosstabCell totalCell = crossCells[i][columnGroups.size()]; 1232 if (totalCell != null) 1233 { 1234 totalHeader.setHeight(totalCell.getContents().getHeight()); 1235 } 1236 } 1237 } 1238 return widthSum; 1239 } 1240 1241 protected int calculateColumnHeadersSizes() 1242 { 1243 int heightSum = 0; 1244 for (int i = columnGroups.size() - 1, widthSum = 0; i >= 0; --i) 1245 { 1246 JRDesignCrosstabColumnGroup group = (JRDesignCrosstabColumnGroup) columnGroups.get(i); 1247 1248 heightSum += group.getHeight(); 1249 JRDesignCrosstabCell cell = crossCells[rowGroups.size()][i + 1]; 1250 if (cell != null) 1251 { 1252 widthSum += cell.getContents().getWidth(); 1253 } 1254 1255 JRDesignCellContents header = (JRDesignCellContents) group.getHeader(); 1256 header.setHeight(group.getHeight()); 1257 header.setWidth(widthSum); 1258 1259 if (group.hasTotal()) 1260 { 1261 JRDesignCellContents totalHeader = (JRDesignCellContents) group.getTotalHeader(); 1262 totalHeader.setHeight(heightSum); 1263 JRDesignCrosstabCell totalCell = crossCells[rowGroups.size()][i]; 1264 if (totalCell != null) 1265 { 1266 totalHeader.setWidth(totalCell.getContents().getWidth()); 1267 } 1268 } 1269 } 1270 return heightSum; 1271 } 1272 1273 public JRCellContents getWhenNoDataCell() 1274 { 1275 return whenNoDataCell; 1276 } 1277 1278 1279 1285 public void setWhenNoDataCell(JRDesignCellContents whenNoDataCell) 1286 { 1287 this.whenNoDataCell = whenNoDataCell; 1288 } 1289 1290 1291 public JRElement getElementByKey(String elementKey) 1292 { 1293 return JRBaseCrosstab.getElementByKey(this, elementKey); 1294 } 1295 1296 1297 public byte getMode() 1298 { 1299 return JRStyleResolver.getMode(this, MODE_TRANSPARENT); 1300 } 1301 1302 public JRCellContents getHeaderCell() 1303 { 1304 return headerCell; 1305 } 1306 1307 1308 1314 public void setHeaderCell(JRDesignCellContents headerCell) 1315 { 1316 this.headerCell = headerCell; 1317 } 1318 1319 1320 protected void measureClassChanged(JRDesignCrosstabMeasure measure, String valueClassName) 1321 { 1322 for (Iterator colIt = columnGroups.iterator(); colIt.hasNext();) 1323 { 1324 JRCrosstabColumnGroup colGroup = (JRCrosstabColumnGroup) colIt.next(); 1325 setTotalVarClass(measure, null, colGroup, valueClassName); 1326 } 1327 1328 for (Iterator rowIt = rowGroups.iterator(); rowIt.hasNext();) 1329 { 1330 JRCrosstabRowGroup rowGroup = (JRCrosstabRowGroup) rowIt.next(); 1331 setTotalVarClass(measure, rowGroup, null, valueClassName); 1332 1333 for (Iterator colIt = columnGroups.iterator(); colIt.hasNext();) 1334 { 1335 JRCrosstabColumnGroup colGroup = (JRCrosstabColumnGroup) colIt.next(); 1336 setTotalVarClass(measure, rowGroup, colGroup, valueClassName); 1337 } 1338 } 1339 } 1340 1341 protected void setTotalVarClass(JRCrosstabMeasure measure, JRCrosstabRowGroup rowGroup, JRCrosstabColumnGroup colGroup, String valueClassName) 1342 { 1343 JRDesignVariable variable = getVariable(getTotalVariableName(measure, rowGroup, colGroup)); 1344 variable.setValueClassName(valueClassName); 1345 } 1346 1347 private void addVariable(JRVariable variable) 1348 { 1349 variablesList.put(variable.getName(), variable); 1350 } 1351 1352 private void removeVariable(JRVariable variable) 1353 { 1354 removeVariable(variable.getName()); 1355 } 1356 1357 private void removeVariable(String varName) 1358 { 1359 variablesList.remove(varName); 1360 } 1361 1362 private JRDesignVariable getVariable(String varName) 1363 { 1364 return (JRDesignVariable) variablesList.get(varName); 1365 } 1366} 1367 | Popular Tags |