1 28 package net.sf.jasperreports.engine.design; 29 30 import java.util.ArrayList ; 31 import java.util.Arrays ; 32 import java.util.Collection ; 33 import java.util.Comparator ; 34 import java.util.HashMap ; 35 import java.util.Iterator ; 36 import java.util.List ; 37 import java.util.Map ; 38 39 import net.sf.jasperreports.charts.JRCategoryDataset; 40 import net.sf.jasperreports.charts.JRCategorySeries; 41 import net.sf.jasperreports.charts.JRHighLowDataset; 42 import net.sf.jasperreports.charts.JRPieDataset; 43 import net.sf.jasperreports.charts.JRTimePeriodDataset; 44 import net.sf.jasperreports.charts.JRTimePeriodSeries; 45 import net.sf.jasperreports.charts.JRTimeSeries; 46 import net.sf.jasperreports.charts.JRTimeSeriesDataset; 47 import net.sf.jasperreports.charts.JRValueDataset; 48 import net.sf.jasperreports.charts.JRXyDataset; 49 import net.sf.jasperreports.charts.JRXySeries; 50 import net.sf.jasperreports.charts.JRXyzDataset; 51 import net.sf.jasperreports.charts.JRXyzSeries; 52 import net.sf.jasperreports.crosstabs.JRCellContents; 53 import net.sf.jasperreports.crosstabs.JRCrosstab; 54 import net.sf.jasperreports.crosstabs.JRCrosstabBucket; 55 import net.sf.jasperreports.crosstabs.JRCrosstabCell; 56 import net.sf.jasperreports.crosstabs.JRCrosstabColumnGroup; 57 import net.sf.jasperreports.crosstabs.JRCrosstabDataset; 58 import net.sf.jasperreports.crosstabs.JRCrosstabGroup; 59 import net.sf.jasperreports.crosstabs.JRCrosstabMeasure; 60 import net.sf.jasperreports.crosstabs.JRCrosstabParameter; 61 import net.sf.jasperreports.crosstabs.JRCrosstabRowGroup; 62 import net.sf.jasperreports.crosstabs.design.JRDesignCrosstab; 63 import net.sf.jasperreports.crosstabs.fill.JRPercentageCalculator; 64 import net.sf.jasperreports.crosstabs.fill.JRPercentageCalculatorFactory; 65 import net.sf.jasperreports.engine.JRAnchor; 66 import net.sf.jasperreports.engine.JRBand; 67 import net.sf.jasperreports.engine.JRBox; 68 import net.sf.jasperreports.engine.JRChart; 69 import net.sf.jasperreports.engine.JRChartDataset; 70 import net.sf.jasperreports.engine.JRDataset; 71 import net.sf.jasperreports.engine.JRDatasetParameter; 72 import net.sf.jasperreports.engine.JRDatasetRun; 73 import net.sf.jasperreports.engine.JRElement; 74 import net.sf.jasperreports.engine.JRElementDataset; 75 import net.sf.jasperreports.engine.JRException; 76 import net.sf.jasperreports.engine.JRExpression; 77 import net.sf.jasperreports.engine.JRExpressionChunk; 78 import net.sf.jasperreports.engine.JRExpressionCollector; 79 import net.sf.jasperreports.engine.JRField; 80 import net.sf.jasperreports.engine.JRFont; 81 import net.sf.jasperreports.engine.JRFrame; 82 import net.sf.jasperreports.engine.JRGroup; 83 import net.sf.jasperreports.engine.JRHyperlink; 84 import net.sf.jasperreports.engine.JRHyperlinkParameter; 85 import net.sf.jasperreports.engine.JRImage; 86 import net.sf.jasperreports.engine.JRParameter; 87 import net.sf.jasperreports.engine.JRQuery; 88 import net.sf.jasperreports.engine.JRQueryChunk; 89 import net.sf.jasperreports.engine.JRReportFont; 90 import net.sf.jasperreports.engine.JRSortField; 91 import net.sf.jasperreports.engine.JRStaticText; 92 import net.sf.jasperreports.engine.JRStyle; 93 import net.sf.jasperreports.engine.JRSubreport; 94 import net.sf.jasperreports.engine.JRSubreportParameter; 95 import net.sf.jasperreports.engine.JRSubreportReturnValue; 96 import net.sf.jasperreports.engine.JRTextField; 97 import net.sf.jasperreports.engine.JRVariable; 98 import net.sf.jasperreports.engine.fill.JRExtendedIncrementerFactory; 99 import net.sf.jasperreports.engine.query.JRQueryExecuterFactory; 100 import net.sf.jasperreports.engine.util.JRQueryExecuterUtils; 101 102 103 107 public class JRVerifier 108 { 109 110 111 114 private static String [] textFieldClassNames = null; 115 private static String [] imageClassNames = null; 116 private static String [] subreportClassNames = null; 117 118 121 private JasperDesign jasperDesign = null; 122 private Collection brokenRules = null; 123 124 private JRExpressionCollector expressionCollector; 125 126 127 130 protected JRVerifier(JasperDesign jrDesign) 131 { 132 this(jrDesign, null); 133 } 134 135 136 protected JRVerifier(JasperDesign jrDesign, JRExpressionCollector expressionCollector) 137 { 138 jasperDesign = jrDesign; 139 brokenRules = new ArrayList (); 140 141 if (expressionCollector != null) 142 { 143 this.expressionCollector = expressionCollector; 144 } 145 else 146 { 147 this.expressionCollector = JRExpressionCollector.collector(jasperDesign); 148 } 149 } 150 151 152 155 public static Collection verifyDesign(JasperDesign jasperDesign, JRExpressionCollector expressionCollector) 156 { 157 JRVerifier verifier = new JRVerifier(jasperDesign, expressionCollector); 158 return verifier.verifyDesign(); 159 } 160 161 public static Collection verifyDesign(JasperDesign jasperDesign) 162 { 163 return verifyDesign(jasperDesign, null); 164 } 165 166 169 protected Collection verifyDesign() 170 { 171 172 jasperDesign.preprocess(); 174 175 verifyDesignAttributes(); 176 177 178 verifyReportFonts(); 179 180 verifyDataset(jasperDesign.getMainDesignDataset()); 181 182 verifyDatasets(); 183 184 185 verifyStyles(); 186 187 188 verifyBand(jasperDesign.getBackground()); 189 verifyBand(jasperDesign.getTitle()); 190 verifyBand(jasperDesign.getPageHeader()); 191 verifyBand(jasperDesign.getColumnHeader()); 192 verifyBand(jasperDesign.getDetail()); 193 verifyBand(jasperDesign.getColumnFooter()); 194 verifyBand(jasperDesign.getPageFooter()); 195 verifyBand(jasperDesign.getLastPageFooter()); 196 verifyBand(jasperDesign.getSummary()); 197 198 return brokenRules; 199 } 200 201 202 205 private void verifyDesignAttributes() 206 { 207 if (jasperDesign.getName() == null || jasperDesign.getName().trim().length() == 0) 208 { 209 brokenRules.add("Report name is missing."); 210 } 211 212 if (jasperDesign.getColumnCount() <= 0) 213 { 214 brokenRules.add("Column count must be greater than zero."); 215 } 216 217 if (jasperDesign.getPageWidth() < 0) 218 { 219 brokenRules.add("Page width must be positive."); 220 } 221 222 if (jasperDesign.getPageHeight() < 0) 223 { 224 brokenRules.add("Page height must be positive."); 225 } 226 227 if (jasperDesign.getColumnWidth() < 0) 228 { 229 brokenRules.add("Column width must be positive."); 230 } 231 232 if (jasperDesign.getColumnSpacing() < 0) 233 { 234 brokenRules.add("Column spacing must be positive."); 235 } 236 237 if (jasperDesign.getLeftMargin() < 0) 238 { 239 brokenRules.add("Left margin must be positive."); 240 } 241 242 if (jasperDesign.getRightMargin() < 0) 243 { 244 brokenRules.add("Right margin must be positive."); 245 } 246 247 if (jasperDesign.getTopMargin() < 0) 248 { 249 brokenRules.add("Top margin must be positive."); 250 } 251 252 if (jasperDesign.getBottomMargin() < 0) 253 { 254 brokenRules.add("Bottom margin must be positive."); 255 } 256 257 if ( 258 jasperDesign.getLeftMargin() + 259 jasperDesign.getColumnCount() * jasperDesign.getColumnWidth() + 260 (jasperDesign.getColumnCount() - 1) * jasperDesign.getColumnSpacing() + 261 jasperDesign.getRightMargin() > 262 jasperDesign.getPageWidth() 263 ) 264 { 265 brokenRules.add("The columns and the margins do not fit the page width."); 266 } 267 268 if ( 269 jasperDesign.getTopMargin() + 270 (jasperDesign.getBackground() != null ? jasperDesign.getBackground().getHeight() : 0) + 271 jasperDesign.getBottomMargin() > 272 jasperDesign.getPageHeight() 273 ) 274 { 275 brokenRules.add("The background section and the margins do not fit the page height."); 276 } 277 278 if (jasperDesign.isTitleNewPage()) 279 { 280 if ( 281 jasperDesign.getTopMargin() + 282 (jasperDesign.getTitle() != null ? jasperDesign.getTitle().getHeight() : 0) + 283 jasperDesign.getBottomMargin() > 284 jasperDesign.getPageHeight() 285 ) 286 { 287 brokenRules.add("The title section and the margins do not fit the page height."); 288 } 289 } 290 else 291 { 292 if ( 293 jasperDesign.getTopMargin() + 294 (jasperDesign.getTitle() != null ? jasperDesign.getTitle().getHeight() : 0) + 295 (jasperDesign.getPageHeader() != null ? jasperDesign.getPageHeader().getHeight() : 0) + 296 (jasperDesign.getColumnHeader() != null ? jasperDesign.getColumnHeader().getHeight() : 0) + 297 (jasperDesign.getColumnFooter() != null ? jasperDesign.getColumnFooter().getHeight() : 0) + 298 (jasperDesign.getPageFooter() != null ? jasperDesign.getPageFooter().getHeight() : 0) + 299 jasperDesign.getBottomMargin() > 300 jasperDesign.getPageHeight() 301 ) 302 { 303 brokenRules.add("The title section, the page and column headers and footers and the margins do not fit the page height."); 304 } 305 } 306 307 if ( 308 jasperDesign.getTopMargin() + 309 (jasperDesign.getPageHeader() != null ? jasperDesign.getPageHeader().getHeight() : 0) + 310 (jasperDesign.getColumnHeader() != null ? jasperDesign.getColumnHeader().getHeight() : 0) + 311 (jasperDesign.getColumnFooter() != null ? jasperDesign.getColumnFooter().getHeight() : 0) + 312 (jasperDesign.getPageFooter() != null ? jasperDesign.getPageFooter().getHeight() : 0) + 313 jasperDesign.getBottomMargin() > 314 jasperDesign.getPageHeight() 315 ) 316 { 317 brokenRules.add("The page and column headers and footers and the margins do not fit the page height."); 318 } 319 320 if ( 321 jasperDesign.getTopMargin() + 322 (jasperDesign.getPageHeader() != null ? jasperDesign.getPageHeader().getHeight() : 0) + 323 (jasperDesign.getColumnHeader() != null ? jasperDesign.getColumnHeader().getHeight() : 0) + 324 (jasperDesign.getColumnFooter() != null ? jasperDesign.getColumnFooter().getHeight() : 0) + 325 (jasperDesign.getLastPageFooter() != null ? jasperDesign.getLastPageFooter().getHeight() : 0) + 326 jasperDesign.getBottomMargin() > 327 jasperDesign.getPageHeight() 328 ) 329 { 330 brokenRules.add("The page and column headers and footers and the margins do not fit the last page height."); 331 } 332 333 if ( 334 jasperDesign.getTopMargin() + 335 (jasperDesign.getSummary() != null ? jasperDesign.getSummary().getHeight() : 0) + 336 jasperDesign.getBottomMargin() > 337 jasperDesign.getPageHeight() 338 ) 339 { 340 brokenRules.add("The summary section and the margins do not fit the page height."); 341 } 342 343 if ( 344 jasperDesign.getTopMargin() + 345 (jasperDesign.getPageHeader() != null ? jasperDesign.getPageHeader().getHeight() : 0) + 346 (jasperDesign.getColumnHeader() != null ? jasperDesign.getColumnHeader().getHeight() : 0) + 347 (jasperDesign.getDetail() != null ? jasperDesign.getDetail().getHeight() : 0) + 348 (jasperDesign.getColumnFooter() != null ? jasperDesign.getColumnFooter().getHeight() : 0) + 349 (jasperDesign.getPageFooter() != null ? jasperDesign.getPageFooter().getHeight() : 0) + 350 jasperDesign.getBottomMargin() > 351 jasperDesign.getPageHeight() 352 ) 353 { 354 brokenRules.add("The detail section, the page and column headers and footers and the margins do not fit the page height."); 355 } 356 } 357 358 359 362 private void verifyQuery(JRDesignDataset dataset) 363 { 364 JRQuery query = dataset.getQuery(); 365 if (query != null) 366 { 367 String language = query.getLanguage(); 368 JRQueryExecuterFactory queryExecuterFactory = null; 369 if (language == null || language.length() == 0) 370 { 371 brokenRules.add("Query language not set."); 372 } 373 else 374 { 375 try 376 { 377 queryExecuterFactory = JRQueryExecuterUtils.getQueryExecuterFactory(query.getLanguage()); 378 } 379 catch (JRException e1) 380 { 381 brokenRules.add("Query executer factory for " + language + " cannot be created."); 382 } 383 } 384 385 386 JRQueryChunk[] chunks = query.getChunks(); 387 if (chunks != null && chunks.length > 0) 388 { 389 Map parametersMap = dataset.getParametersMap(); 390 391 for(int j = 0; j < chunks.length; j++) 392 { 393 JRQueryChunk queryChunk = chunks[j]; 394 switch (queryChunk.getType()) 395 { 396 case JRQueryChunk.TYPE_PARAMETER : 397 { 398 JRParameter parameter = (JRParameter)parametersMap.get(queryChunk.getText()); 399 if ( parameter == null ) 400 { 401 brokenRules.add("Query parameter not found : " + queryChunk.getText()); 402 } 403 else if (queryExecuterFactory != null) 404 { 405 if (!queryExecuterFactory.supportsQueryParameterType(parameter.getValueClassName())) 406 { 407 brokenRules.add("Parameter type not supported in query : " + queryChunk.getText() + " class " + parameter.getValueClassName()); 408 } 409 } 410 411 break; 412 } 413 case JRQueryChunk.TYPE_PARAMETER_CLAUSE : 414 { 415 if (!parametersMap.containsKey(queryChunk.getText())) 416 { 417 brokenRules.add("Query parameter not found : " + queryChunk.getText()); 418 } 419 break; 420 } 421 case JRQueryChunk.TYPE_TEXT : 422 default : 423 { 424 } 425 } 426 } 427 } 428 } 429 } 430 431 432 435 private void verifyExpressions(List expressions, Map parametersMap, Map fieldsMap, Map variablesMap) 436 { 437 if (expressions != null && expressions.size() > 0) 438 { 439 for(Iterator it = expressions.iterator(); it.hasNext();) 440 { 441 JRExpression expression = (JRExpression)it.next(); 442 JRExpressionChunk[] chunks = expression.getChunks(); 443 if (chunks != null && chunks.length > 0) 444 { 445 for(int j = 0; j < chunks.length; j++) 446 { 447 JRExpressionChunk expressionChunk = chunks[j]; 448 switch (expressionChunk.getType()) 449 { 450 case JRExpressionChunk.TYPE_VARIABLE : 451 { 452 if ( !variablesMap.containsKey(expressionChunk.getText()) ) 453 { 454 brokenRules.add("Variable not found : " + expressionChunk.getText()); 455 } 456 break; 457 } 458 case JRExpressionChunk.TYPE_FIELD : 459 { 460 if ( !fieldsMap.containsKey(expressionChunk.getText()) ) 461 { 462 brokenRules.add("Field not found : " + expressionChunk.getText()); 463 } 464 break; 465 } 466 case JRExpressionChunk.TYPE_PARAMETER : 467 { 468 if ( !parametersMap.containsKey(expressionChunk.getText()) ) 469 { 470 brokenRules.add("Parameter not found : " + expressionChunk.getText()); 471 } 472 break; 473 } 474 case JRExpressionChunk.TYPE_RESOURCE : 475 case JRExpressionChunk.TYPE_TEXT : 476 default : 477 { 478 } 479 } 480 } 481 } 482 } 483 } 484 } 485 486 487 private void verifyExpressions(JRDesignDataset dataset) 488 { 489 verifyExpressions( 490 expressionCollector.getExpressions(dataset), 491 dataset.getParametersMap(), 492 dataset.getFieldsMap(), 493 dataset.getVariablesMap()); 494 } 495 496 499 private void verifyReportFonts() 500 { 501 JRReportFont[] fonts = jasperDesign.getFonts(); 502 if (fonts != null && fonts.length > 0) 503 { 504 for(int index = 0; index < fonts.length; index++) 505 { 506 JRReportFont font = fonts[index]; 507 508 if (font.getName() == null || font.getName().trim().length() == 0) 509 { 510 brokenRules.add("Report font name missing."); 511 } 512 } 513 } 514 } 515 516 517 520 private void verifyStyles() 521 { 522 JRStyle[] styles = jasperDesign.getStyles(); 523 if (styles != null && styles.length > 0) 524 { 525 for(int index = 0; index < styles.length; index++) 526 { 527 JRStyle style = styles[index]; 528 529 if (style.getName() == null || style.getName().trim().length() == 0) 530 { 531 brokenRules.add("Report style name missing."); 532 } 533 } 534 } 535 } 536 537 538 541 private void verifyParameters(JRDesignDataset dataset) 542 { 543 JRParameter[] parameters = dataset.getParameters(); 544 if (parameters != null && parameters.length > 0) 545 { 546 for(int index = 0; index < parameters.length; index++) 547 { 548 JRParameter parameter = parameters[index]; 549 550 if (parameter.getName() == null || parameter.getName().trim().length() == 0) 551 { 552 brokenRules.add("Parameter name missing."); 553 } 554 555 if (parameter.getValueClassName() == null) 556 { 557 brokenRules.add("Class not set for parameter : " + parameter.getName()); 558 } 559 else 560 { 561 JRExpression expression = parameter.getDefaultValueExpression(); 562 if (expression != null) 563 { 564 if (expression.getValueClass() == null) { 565 brokenRules.add("No value class defined for the expression in parameter: "+parameter.getName()); 566 } 567 else { 568 if ( 569 !parameter.getValueClass().isAssignableFrom( 570 expression.getValueClass() 571 ) 572 ) 573 { 574 brokenRules.add("The parameter default value expression class is not compatible with the parameter's class : " + parameter.getName()); 575 } 576 } 577 } 578 } 579 } 580 } 581 } 582 583 584 587 private void verifyFields(JRDesignDataset dataset) 588 { 589 JRField[] fields = dataset.getFields(); 590 if (fields != null && fields.length > 0) 591 { 592 for(int index = 0; index < fields.length; index++) 593 { 594 JRField field = fields[index]; 595 596 if (field.getName() == null || field.getName().trim().length() == 0) 597 { 598 brokenRules.add("Field name missing."); 599 } 600 601 String className = field.getValueClassName(); 602 603 if (className == null) 604 { 605 brokenRules.add("Class not set for field : " + field.getName()); 606 } 607 } 608 } 609 } 610 611 612 615 private void verifySortFields(JRDesignDataset dataset) 616 { 617 JRField[] fields = dataset.getFields(); 618 JRSortField[] sortFields = dataset.getSortFields(); 619 if (sortFields != null && sortFields.length > 0) 620 { 621 for(int index = 0; index < sortFields.length; index++) 622 { 623 JRSortField sortField = sortFields[index]; 624 String sortFieldName = sortField.getName(); 625 626 if (sortFieldName == null || sortFieldName.trim().length() == 0) 627 { 628 brokenRules.add("Sort field name missing."); 629 } 630 else 631 { 632 boolean isFound = false; 633 634 int j = 0; 635 while (!isFound && j < fields.length) 636 { 637 isFound = sortFieldName.equals(fields[j].getName()); 638 j++; 639 } 640 641 if (!isFound) 642 { 643 brokenRules.add("Sort field \"" + sortFieldName + "\" not declared."); 644 } 645 } 646 } 647 } 648 } 649 650 651 654 private void verifyVariables(JRDesignDataset dataset) 655 { 656 JRVariable[] variables = dataset.getVariables(); 657 if (variables != null && variables.length > 0) 658 { 659 boolean isMainDataset = dataset.isMainDataset(); 660 for(int index = 0; index < variables.length; index++) 661 { 662 JRVariable variable = variables[index]; 663 664 if (variable.getName() == null || variable.getName().trim().length() == 0) 665 { 666 brokenRules.add("Variable name missing."); 667 } 668 669 Class valueClass = variable.getValueClass(); 670 671 if (valueClass == null) 672 { 673 brokenRules.add("Class not set for variable : " + variable.getName()); 674 } 675 else 676 { 677 JRExpression expression = variable.getExpression(); 678 if (expression != null) 679 { 680 if (expression.getValueClass() == null) { 681 brokenRules.add("No value class for the expression has been set in variable: "+variable.getName()); 682 } 683 else { 684 if ( 685 variable.getCalculation() != JRVariable.CALCULATION_COUNT 686 && variable.getCalculation() != JRVariable.CALCULATION_DISTINCT_COUNT 687 && variable.getCalculation() != JRVariable.CALCULATION_SYSTEM 688 && !valueClass.isAssignableFrom( 689 expression.getValueClass() 690 ) 691 ) 692 { 693 brokenRules.add("The variable expression class is not compatible with the variable's class : " + variable.getName()); 694 } 695 } 696 } 697 698 if (variable.getInitialValueExpression() != null) 699 { 700 if ( 701 !valueClass.isAssignableFrom( 702 variable.getInitialValueExpression().getValueClass() 703 ) 704 ) 705 { 706 brokenRules.add("The initial value class is not compatible with the variable's class : " + variable.getName()); 707 } 708 } 709 } 710 711 byte resetType = variable.getResetType(); 712 if (resetType == JRVariable.RESET_TYPE_GROUP) 713 { 714 if (variable.getResetGroup() == null) 715 { 716 brokenRules.add("Reset group missing for variable : " + variable.getName()); 717 } 718 else 719 { 720 Map groupsMap = dataset.getGroupsMap(); 721 722 if (!groupsMap.containsKey(variable.getResetGroup().getName())) 723 { 724 brokenRules.add("Reset group \"" + variable.getResetGroup().getName() + "\" not found for variable : " + variable.getName()); 725 } 726 } 727 } 728 729 byte incrementType = variable.getIncrementType(); 730 if (incrementType == JRVariable.RESET_TYPE_GROUP) 731 { 732 if (variable.getIncrementGroup() == null) 733 { 734 brokenRules.add("Increment group missing for variable : " + variable.getName()); 735 } 736 else 737 { 738 Map groupsMap = dataset.getGroupsMap(); 739 740 if (!groupsMap.containsKey(variable.getIncrementGroup().getName())) 741 { 742 brokenRules.add("Increment group \"" + variable.getIncrementGroup().getName() + "\" not found for variable : " + variable.getName()); 743 } 744 } 745 } 746 747 if (!isMainDataset) 748 { 749 if (resetType == JRVariable.RESET_TYPE_COLUMN || resetType == JRVariable.RESET_TYPE_PAGE) 750 { 751 brokenRules.add("Variable " + variable.getName() + " of dataset " + dataset.getName() + " cannot have Column or Page reset type."); 752 } 753 754 if (incrementType == JRVariable.RESET_TYPE_COLUMN || incrementType == JRVariable.RESET_TYPE_PAGE) 755 { 756 brokenRules.add("Variable " + variable.getName() + " of dataset " + dataset.getName() + " cannot have Column or Page increment type."); 757 } 758 } 759 } 760 } 761 } 762 763 764 767 private void verifyGroups(JRDesignDataset dataset) 768 { 769 JRGroup[] groups = dataset.getGroups(); 770 if (groups != null && groups.length > 0) 771 { 772 boolean isMainDataset = dataset.isMainDataset(); 773 for(int index = 0; index < groups.length; index++) 774 { 775 JRGroup group = groups[index]; 776 777 if (group.getName() == null || group.getName().trim().length() == 0) 778 { 779 brokenRules.add("Group name missing."); 780 } 781 782 if (isMainDataset) 783 { 784 verifyGroupHeaderAndFooter(group); 785 } 786 else 787 { 788 if (group.getGroupHeader() != null || group.getGroupFooter() != null) 789 { 790 brokenRules.add("Group " + group.getName() + " cannot have header or footer sections."); 791 } 792 } 793 794 JRExpression expression = group.getExpression(); 795 796 if (expression != null) 797 { 798 Class clazz = expression.getValueClass(); 799 800 if (clazz == null) 801 { 802 brokenRules.add("Class not set for group expression : " + group.getName()); 803 } 804 } 805 806 if (isMainDataset) 807 { 808 verifyBand(group.getGroupHeader()); 809 verifyBand(group.getGroupFooter()); 810 } 811 } 812 } 813 } 814 815 816 private void verifyGroupHeaderAndFooter(JRGroup group) 817 { 818 if (jasperDesign.isTitleNewPage()) 819 { 820 if ( 821 jasperDesign.getTopMargin() + 822 (jasperDesign.getPageHeader() != null ? jasperDesign.getPageHeader().getHeight() : 0) + 823 (jasperDesign.getColumnHeader() != null ? jasperDesign.getColumnHeader().getHeight() : 0) + 824 (group.getGroupHeader() != null ? group.getGroupHeader().getHeight() : 0) + 825 (jasperDesign.getColumnFooter() != null ? jasperDesign.getColumnFooter().getHeight() : 0) + 826 (jasperDesign.getPageFooter() != null ? jasperDesign.getPageFooter().getHeight() : 0) + 827 jasperDesign.getBottomMargin() > 828 jasperDesign.getPageHeight() 829 ) 830 { 831 brokenRules.add("The '" + group.getName() + "' group header section, the page and column headers and footers and the margins do not fit the page height."); 832 } 833 834 if ( 835 jasperDesign.getTopMargin() + 836 (jasperDesign.getPageHeader() != null ? jasperDesign.getPageHeader().getHeight() : 0) + 837 (jasperDesign.getColumnHeader() != null ? jasperDesign.getColumnHeader().getHeight() : 0) + 838 (group.getGroupFooter() != null ? group.getGroupFooter().getHeight() : 0) + 839 (jasperDesign.getColumnFooter() != null ? jasperDesign.getColumnFooter().getHeight() : 0) + 840 (jasperDesign.getPageFooter() != null ? jasperDesign.getPageFooter().getHeight() : 0) + 841 jasperDesign.getBottomMargin() > 842 jasperDesign.getPageHeight() 843 ) 844 { 845 brokenRules.add("The '" + group.getName() + "' group footer section, the page and column headers and footers and the margins do not fit the page height."); 846 } 847 } 848 else 849 { 850 if ( 851 jasperDesign.getTopMargin() + 852 (jasperDesign.getTitle() != null ? jasperDesign.getTitle().getHeight() : 0) + 853 (jasperDesign.getPageHeader() != null ? jasperDesign.getPageHeader().getHeight() : 0) + 854 (jasperDesign.getColumnHeader() != null ? jasperDesign.getColumnHeader().getHeight() : 0) + 855 (group.getGroupHeader() != null ? group.getGroupHeader().getHeight() : 0) + 856 (jasperDesign.getColumnFooter() != null ? jasperDesign.getColumnFooter().getHeight() : 0) + 857 (jasperDesign.getPageFooter() != null ? jasperDesign.getPageFooter().getHeight() : 0) + 858 jasperDesign.getBottomMargin() > 859 jasperDesign.getPageHeight() 860 ) 861 { 862 brokenRules.add("The '" + group.getName() + "' group header section, the title, the page and column headers and footers and the margins do not fit the first page height."); 863 } 864 865 if ( 866 jasperDesign.getTopMargin() + 867 (jasperDesign.getTitle() != null ? jasperDesign.getTitle().getHeight() : 0) + 868 (jasperDesign.getPageHeader() != null ? jasperDesign.getPageHeader().getHeight() : 0) + 869 (jasperDesign.getColumnHeader() != null ? jasperDesign.getColumnHeader().getHeight() : 0) + 870 (group.getGroupFooter() != null ? group.getGroupFooter().getHeight() : 0) + 871 (jasperDesign.getColumnFooter() != null ? jasperDesign.getColumnFooter().getHeight() : 0) + 872 (jasperDesign.getPageFooter() != null ? jasperDesign.getPageFooter().getHeight() : 0) + 873 jasperDesign.getBottomMargin() > 874 jasperDesign.getPageHeight() 875 ) 876 { 877 brokenRules.add("The '" + group.getName() + "' group footer section, the title, the page and column headers and footers and the margins do not fit the first page height."); 878 } 879 } 880 } 881 882 883 886 private void verifyBand(JRBand band) 887 { 888 if (band != null) 889 { 890 JRElement[] elements = band.getElements(); 891 if (elements != null && elements.length > 0) 892 { 893 JRExpression expression = band.getPrintWhenExpression(); 894 895 if (expression != null) 896 { 897 Class clazz = expression.getValueClass(); 898 899 if (clazz == null) 900 { 901 brokenRules.add("Class not set for band \"print when\" expression."); 902 } 903 else if (!java.lang.Boolean .class.isAssignableFrom(clazz)) 904 { 905 brokenRules.add("Class " + clazz + " not supported for band \"print when\" expression. Use java.lang.Boolean instead."); 906 } 907 } 908 909 for(int index = 0; index < elements.length; index++) 910 { 911 JRElement element = elements[index]; 912 913 verifyPrintWhenExpr(element); 914 915 925 if (element.getY() + element.getHeight() > band.getHeight()) 926 { 927 brokenRules.add( 934 "Warning : Element bottom reaches outside band area : y=" + element.getY() + 935 " height=" + element.getHeight() + 936 " band-height=" + band.getHeight() 937 ); 938 } 939 940 verifyElement(element); 941 } 942 } 943 } 944 } 945 946 947 protected void verifyElement(JRElement element) 948 { 949 if (element instanceof JRStaticText) 950 { 951 verifyStaticText((JRStaticText)element); 952 } 953 else if (element instanceof JRTextField) 954 { 955 verifyTextField((JRTextField)element); 956 } 957 else if (element instanceof JRImage) 958 { 959 verifyImage((JRImage)element); 960 } 961 else if (element instanceof JRSubreport) 962 { 963 verifySubreport((JRSubreport)element); 964 } 965 else if (element instanceof JRCrosstab) 966 { 967 verifyCrosstab((JRDesignCrosstab) element); 968 } 969 else if (element instanceof JRChart) 970 { 971 verifyChart((JRChart) element); 972 } 973 else if (element instanceof JRFrame) 974 { 975 verifyFrame((JRFrame) element); 976 } 977 } 978 979 980 private void verifyPrintWhenExpr(JRElement element) 981 { 982 JRExpression expression; 983 expression = element.getPrintWhenExpression(); 984 985 if (expression != null) 986 { 987 Class clazz = expression.getValueClass(); 988 989 if (clazz == null) 990 { 991 brokenRules.add("Class not set for element \"print when\" expression."); 992 } 993 else if (!java.lang.Boolean .class.isAssignableFrom(clazz)) 994 { 995 brokenRules.add("Class " + clazz + " not supported for element \"print when\" expression. Use java.lang.Boolean instead."); 996 } 997 } 998 } 999 1000 1001 1004 private void verifyStaticText(JRStaticText staticText) 1005 { 1006 verifyFont(staticText); 1007 } 1008 1009 1010 1013 private void verifyTextField(JRTextField textField) 1014 { 1015 verifyFont(textField); 1016 verifyAnchor(textField); 1017 verifyHyperlink(textField); 1018 1019 if (textField != null) 1020 { 1021 JRExpression expression = textField.getExpression(); 1022 1023 if (expression != null) 1024 { 1025 String className = expression.getValueClassName(); 1026 1027 if (className == null) 1028 { 1029 brokenRules.add("Class not set for text field expression."); 1030 } 1031 else if (Arrays.binarySearch(getTextFieldClassNames(), className) < 0) 1032 { 1033 brokenRules.add("Class \"" + className + "\" not supported for text field expression."); 1034 } 1035 } 1036 } 1037 } 1038 1039 1040 1043 private void verifyFont(JRFont font) 1044 { 1045 JRReportFont reportFont = font.getReportFont(); 1046 1047 if (reportFont != null && reportFont.getName() != null) 1048 { 1049 Map fontsMap = jasperDesign.getFontsMap(); 1050 1051 if (!fontsMap.containsKey(reportFont.getName())) 1052 { 1053 brokenRules.add("Report font not found : " + reportFont.getName()); 1054 } 1055 } 1056 } 1057 1058 1059 1062 private void verifyAnchor(JRAnchor anchor) 1063 { 1064 if (anchor != null) 1065 { 1066 JRExpression expression = anchor.getAnchorNameExpression(); 1067 1068 if (expression != null) 1069 { 1070 Class clazz = expression.getValueClass(); 1071 1072 if (clazz == null) 1073 { 1074 brokenRules.add("Class not set for anchor name expression."); 1075 } 1076 else if (!java.lang.String .class.isAssignableFrom(clazz)) 1077 { 1078 brokenRules.add("Class " + clazz + " not supported for anchor name expression. Use java.lang.String instead."); 1079 } 1080 } 1081 1082 if (anchor.getBookmarkLevel() != JRAnchor.NO_BOOKMARK && anchor.getBookmarkLevel() < 1) 1083 { 1084 brokenRules.add("Bookmark level should be " + JRAnchor.NO_BOOKMARK + " or greater than 0"); 1085 } 1086 } 1087 } 1088 1089 1090 1093 private void verifyHyperlink(JRHyperlink hyperlink) 1094 { 1095 if (hyperlink != null) 1096 { 1097 JRExpression expression = hyperlink.getHyperlinkReferenceExpression(); 1098 1099 if (expression != null) 1100 { 1101 Class clazz = expression.getValueClass(); 1102 1103 if (clazz == null) 1104 { 1105 brokenRules.add("Class not set for hyperlink reference expression."); 1106 } 1107 else if (!java.lang.String .class.isAssignableFrom(clazz)) 1108 { 1109 brokenRules.add("Class " + clazz + " not supported for hyperlink reference expression. Use java.lang.String instead."); 1110 } 1111 } 1112 1113 expression = hyperlink.getHyperlinkAnchorExpression(); 1114 1115 if (expression != null) 1116 { 1117 Class clazz = expression.getValueClass(); 1118 1119 if (clazz == null) 1120 { 1121 brokenRules.add("Class not set for hyperlink anchor expression."); 1122 } 1123 else if (!java.lang.String .class.isAssignableFrom(clazz)) 1124 { 1125 brokenRules.add("Class " + clazz + " not supported for hyperlink anchor expression. Use java.lang.String instead."); 1126 } 1127 } 1128 1129 expression = hyperlink.getHyperlinkPageExpression(); 1130 1131 if (expression != null) 1132 { 1133 Class clazz = expression.getValueClass(); 1134 1135 if (clazz == null) 1136 { 1137 brokenRules.add("Class not set for hyperlink page expression."); 1138 } 1139 else if (!java.lang.Integer .class.isAssignableFrom(clazz)) 1140 { 1141 brokenRules.add("Class " + clazz + " not supported for hyperlink page expression. Use java.lang.Integer instead."); 1142 } 1143 } 1144 1145 expression = hyperlink.getHyperlinkTooltipExpression(); 1146 1147 if (expression != null) 1148 { 1149 Class clazz = expression.getValueClass(); 1150 1151 if (clazz == null) 1152 { 1153 brokenRules.add("Class not set for hyperlink tooltip expression."); 1154 } 1155 else if (!java.lang.String .class.isAssignableFrom(clazz)) 1156 { 1157 brokenRules.add("Class " + clazz + " not supported for hyperlink tooltip expression. Use java.lang.String instead."); 1158 } 1159 } 1160 1161 JRHyperlinkParameter[] parameters = hyperlink.getHyperlinkParameters(); 1162 if (parameters != null) 1163 { 1164 for (int i = 0; i < parameters.length; i++) 1165 { 1166 JRHyperlinkParameter parameter = parameters[i]; 1167 verifyHyperlinkParameter(parameter); 1168 } 1169 } 1170 } 1171 } 1172 1173 1174 protected void verifyHyperlinkParameter(JRHyperlinkParameter parameter) 1175 { 1176 if (parameter != null) 1177 { 1178 String name = parameter.getName(); 1179 if (name == null || name.length() == 0) 1180 { 1181 brokenRules.add("Hyperlink parameter name missing."); 1182 } 1183 } 1184 } 1185 1186 1187 1190 private void verifyImage(JRImage image) 1191 { 1192 verifyAnchor(image); 1193 verifyHyperlink(image); 1194 1195 if (image != null) 1196 { 1197 JRExpression expression = image.getExpression(); 1198 1199 if (expression != null) 1200 { 1201 String className = expression.getValueClassName(); 1202 1203 if (className == null) 1204 { 1205 brokenRules.add("Class not set for image expression."); 1206 } 1207 else if (Arrays.binarySearch(getImageClassNames(), className) < 0) 1208 { 1209 brokenRules.add("Class \"" + className + "\" not supported for image expression."); 1210 } 1211 } 1212 } 1213 } 1214 1215 1216 1219 private void verifySubreport(JRSubreport subreport) 1220 { 1221 if (subreport != null) 1222 { 1223 JRExpression expression = subreport.getExpression(); 1224 1225 if (expression != null) 1226 { 1227 String className = expression.getValueClassName(); 1228 1229 if (className == null) 1230 { 1231 brokenRules.add("Class not set for subreport expression."); 1232 } 1233 else if (Arrays.binarySearch(getSubreportClassNames(), className) < 0) 1234 { 1235 brokenRules.add("Class \"" + className + "\" not supported for subreport expression."); 1236 } 1237 } 1238 1239 expression = subreport.getParametersMapExpression(); 1240 1241 if (expression != null) 1242 { 1243 Class clazz = expression.getValueClass(); 1244 1245 if (clazz == null) 1246 { 1247 brokenRules.add("Class not set for subreport parameters map expression."); 1248 } 1249 else if (!java.util.Map .class.isAssignableFrom(clazz)) 1250 { 1251 brokenRules.add("Class " + clazz + " not supported for subreport parameters map expression. Use java.util.Map instead."); 1252 } 1253 } 1254 1255 JRSubreportParameter[] parameters = subreport.getParameters(); 1256 if (parameters != null && parameters.length > 0) 1257 { 1258 for(int index = 0; index < parameters.length; index++) 1259 { 1260 JRSubreportParameter parameter = parameters[index]; 1261 1262 if (parameter.getName() == null || parameter.getName().trim().length() == 0) 1263 { 1264 brokenRules.add("Subreport parameter name missing."); 1265 } 1266 1267 expression = parameter.getExpression(); 1268 1269 if (expression != null) 1270 { 1271 Class clazz = expression.getValueClass(); 1272 1273 if (clazz == null) 1274 { 1275 brokenRules.add("Class not set for subreport parameter expression : " + parameter.getName() + ". Use java.lang.Object class."); 1276 } 1277 } 1278 } 1279 } 1280 1281 if ( 1282 subreport.getConnectionExpression() != null && 1283 subreport.getDataSourceExpression() != null 1284 ) 1285 { 1286 brokenRules.add("Subreport cannot have both connection expresion and data source expression."); 1287 } 1288 1289 expression = subreport.getConnectionExpression(); 1290 1291 if (expression != null) 1292 { 1293 Class clazz = expression.getValueClass(); 1294 1295 if (clazz == null) 1296 { 1297 brokenRules.add("Class not set for subreport connection expression."); 1298 } 1299 else if (!java.sql.Connection .class.isAssignableFrom(clazz)) 1300 { 1301 brokenRules.add("Class " + clazz + " not supported for subreport connection expression. Use java.sql.Connection instead."); 1302 } 1303 } 1304 1305 expression = subreport.getDataSourceExpression(); 1306 1307 if (expression != null) 1308 { 1309 Class clazz = expression.getValueClass(); 1310 1311 if (clazz == null) 1312 { 1313 brokenRules.add("Class not set for subreport data source expression."); 1314 } 1315 else if (!net.sf.jasperreports.engine.JRDataSource.class.isAssignableFrom(clazz)) 1316 { 1317 brokenRules.add("Class " + clazz + " not supported for subreport data source expression. Use net.sf.jasperreports.engine.JRDataSource instead."); 1318 } 1319 } 1320 1321 JRSubreportReturnValue[] returnValues = subreport.getReturnValues(); 1322 if (returnValues != null && returnValues.length > 0) 1323 { 1324 for (int i = 0; i < returnValues.length; i++) 1325 { 1326 JRSubreportReturnValue returnValue = returnValues[i]; 1327 1328 if (returnValue.getSubreportVariable() == null || returnValue.getSubreportVariable().trim().length() == 0) 1329 { 1330 brokenRules.add("Subreport return value variable name missing."); 1331 } 1332 1333 if (returnValue.getToVariable() == null || returnValue.getToVariable().trim().length() == 0) 1334 { 1335 brokenRules.add("Subreport return value to variable name missing."); 1336 } 1337 1338 if (!jasperDesign.getVariablesMap().containsKey(returnValue.getToVariable())) 1339 { 1340 brokenRules.add("Subreport return value to variable not found."); 1341 } 1342 } 1343 } 1344 } 1345 } 1346 1347 1348 1351 private static synchronized String [] getTextFieldClassNames() 1352 { 1353 if (textFieldClassNames == null) 1354 { 1355 textFieldClassNames = new String [] 1356 { 1357 java.lang.Boolean .class.getName(), 1358 java.lang.Byte .class.getName(), 1359 java.util.Date .class.getName(), 1360 java.sql.Timestamp .class.getName(), 1361 java.sql.Time .class.getName(), 1362 java.lang.Double .class.getName(), 1363 java.lang.Float .class.getName(), 1364 java.lang.Integer .class.getName(), 1365 java.lang.Long .class.getName(), 1366 java.lang.Short .class.getName(), 1367 java.math.BigDecimal .class.getName(), 1368 java.lang.Number .class.getName(), 1369 java.lang.String .class.getName() 1370 }; 1371 1372 Arrays.sort(textFieldClassNames); 1373 } 1374 1375 return textFieldClassNames; 1376 } 1377 1378 1379 1382 private static synchronized String [] getImageClassNames() 1383 { 1384 if (imageClassNames == null) 1385 { 1386 imageClassNames = new String [] 1387 { 1388 java.lang.String .class.getName(), 1389 java.io.File .class.getName(), 1390 java.net.URL .class.getName(), 1391 java.io.InputStream .class.getName(), 1392 java.awt.Image .class.getName(), 1393 net.sf.jasperreports.engine.JRRenderable.class.getName() 1394 }; 1395 1396 Arrays.sort(imageClassNames); 1397 } 1398 1399 return imageClassNames; 1400 } 1401 1402 1403 1406 private static synchronized String [] getSubreportClassNames() 1407 { 1408 if (subreportClassNames == null) 1409 { 1410 subreportClassNames = new String [] 1411 { 1412 java.lang.String .class.getName(), 1413 java.io.File .class.getName(), 1414 java.net.URL .class.getName(), 1415 java.io.InputStream .class.getName(), 1416 net.sf.jasperreports.engine.JasperReport.class.getName() 1417 }; 1418 1419 Arrays.sort(subreportClassNames); 1420 } 1421 1422 return subreportClassNames; 1423 } 1424 1425 1426 private void verifyCrosstab(JRDesignCrosstab crosstab) 1427 { 1428 verifyParameters(crosstab); 1429 1430 JRCrosstabDataset dataset = crosstab.getDataset(); 1431 if (dataset == null) 1432 { 1433 brokenRules.add("Crosstab dataset missing."); 1434 } 1435 else 1436 { 1437 verifyElementDataset(dataset); 1438 } 1439 1440 verifyCellContents(crosstab.getHeaderCell(), "crosstab cell"); 1441 1442 JRCrosstabRowGroup[] rowGroups = crosstab.getRowGroups(); 1443 if (rowGroups == null || rowGroups.length == 0) 1444 { 1445 brokenRules.add("Crosstab should have at least one row group."); 1446 } 1447 else 1448 { 1449 for (int i = 0; i < rowGroups.length; i++) 1450 { 1451 verifyCrosstabRowGroup(rowGroups[i]); 1452 } 1453 } 1454 1455 JRCrosstabColumnGroup[] colGroups = crosstab.getColumnGroups(); 1456 if (colGroups == null || colGroups.length == 0) 1457 { 1458 brokenRules.add("Crosstab should have at least one column group."); 1459 } 1460 else 1461 { 1462 for (int i = 0; i < colGroups.length; i++) 1463 { 1464 verifyCrosstabColumnGroup(colGroups[i]); 1465 } 1466 } 1467 1468 JRCrosstabMeasure[] measures = crosstab.getMeasures(); 1469 if (measures == null || measures.length == 0) 1470 { 1471 brokenRules.add("Crosstab should have at least one measure."); 1472 } 1473 else 1474 { 1475 for (int i = 0; i < measures.length; i++) 1476 { 1477 verifyCrosstabMeasure(measures[i]); 1478 } 1479 } 1480 1481 verifyCrosstabCells(crosstab); 1482 1483 verifyCellContents(crosstab.getWhenNoDataCell(), "when no data cell"); 1484 1485 verifyExpressions(crosstab); 1486 } 1487 1488 1489 private void verifyParameters(JRDesignCrosstab crosstab) 1490 { 1491 JRExpression paramMapExpression = crosstab.getParametersMapExpression(); 1492 1493 if (paramMapExpression != null) 1494 { 1495 Class clazz = paramMapExpression.getValueClass(); 1496 1497 if (clazz == null) 1498 { 1499 brokenRules.add("Class not set for crosstab parameters map expression."); 1500 } 1501 else if (!java.util.Map .class.isAssignableFrom(clazz)) 1502 { 1503 brokenRules.add("Class " + clazz + " not supported for crosstab parameters map expression. Use java.util.Map instead."); 1504 } 1505 } 1506 1507 JRCrosstabParameter[] parameters = crosstab.getParameters(); 1508 if (parameters != null) 1509 { 1510 for (int i = 0; i < parameters.length; i++) 1511 { 1512 JRCrosstabParameter parameter = parameters[i]; 1513 1514 String paramName = parameter.getName(); 1515 if (paramName == null || paramName.length() == 0) 1516 { 1517 brokenRules.add("Missing parameter name for crosstab."); 1518 } 1519 1520 JRExpression expression = parameter.getExpression(); 1521 Class expressionClass = null; 1522 if (expression != null) 1523 { 1524 expressionClass = expression.getValueClass(); 1525 1526 if (expressionClass == null) 1527 { 1528 brokenRules.add("Expression class not set for crosstab parameter " + paramName + "."); 1529 } 1530 } 1531 1532 Class valueClass = parameter.getValueClass(); 1533 if (valueClass == null) 1534 { 1535 brokenRules.add("Class not set for crosstab parameter " + paramName + "."); 1536 } 1537 else if (expressionClass != null && !valueClass.isAssignableFrom(expressionClass)) 1538 { 1539 brokenRules.add("Incompatible expression class for crosstab parameter " + paramName + "."); 1540 } 1541 } 1542 } 1543 } 1544 1545 1546 private void verifyCrosstabRowGroup(JRCrosstabRowGroup group) 1547 { 1548 verifyCrosstabGroup(group); 1549 } 1550 1551 1552 private void verifyCrosstabColumnGroup(JRCrosstabColumnGroup group) 1553 { 1554 verifyCrosstabGroup(group); 1555 } 1556 1557 1558 private void verifyCrosstabGroup(JRCrosstabGroup group) 1559 { 1560 String groupName = group.getName(); 1561 if (groupName == null || groupName.length() == 0) 1562 { 1563 brokenRules.add("Crosstab group name missing."); 1564 } 1565 1566 verifyCrosstabBucket(group); 1567 verifyCellContents(group.getHeader(), groupName + " header"); 1568 if (group.hasTotal()) 1569 { 1570 verifyCellContents(group.getTotalHeader(), groupName + " total header"); 1571 } 1572 } 1573 1574 1575 private void verifyCrosstabBucket(JRCrosstabGroup group) 1576 { 1577 JRCrosstabBucket bucket = group.getBucket(); 1578 1579 JRExpression expression = bucket.getExpression(); 1580 Class expressionClass = null; 1581 if (expression == null) 1582 { 1583 brokenRules.add("Crosstab bucket expression missing for group " + group.getName() + "."); 1584 } 1585 else 1586 { 1587 expressionClass = expression.getValueClass(); 1588 1589 if (expressionClass == null) 1590 { 1591 brokenRules.add("Crosstab bucket expression class missing for group " + group.getName() + "."); 1592 } 1593 } 1594 1595 Class valueClass = expression == null ? null : expression.getValueClass(); 1596 if (valueClass == null) 1597 { 1598 brokenRules.add("Crosstab bucket value class missing for group " + group.getName() + "."); 1599 } 1600 else if (expressionClass != null && !valueClass.isAssignableFrom(expressionClass)) 1601 { 1602 brokenRules.add("The class of the expression is not compatible with the class of the crosstab bucket for group " + group.getName() + "."); 1603 } 1604 1605 JRExpression comparatorExpression = bucket.getComparatorExpression(); 1606 if (comparatorExpression == null) 1607 { 1608 if (valueClass != null && !Comparable .class.isAssignableFrom(valueClass)) 1609 { 1610 brokenRules.add("No comparator expression specified and the value class is not comparable for crosstab group " + group.getName() + "."); 1611 } 1612 } 1613 else 1614 { 1615 Class comparatorClass = comparatorExpression.getValueClass(); 1616 if (comparatorClass == null) 1617 { 1618 brokenRules.add("Crosstab bucket comparator expression class missing for group " + group.getName() + "."); 1619 } 1620 else if (!Comparator .class.isAssignableFrom(comparatorClass)) 1621 { 1622 brokenRules.add("The comparator expression should be compatible with java.util.Comparator for crosstab group " + group.getName() + "."); 1623 } 1624 } 1625 } 1626 1627 1628 private void verifyCrosstabCells(JRDesignCrosstab crosstab) 1629 { 1630 JRCrosstabCell[][] cells = crosstab.getCells(); 1631 JRCrosstabRowGroup[] rowGroups = crosstab.getRowGroups(); 1632 JRCrosstabColumnGroup[] columnGroups = crosstab.getColumnGroups(); 1633 1634 JRCrosstabCell baseCell = cells[rowGroups.length][columnGroups.length]; 1635 if(baseCell == null || baseCell.getWidth() == null) 1636 { 1637 brokenRules.add("Crosstab base cell width not specified."); 1638 } 1639 1640 if(baseCell == null || baseCell.getHeight() == null) 1641 { 1642 brokenRules.add("Crosstab base cell height not specified."); 1643 } 1644 1645 for (int i = rowGroups.length; i >= 0 ; --i) 1646 { 1647 for (int j = columnGroups.length; j >= 0 ; --j) 1648 { 1649 JRCrosstabCell cell = cells[i][j]; 1650 1651 String cellText = getCrosstabCellText(rowGroups, columnGroups, i, j); 1652 1653 if (cell != null) 1654 { 1655 JRCellContents contents = cell.getContents(); 1656 1657 if (i < rowGroups.length) 1658 { 1659 JRCrosstabCell colCell = cells[rowGroups.length][j]; 1660 if (colCell != null && colCell.getContents().getWidth() != contents.getWidth()) 1661 { 1662 brokenRules.add("Crosstab " + cellText + " width should be " + colCell.getContents().getWidth() + "."); 1663 } 1664 } 1665 1666 if (j < columnGroups.length) 1667 { 1668 JRCrosstabCell rowCell = cells[i][columnGroups.length]; 1669 if (rowCell != null && rowCell.getContents().getHeight() != contents.getHeight()) 1670 { 1671 brokenRules.add("Crosstab " + cellText + " height should be " + rowCell.getContents().getHeight() + "."); 1672 } 1673 } 1674 1675 verifyCellContents(contents, cellText); 1676 } 1677 } 1678 } 1679 } 1680 1681 private String getCrosstabCellText(JRCrosstabRowGroup[] rowGroups, JRCrosstabColumnGroup[] columnGroups, 1682 int rowIndex, int columnIndex) 1683 { 1684 String text; 1685 1686 if (rowIndex == rowGroups.length) 1687 { 1688 if (columnIndex == columnGroups.length) 1689 { 1690 text = "cell"; 1691 } 1692 else 1693 { 1694 text = columnGroups[columnIndex].getName() + " total cell"; 1695 } 1696 } 1697 else 1698 { 1699 if (columnIndex == columnGroups.length) 1700 { 1701 text = rowGroups[rowIndex].getName() + " total cell"; 1702 } 1703 else 1704 { 1705 text = rowGroups[rowIndex].getName() + "," + columnGroups[columnIndex].getName() + " total cell"; 1706 } 1707 } 1708 1709 return text; 1710 } 1711 1712 private void verifyCrosstabMeasure(JRCrosstabMeasure measure) 1713 { 1714 String measureName = measure.getName(); 1715 if (measureName == null || measureName.trim().length() == 0) 1716 { 1717 brokenRules.add("Measure name missing."); 1718 } 1719 1720 byte calculation = measure.getCalculation(); 1721 if (calculation == JRVariable.CALCULATION_SYSTEM) 1722 { 1723 brokenRules.add("Crosstab mesures cannot have system calculation"); 1724 } 1725 1726 JRExpression valueExpression = measure.getValueExpression(); 1727 Class expressionClass = null; 1728 if (valueExpression == null) 1729 { 1730 brokenRules.add("Missing expression for measure " + measureName); 1731 } 1732 else 1733 { 1734 expressionClass = valueExpression.getValueClass(); 1735 if (expressionClass == null) 1736 { 1737 brokenRules.add("Crosstab measure expression class missing for " + measureName + "."); 1738 } 1739 } 1740 1741 Class valueClass = measure.getValueClass(); 1742 if (valueClass == null) 1743 { 1744 brokenRules.add("Measure value class missing."); 1745 } 1746 else if (expressionClass != null 1747 && calculation != JRVariable.CALCULATION_COUNT 1748 && calculation != JRVariable.CALCULATION_DISTINCT_COUNT 1749 && !valueClass.isAssignableFrom(expressionClass) 1750 ) 1751 { 1752 brokenRules.add("The class of the expression is not compatible with the class of the measure " + measureName + "."); 1753 } 1754 1755 if (measure.getPercentageOfType() != JRCrosstabMeasure.PERCENTAGE_TYPE_NONE) 1756 { 1757 Class percentageCalculatorClass = measure.getPercentageCalculatorClass(); 1758 if (percentageCalculatorClass == null) 1759 { 1760 if (valueClass != null && !JRPercentageCalculatorFactory.hasBuiltInCalculator(valueClass)) 1761 { 1762 brokenRules.add("Percentage calculator class needs to be specified for measure " + measureName + "."); 1763 } 1764 } 1765 else 1766 { 1767 if (!JRPercentageCalculator.class.isAssignableFrom(percentageCalculatorClass)) 1768 { 1769 brokenRules.add("Incompatible percentage calculator class for measure " + measureName + "."); 1770 } 1771 } 1772 } 1773 1774 Class incrementerFactoryClass = measure.getIncrementerFactoryClass(); 1775 if (incrementerFactoryClass != null && !JRExtendedIncrementerFactory.class.isAssignableFrom(incrementerFactoryClass)) 1776 { 1777 brokenRules.add("Crosstab measures need extended incrementers (net.sf.jasperreports.engine.fill.JRExtendedIncrementerFactory)."); 1778 } 1779 } 1780 1781 1782 private void verifyExpressions(JRDesignCrosstab crosstab) 1783 { 1784 verifyExpressions(expressionCollector.getExpressions(crosstab), 1785 crosstab.getParametersMap(), 1786 new HashMap (), 1787 crosstab.getVariablesMap()); 1788 } 1789 1790 1791 private void verifyChart(JRChart chart) 1792 { 1793 if (chart.getEvaluationTime() == JRExpression.EVALUATION_TIME_AUTO) 1794 { 1795 brokenRules.add("Charts do not support Auto evaluation time."); 1796 } 1797 1798 JRChartDataset dataset = chart.getDataset(); 1799 if (dataset == null) 1800 { 1801 brokenRules.add("Chart dataset missing."); 1802 } 1803 else 1804 { 1805 dataset.validate(this); 1806 } 1807 } 1808 1809 1810 private void verifyCellContents(JRCellContents contents, String cellText) 1811 { 1812 if (contents != null) 1813 { 1814 JRElement[] elements = contents.getElements(); 1815 if (elements != null && elements.length > 0) 1816 { 1817 int topPadding = 0; 1818 int leftPadding = 0; 1819 int bottomPadding = 0; 1820 int rightPadding = 0; 1821 1822 JRBox box = contents.getBox(); 1823 if (box != null) 1824 { 1825 topPadding = box.getTopPadding(); 1826 leftPadding = box.getLeftPadding(); 1827 bottomPadding = box.getBottomPadding(); 1828 rightPadding = box.getRightPadding(); 1829 } 1830 1831 int cellWidth = contents.getWidth(); 1832 boolean widthCalculated = cellWidth != JRCellContents.NOT_CALCULATED; 1833 int avlblWidth = cellWidth - leftPadding - rightPadding; 1834 int cellHeight = contents.getHeight(); 1835 boolean heightCalculated = cellHeight != JRCellContents.NOT_CALCULATED; 1836 int avlblHeight = cellHeight - topPadding - bottomPadding; 1837 1838 for (int i = 0; i < elements.length; i++) 1839 { 1840 JRElement element = elements[i]; 1841 1842 verifyPrintWhenExpr(element); 1843 1844 if (widthCalculated && element.getX() + element.getWidth() > avlblWidth) 1845 { 1846 brokenRules.add("Element reaches outside " + cellText + " width: x=" + element.getX() + ", width=" 1847 + element.getWidth() + ", available width=" + avlblWidth + "."); 1848 } 1849 1850 if (heightCalculated && element.getY() + element.getHeight() > avlblHeight) 1851 { 1852 brokenRules.add("Element reaches outside " + cellText + " height: y=" + element.getY() + ", height=" 1853 + element.getHeight() + ", available height=" + avlblHeight + "."); 1854 } 1855 1856 if (element instanceof JRStaticText) 1857 { 1858 verifyStaticText((JRStaticText)element); 1859 } 1860 else if (element instanceof JRTextField) 1861 { 1862 JRTextField textField = (JRTextField) element; 1863 1864 if (textField.getEvaluationTime() != JRExpression.EVALUATION_TIME_NOW) 1865 { 1866 brokenRules.add("Elements with delayed evaluation time are not supported inside crosstab cells."); 1867 } 1868 1869 verifyTextField(textField); 1870 } 1871 else if (element instanceof JRImage) 1872 { 1873 JRImage image = (JRImage) element; 1874 1875 if (image.getEvaluationTime() != JRExpression.EVALUATION_TIME_NOW) 1876 { 1877 brokenRules.add("Elements with delayed evaluation time are not supported inside crosstab cells."); 1878 } 1879 1880 verifyImage(image); 1881 } 1882 else if (element instanceof JRFrame) 1883 { 1884 verifyFrame((JRFrame) element); 1885 } 1886 else if (element instanceof JRSubreport) 1887 { 1888 brokenRules.add("Subreports are not allowed inside crosstab cells."); 1889 } 1890 else if (element instanceof JRCrosstab) 1891 { 1892 brokenRules.add("Crosstabs are not allowed inside crosstab cells."); 1893 } 1894 else if (element instanceof JRChart) 1895 { 1896 brokenRules.add("Charts are not allowed inside crosstab cells."); 1897 } 1898 } 1899 } 1900 } 1901 } 1902 1903 1904 private void verifyElementDataset(JRElementDataset dataset) 1905 { 1906 JRDatasetRun datasetRun = dataset.getDatasetRun(); 1907 1908 if (datasetRun != null) 1909 { 1910 byte incrementType = dataset.getIncrementType(); 1911 if (incrementType == JRVariable.RESET_TYPE_PAGE || incrementType == JRVariable.RESET_TYPE_COLUMN) 1912 { 1913 brokenRules.add("Chart datasets with dataset run cannont have Column or Page increment type."); 1914 } 1915 1916 byte resetType = dataset.getResetType(); 1917 if (resetType == JRVariable.RESET_TYPE_PAGE || resetType == JRVariable.RESET_TYPE_COLUMN) 1918 { 1919 brokenRules.add("Chart datasets with dataset run cannont have Column or Page reset type."); 1920 } 1921 else if (resetType != JRVariable.RESET_TYPE_REPORT) 1922 { 1923 } 1925 1926 verifyDatasetRun(datasetRun); 1927 } 1928 1929 JRExpression incrementWhenExpression = dataset.getIncrementWhenExpression(); 1930 if (incrementWhenExpression != null) 1931 { 1932 Class valueClass = incrementWhenExpression.getValueClass(); 1933 if (valueClass == null) 1934 { 1935 brokenRules.add("Class not set for data set \"increment when\" expression."); 1936 } 1937 else if (!Boolean .class.isAssignableFrom(valueClass)) 1938 { 1939 brokenRules.add("Class " + valueClass + " not supported for dataset \"increment when\" expression. Use java.lang.Boolean instead."); 1940 } 1941 } 1942 } 1943 1944 1945 private void verifyDatasetRun(JRDatasetRun datasetRun) 1946 { 1947 JRDesignDataset dataset = null; 1948 1949 String datasetName = datasetRun.getDatasetName(); 1950 if (datasetName == null || datasetName.length() == 0) 1951 { 1952 brokenRules.add("Dataset name is missing for dataset run."); 1953 } 1954 else 1955 { 1956 dataset = (JRDesignDataset) jasperDesign.getDatasetMap().get(datasetName); 1957 1958 if (dataset == null) 1959 { 1960 brokenRules.add("Unknown dataset name " + datasetName + "."); 1961 } 1962 } 1963 1964 JRExpression parametersMapExpression = datasetRun.getParametersMapExpression(); 1965 1966 if (parametersMapExpression != null) 1967 { 1968 Class clazz = parametersMapExpression.getValueClass(); 1969 1970 if (clazz == null) 1971 { 1972 brokenRules.add("Class not set for dataset " + datasetName + " parameters map expression."); 1973 } 1974 else if (!java.util.Map .class.isAssignableFrom(clazz)) 1975 { 1976 brokenRules.add("Class " + clazz + " not supported for dataset " + datasetName + " parameters map expression. Use java.util.Map instead."); 1977 } 1978 } 1979 1980 JRDatasetParameter[] parameters = datasetRun.getParameters(); 1981 if (parameters != null && parameters.length > 0) 1982 { 1983 for(int index = 0; index < parameters.length; index++) 1984 { 1985 JRDatasetParameter parameter = parameters[index]; 1986 1987 String paramName = parameter.getName(); 1988 if (paramName == null || paramName.trim().length() == 0) 1989 { 1990 brokenRules.add("Dataset " + datasetName + " parameter name missing."); 1991 } 1992 1993 JRParameter datasetParam = null; 1994 if (dataset != null) 1995 { 1996 datasetParam = (JRParameter) dataset.getParametersMap().get(paramName); 1997 1998 if (datasetParam == null) 1999 { 2000 brokenRules.add("Unknown parameter " + paramName + " in dataset " + datasetName + "."); 2001 } 2002 } 2003 2004 JRExpression expression = parameter.getExpression(); 2005 2006 if (expression != null) 2007 { 2008 Class clazz = expression.getValueClass(); 2009 2010 if (clazz == null) 2011 { 2012 brokenRules.add("Class not set for dataset " + datasetName + " parameter expression : " + paramName + "."); 2013 } 2014 else if (datasetParam != null && !datasetParam.getValueClass().isAssignableFrom(clazz)) 2015 { 2016 brokenRules.add("Class " + clazz + " not supported for parameter " + paramName + " of dataset " + datasetName + ". Use " + datasetParam.getValueClass() + " instead."); 2017 } 2018 } 2019 } 2020 } 2021 2022 JRExpression connectionExpression = datasetRun.getConnectionExpression(); 2023 JRExpression dataSourceExpression = datasetRun.getDataSourceExpression(); 2024 2025 if (connectionExpression != null && dataSourceExpression != null) 2026 { 2027 brokenRules.add("Dataset " + datasetName + " cannot have both connection expresion and data source expression."); 2028 } 2029 2030 if (connectionExpression != null) 2031 { 2032 Class clazz = connectionExpression.getValueClass(); 2033 2034 if (clazz == null) 2035 { 2036 brokenRules.add("Class not set for dataset " + datasetName + " connection expression."); 2037 } 2038 else if (!java.sql.Connection .class.isAssignableFrom(clazz)) 2039 { 2040 brokenRules.add("Class " + clazz + " not supported for dataset " + datasetName + " connection expression. Use java.sql.Connection instead."); 2041 } 2042 } 2043 2044 if (dataSourceExpression != null) 2045 { 2046 Class clazz = dataSourceExpression.getValueClass(); 2047 2048 if (clazz == null) 2049 { 2050 brokenRules.add("Class not set for dataset " + datasetName + " data source expression."); 2051 } 2052 else if (!net.sf.jasperreports.engine.JRDataSource.class.isAssignableFrom(clazz)) 2053 { 2054 brokenRules.add("Class " + clazz + " not supported for dataset " + datasetName + " data source expression. Use net.sf.jasperreports.engine.JRDataSource instead."); 2055 } 2056 } 2057 } 2058 2059 2060 private void verifyDatasets() 2061 { 2062 JRDataset[] datasets = jasperDesign.getDatasets(); 2063 if (datasets != null && datasets.length > 0) 2064 { 2065 for (int i = 0; i < datasets.length; ++i) 2066 { 2067 JRDesignDataset dataset = (JRDesignDataset) datasets[i]; 2068 2069 if (dataset.getName() == null || dataset.getName().trim().length() == 0) 2070 { 2071 brokenRules.add("Dataset name is missing."); 2072 } 2073 2074 verifyDataset(dataset); 2075 } 2076 } 2077 } 2078 2079 2080 private void verifyDataset(JRDesignDataset dataset) 2081 { 2082 verifyExpressions(dataset); 2083 2084 verifyParameters(dataset); 2085 2086 verifyQuery(dataset); 2087 2088 verifyFields(dataset); 2089 2090 verifySortFields(dataset); 2091 2092 verifyVariables(dataset); 2093 2094 verifyGroups(dataset); 2095 2096 JRExpression filterExpression = dataset.getFilterExpression(); 2097 if (filterExpression != null) 2098 { 2099 Class valueClass = filterExpression.getValueClass(); 2100 if (valueClass == null) 2101 { 2102 brokenRules.add("Class not set for filter expression."); 2103 } 2104 else if (!Boolean .class.isAssignableFrom(valueClass)) 2105 { 2106 brokenRules.add("Class " + valueClass + " not supported for filter expression. Use java.lang.Boolean instead."); 2107 } 2108 } 2109 } 2110 2111 2112 private void verifyFrame(JRFrame frame) 2113 { 2114 JRElement[] elements = frame.getElements(); 2115 if (elements != null && elements.length > 0) 2116 { 2117 int topPadding = frame.getTopPadding(); 2118 int leftPadding = frame.getLeftPadding(); 2119 int bottomPadding = frame.getBottomPadding(); 2120 int rightPadding = frame.getRightPadding(); 2121 2122 int avlblWidth = frame.getWidth() - leftPadding - rightPadding; 2123 int avlblHeight = frame.getHeight() - topPadding - bottomPadding; 2124 2125 for (int i = 0; i < elements.length; i++) 2126 { 2127 JRElement element = elements[i]; 2128 2129 if (element.getX() + element.getWidth() > avlblWidth) 2130 { 2131 brokenRules.add("Element reaches outside frame width: x=" + element.getX() + ", width=" 2132 + element.getWidth() + ", available width=" + avlblWidth + "."); 2133 } 2134 2135 if (element.getY() + element.getHeight() > avlblHeight) 2136 { 2137 brokenRules.add("Element reaches outside frame height: y=" + element.getY() + ", height=" 2138 + element.getHeight() + ", available height=" + avlblHeight + "."); 2139 } 2140 2141 verifyElement(element); 2142 } 2143 } 2144 } 2145 2146 2147 public void verify(JRCategoryDataset dataset) 2148 { 2149 verifyElementDataset(dataset); 2150 2151 JRCategorySeries[] series = dataset.getSeries(); 2152 if (series != null) 2153 { 2154 for (int i = 0; i < series.length; i++) 2155 { 2156 verify(series[i]); 2157 } 2158 } 2159 } 2160 2161 2162 protected void verify(JRCategorySeries series) 2163 { 2164 verifyHyperlink(series.getItemHyperlink()); 2165 } 2166 2167 2168 public void verify(JRPieDataset dataset) 2169 { 2170 verifyElementDataset(dataset); 2171 verifyHyperlink(dataset.getSectionHyperlink()); 2172 } 2173 2174 2175 public void verify(JRHighLowDataset dataset) 2176 { 2177 verifyElementDataset(dataset); 2178 verifyHyperlink(dataset.getItemHyperlink()); 2179 } 2180 2181 2182 public void verify(JRTimePeriodDataset dataset) 2183 { 2184 verifyElementDataset(dataset); 2185 2186 JRTimePeriodSeries[] series = dataset.getSeries(); 2187 if (series != null) 2188 { 2189 for (int i = 0; i < series.length; i++) 2190 { 2191 verify(series[i]); 2192 } 2193 } 2194 } 2195 2196 2197 protected void verify(JRTimePeriodSeries series) 2198 { 2199 verifyHyperlink(series.getItemHyperlink()); 2200 } 2201 2202 2203 public void verify(JRTimeSeriesDataset dataset) 2204 { 2205 verifyElementDataset(dataset); 2206 2207 JRTimeSeries[] series = dataset.getSeries(); 2208 if (series != null) 2209 { 2210 for (int i = 0; i < series.length; i++) 2211 { 2212 verify(series[i]); 2213 } 2214 } 2215 } 2216 2217 2218 protected void verify(JRTimeSeries series) 2219 { 2220 verifyHyperlink(series.getItemHyperlink()); 2221 } 2222 2223 2224 2229 public void verify(JRValueDataset dataset) 2230 { 2231 } 2232 2233 public void verify(JRXyDataset dataset) 2234 { 2235 verifyElementDataset(dataset); 2236 2237 JRXySeries[] series = dataset.getSeries(); 2238 if (series != null) 2239 { 2240 for (int i = 0; i < series.length; i++) 2241 { 2242 verify(series[i]); 2243 } 2244 } 2245 } 2246 2247 2248 protected void verify(JRXySeries series) 2249 { 2250 verifyHyperlink(series.getItemHyperlink()); 2251 } 2252 2253 2254 public void verify(JRXyzDataset dataset) 2255 { 2256 verifyElementDataset(dataset); 2257 2258 JRXyzSeries[] series = dataset.getSeries(); 2259 if (series != null) 2260 { 2261 for (int i = 0; i < series.length; i++) 2262 { 2263 verify(series[i]); 2264 } 2265 } 2266 } 2267 2268 2269 protected void verify(JRXyzSeries series) 2270 { 2271 verifyHyperlink(series.getItemHyperlink()); 2272 } 2273} 2274 | Popular Tags |