1 28 package net.sf.jasperreports.engine.fill; 29 30 import java.awt.Color ; 31 import java.io.Serializable ; 32 import java.util.ArrayList ; 33 import java.util.Collection ; 34 import java.util.HashMap ; 35 import java.util.HashSet ; 36 import java.util.Iterator ; 37 import java.util.Map ; 38 import java.util.Set ; 39 40 import net.sf.jasperreports.engine.JRDefaultStyleProvider; 41 import net.sf.jasperreports.engine.JRElement; 42 import net.sf.jasperreports.engine.JRElementGroup; 43 import net.sf.jasperreports.engine.JRException; 44 import net.sf.jasperreports.engine.JRExpression; 45 import net.sf.jasperreports.engine.JRExpressionChunk; 46 import net.sf.jasperreports.engine.JRGroup; 47 import net.sf.jasperreports.engine.JRPrintElement; 48 import net.sf.jasperreports.engine.JRStyle; 49 import net.sf.jasperreports.engine.JRVariable; 50 import net.sf.jasperreports.engine.util.JRStyleResolver; 51 52 53 57 public abstract class JRFillElement implements JRElement, JRCloneable 58 { 59 60 61 64 protected JRElement parent = null; 65 protected Map templates = new HashMap (); 66 67 70 protected JRBaseFiller filler = null; 71 protected JRFillExpressionEvaluator expressionEvaluator = null; 72 73 76 protected JRGroup printWhenGroupChanges = null; 77 protected JRFillElementGroup elementGroup = null; 78 79 82 protected JRFillBand band = null; 83 84 87 private boolean isPrintWhenExpressionNull = true; 88 private boolean isPrintWhenTrue = true; 89 private boolean isToPrint = true; 90 private boolean isReprinted = false; 91 private boolean isAlreadyPrinted = false; 92 private Collection dependantElements = new ArrayList (); 93 private int relativeY = 0; 94 private int stretchHeight = 0; 95 private int bandBottomY = 0; 96 97 private int x; 98 private int y; 99 private int width; 100 private int height; 101 102 private boolean isValueRepeating = false; 103 104 protected byte currentEvaluation; 105 106 protected Map delayedEvaluationsMap; 108 109 protected JRFillElementContainer conditionalStylesContainer; 110 111 protected final JRStyle initStyle; 112 113 117 private boolean shrinkable; 118 119 129 protected JRFillElement( 130 JRBaseFiller filler, 131 JRElement element, 132 JRFillObjectFactory factory 133 ) 134 { 135 factory.put(element, this); 136 137 this.parent = element; 138 this.filler = filler; 139 this.expressionEvaluator = factory.getExpressionEvaluator(); 140 141 142 printWhenGroupChanges = factory.getGroup(element.getPrintWhenGroupChanges()); 143 elementGroup = (JRFillElementGroup)factory.getElementGroup(element.getElementGroup()); 144 145 x = element.getX(); 146 y = element.getY(); 147 width = element.getWidth(); 148 height = element.getHeight(); 149 150 initStyle = factory.getStyle(parent.getStyle()); 151 } 152 153 154 protected JRFillElement(JRFillElement element, JRFillCloneFactory factory) 155 { 156 factory.put(element, this); 157 158 this.parent = element.parent; 159 this.filler = element.filler; 160 this.expressionEvaluator = element.expressionEvaluator; 161 162 163 printWhenGroupChanges = element.printWhenGroupChanges; 164 elementGroup = (JRFillElementGroup) factory.getClone((JRFillElementGroup) element.getElementGroup()); 165 166 x = element.getX(); 167 y = element.getY(); 168 width = element.getWidth(); 169 height = element.getHeight(); 170 171 templates = element.templates; 172 173 initStyle = element.initStyle; 174 175 shrinkable = element.shrinkable; 176 } 177 178 179 182 public JRDefaultStyleProvider getDefaultStyleProvider() 183 { 184 return parent.getDefaultStyleProvider(); 185 } 186 187 188 191 public String getKey() 192 { 193 return parent.getKey(); 194 } 195 196 199 public byte getPositionType() 200 { 201 return parent.getPositionType(); } 203 204 207 public void setPositionType(byte positionType) 208 { 209 } 210 211 214 public byte getStretchType() 215 { 216 return parent.getStretchType(); 217 } 218 219 222 public void setStretchType(byte stretchType) 223 { 224 } 225 226 229 public boolean isPrintRepeatedValues() 230 { 231 return parent.isPrintRepeatedValues(); 232 } 233 234 237 public void setPrintRepeatedValues(boolean isPrintRepeatedValues) 238 { 239 } 240 241 244 public byte getMode() 245 { 246 return JRStyleResolver.getMode(this, MODE_OPAQUE); 247 } 248 249 252 public Byte getOwnMode() 253 { 254 return parent.getOwnMode(); 255 } 256 257 260 public void setMode(byte mode) 261 { 262 } 263 264 267 public void setMode(Byte mode) 268 { 269 } 270 271 274 public int getX() 275 { 276 return x; 277 } 278 279 282 public void setX(int x) 283 { 284 this.x = x; 285 } 286 287 290 public void setY(int y) 291 { 292 this.y = y; 293 } 294 295 298 public int getY() 299 { 300 return y; 301 } 302 303 306 public int getWidth() 307 { 308 return width; 309 } 310 311 314 public void setWidth(int width) 315 { 316 this.width = width; 317 } 318 319 322 public void setHeight(int height) 323 { 324 this.height = height; 325 } 326 327 330 public int getHeight() 331 { 332 return height; 333 } 334 335 338 public boolean isRemoveLineWhenBlank() 339 { 340 return parent.isRemoveLineWhenBlank(); 341 } 342 343 346 public void setRemoveLineWhenBlank(boolean isRemoveLine) 347 { 348 } 349 350 353 public boolean isPrintInFirstWholeBand() 354 { 355 return parent.isPrintInFirstWholeBand(); 356 } 357 358 361 public void setPrintInFirstWholeBand(boolean isPrint) 362 { 363 } 364 365 368 public boolean isPrintWhenDetailOverflows() 369 { 370 return parent.isPrintWhenDetailOverflows(); 371 } 372 373 376 public void setPrintWhenDetailOverflows(boolean isPrint) 377 { 378 } 379 380 383 public Color getForecolor() 384 { 385 return JRStyleResolver.getForecolor(this); 386 } 387 388 public Color getOwnForecolor() 389 { 390 return parent.getOwnForecolor(); 391 } 392 393 396 public void setForecolor(Color forecolor) 397 { 398 } 399 400 403 public Color getBackcolor() 404 { 405 return JRStyleResolver.getBackcolor(this); 406 } 407 408 411 public Color getOwnBackcolor() 412 { 413 return parent.getOwnBackcolor(); 414 } 415 416 419 public void setBackcolor(Color backcolor) 420 { 421 } 422 423 426 public JRExpression getPrintWhenExpression() 427 { 428 return parent.getPrintWhenExpression(); 429 } 430 431 434 public JRGroup getPrintWhenGroupChanges() 435 { 436 return printWhenGroupChanges; 437 } 438 439 442 public JRElementGroup getElementGroup() 443 { 444 return elementGroup; 445 } 446 447 450 protected boolean isPrintWhenExpressionNull() 451 { 452 return isPrintWhenExpressionNull; 453 } 454 455 458 protected void setPrintWhenExpressionNull(boolean isPrintWhenExpressionNull) 459 { 460 this.isPrintWhenExpressionNull = isPrintWhenExpressionNull; 461 } 462 463 466 protected boolean isPrintWhenTrue() 467 { 468 return isPrintWhenTrue; 469 } 470 471 474 protected void setPrintWhenTrue(boolean isPrintWhenTrue) 475 { 476 this.isPrintWhenTrue = isPrintWhenTrue; 477 } 478 479 482 protected boolean isToPrint() 483 { 484 return isToPrint; 485 } 486 487 490 protected void setToPrint(boolean isToPrint) 491 { 492 this.isToPrint = isToPrint; 493 } 494 495 498 protected boolean isReprinted() 499 { 500 return isReprinted; 501 } 502 503 506 protected void setReprinted(boolean isReprinted) 507 { 508 this.isReprinted = isReprinted; 509 } 510 511 514 protected boolean isAlreadyPrinted() 515 { 516 return isAlreadyPrinted; 517 } 518 519 522 protected void setAlreadyPrinted(boolean isAlreadyPrinted) 523 { 524 this.isAlreadyPrinted = isAlreadyPrinted; 525 } 526 527 530 protected JRElement[] getGroupElements() 531 { 532 JRElement[] groupElements = null; 533 534 if (elementGroup != null) 535 { 536 groupElements = elementGroup.getElements(); 537 } 538 539 return groupElements; 540 } 541 542 545 protected Collection getDependantElements() 546 { 547 return dependantElements; 548 } 549 550 553 protected void addDependantElement(JRElement element) 554 { 555 dependantElements.add(element); 556 } 557 558 561 protected int getRelativeY() 562 { 563 return relativeY; 564 } 565 566 569 protected void setRelativeY(int relativeY) 570 { 571 this.relativeY = relativeY; 572 } 573 574 577 protected int getStretchHeight() 578 { 579 return stretchHeight; 580 } 581 582 585 protected void setStretchHeight(int stretchHeight) 586 { 587 if (stretchHeight > getHeight() || (shrinkable && isRemoveLineWhenBlank())) 588 { 589 this.stretchHeight = stretchHeight; 590 } 591 else 592 { 593 this.stretchHeight = getHeight(); 594 } 595 } 596 597 600 protected int getBandBottomY() 601 { 602 return bandBottomY; 603 } 604 605 608 protected void setBandBottomY(int bandBottomY) 609 { 610 this.bandBottomY = bandBottomY; 611 } 612 613 616 protected JRFillBand getBand() 617 { 618 return band; 619 } 620 621 624 protected void setBand(JRFillBand band) 625 { 626 this.band = band; 627 } 628 629 630 633 protected void reset() 634 { 635 relativeY = y; 636 stretchHeight = height; 637 638 if (elementGroup != null) 639 { 640 elementGroup.reset(); 641 } 642 } 643 644 protected void setCurrentEvaluation(byte evaluation) 645 { 646 currentEvaluation = evaluation; 647 } 648 649 652 protected abstract void evaluate( 653 byte evaluation 654 ) throws JRException; 655 656 657 660 protected void evaluatePrintWhenExpression( 661 byte evaluation 662 ) throws JRException 663 { 664 boolean isExprNull = true; 665 boolean isExprTrue = false; 666 667 JRExpression expression = getPrintWhenExpression(); 668 if (expression != null) 669 { 670 isExprNull = false; 671 Boolean printWhenExpressionValue = (Boolean ) evaluateExpression(expression, evaluation); 672 if (printWhenExpressionValue == null) 673 { 674 isExprTrue = false; 675 } 676 else 677 { 678 isExprTrue = printWhenExpressionValue.booleanValue(); 679 } 680 } 681 682 setPrintWhenExpressionNull(isExprNull); 683 setPrintWhenTrue(isExprTrue); 684 } 685 686 687 690 protected abstract void rewind() throws JRException; 691 692 693 696 protected abstract JRPrintElement fill() throws JRException; 697 698 699 702 protected boolean prepare( 703 int availableStretchHeight, 704 boolean isOverflow 705 ) throws JRException 706 { 707 if ( 708 isPrintWhenExpressionNull() || 709 ( !isPrintWhenExpressionNull() && 710 isPrintWhenTrue() ) 711 ) 712 { 713 setToPrint(true); 714 } 715 else 716 { 717 setToPrint(false); 718 } 719 720 setReprinted(false); 721 722 return false; 723 } 724 725 726 727 730 protected void stretchElement(int bandStretch) 731 { 732 switch (getStretchType()) 733 { 734 case JRElement.STRETCH_TYPE_RELATIVE_TO_BAND_HEIGHT : 735 { 736 setStretchHeight(getHeight() + bandStretch); 737 break; 738 } 739 case JRElement.STRETCH_TYPE_RELATIVE_TO_TALLEST_OBJECT : 740 { 741 if (elementGroup != null) 742 { 743 setStretchHeight(getHeight() + elementGroup.getStretchHeightDiff()); 745 } 746 747 break; 748 } 749 case JRElement.STRETCH_TYPE_NO_STRETCH : 750 default : 751 { 752 break; 753 } 754 } 755 } 756 757 758 761 protected void moveDependantElements() 762 { 763 Collection elements = getDependantElements(); 764 if (elements != null && elements.size() > 0) 765 { 766 JRFillElement element = null; 767 int diffY = 0; 768 for(Iterator it = elements.iterator(); it.hasNext();) 769 { 770 element = (JRFillElement)it.next(); 771 772 diffY = element.getY() - getY() - getHeight() - 773 (element.getRelativeY() - getRelativeY() - getStretchHeight()); 774 775 if (diffY < 0) 776 { 777 diffY = 0; 778 } 779 780 element.setRelativeY(element.getRelativeY() + diffY); 781 } 782 } 783 } 784 785 786 792 protected abstract void resolveElement (JRPrintElement element, byte evaluation) throws JRException; 793 794 795 803 protected final Object evaluateExpression(JRExpression expression, byte evaluation) throws JRException 804 { 805 return expressionEvaluator.evaluate(expression, evaluation); 806 } 807 808 809 819 protected boolean isValueRepeating() 820 { 821 return isValueRepeating; 822 } 823 824 825 833 protected void setValueRepeating(boolean isValueRepeating) 834 { 835 this.isValueRepeating = isValueRepeating; 836 } 837 838 839 protected JRFillVariable getVariable(String variableName) 840 { 841 return filler.getVariable(variableName); 842 } 843 844 845 protected JRFillField getField(String fieldName) 846 { 847 return filler.getField(fieldName); 848 } 849 850 protected byte getEvaluationTime() 852 { 853 return JRExpression.EVALUATION_TIME_NOW; 854 } 855 856 863 protected void resolveElement (JRPrintElement element, byte evaluation, JREvaluationTime evaluationTime) throws JRException 864 { 865 byte evaluationTimeType = getEvaluationTime(); 866 switch (evaluationTimeType) 867 { 868 case JRExpression.EVALUATION_TIME_NOW: 869 break; 870 case JRExpression.EVALUATION_TIME_AUTO: 871 delayedEvaluate((JRRecordedValuesPrintElement) element, evaluationTime, evaluation); 872 break; 873 default: 874 resolveElement(element, evaluation); 875 break; 876 } 877 } 878 879 private static class DelayedEvaluations implements Serializable 880 { 881 final Set fields; 882 final Set variables; 883 884 DelayedEvaluations() 885 { 886 fields = new HashSet (); 887 variables = new HashSet (); 888 } 889 } 890 891 protected void initDelayedEvaluations() 892 { 893 if (getEvaluationTime() == JRExpression.EVALUATION_TIME_AUTO && delayedEvaluationsMap == null) 894 { 895 delayedEvaluationsMap = new HashMap (); 896 collectDelayedEvaluations(); 897 } 898 } 899 900 protected void collectDelayedEvaluations() 901 { 902 } 904 905 protected void collectDelayedEvaluations(JRExpression expression) 906 { 907 if (expression != null) 908 { 909 JRExpressionChunk[] chunks = expression.getChunks(); 910 if (chunks != null) 911 { 912 for (int i = 0; i < chunks.length; i++) 913 { 914 JRExpressionChunk chunk = chunks[i]; 915 switch (chunk.getType()) 916 { 917 case JRExpressionChunk.TYPE_FIELD: 918 { 919 DelayedEvaluations delayedEvaluations = getDelayedEvaluations(JREvaluationTime.EVALUATION_TIME_NOW); 920 delayedEvaluations.fields.add(chunk.getText()); 921 break; 922 } 923 case JRExpressionChunk.TYPE_VARIABLE: 924 { 925 JREvaluationTime time = autogetVariableEvaluationTime(chunk.getText()); 926 DelayedEvaluations delayedEvaluations = getDelayedEvaluations(time); 927 delayedEvaluations.variables.add(chunk.getText()); 928 break; 929 } 930 } 931 } 932 } 933 } 934 } 935 936 937 private DelayedEvaluations getDelayedEvaluations(JREvaluationTime time) 938 { 939 DelayedEvaluations delayedEvaluations = (DelayedEvaluations) delayedEvaluationsMap.get(time); 940 if (delayedEvaluations == null) 941 { 942 delayedEvaluations = new DelayedEvaluations(); 943 delayedEvaluationsMap.put(time, delayedEvaluations); 944 } 945 return delayedEvaluations; 946 } 947 948 949 private JREvaluationTime autogetVariableEvaluationTime(String variableName) 950 { 951 JRFillVariable variable = getVariable(variableName); 952 JREvaluationTime evaluationTime; 953 switch (variable.getResetType()) 954 { 955 case JRVariable.RESET_TYPE_REPORT: 956 evaluationTime = JREvaluationTime.EVALUATION_TIME_REPORT; 957 break; 958 case JRVariable.RESET_TYPE_PAGE: 959 evaluationTime = JREvaluationTime.EVALUATION_TIME_PAGE; 960 break; 961 case JRVariable.RESET_TYPE_COLUMN: 962 evaluationTime = JREvaluationTime.EVALUATION_TIME_COLUMN; 963 break; 964 case JRVariable.RESET_TYPE_GROUP: 965 evaluationTime = JREvaluationTime.getGroupEvaluationTime(variable.getResetGroup().getName()); 966 break; 967 default: 968 evaluationTime = JREvaluationTime.EVALUATION_TIME_NOW; 969 break; 970 } 971 972 if (!evaluationTime.equals(JREvaluationTime.EVALUATION_TIME_NOW) && 973 band.isNowEvaluationTime(evaluationTime)) 974 { 975 evaluationTime = JREvaluationTime.EVALUATION_TIME_NOW; 976 } 977 978 if (variable.getCalculation() == JRVariable.CALCULATION_SYSTEM && 979 evaluationTime.equals(JREvaluationTime.EVALUATION_TIME_NOW) && 980 band.isVariableUsedInSubreportReturns(variableName)) 981 { 982 evaluationTime = JREvaluationTime.getBandEvaluationTime(band); 983 } 984 985 return evaluationTime; 986 } 987 988 989 protected void initDelayedEvaluationPrint(JRRecordedValuesPrintElement printElement) throws JRException 990 { 991 for (Iterator it = delayedEvaluationsMap.keySet().iterator(); it.hasNext();) 992 { 993 JREvaluationTime evaluationTime = (JREvaluationTime) it.next(); 994 if (!evaluationTime.equals(JREvaluationTime.EVALUATION_TIME_NOW)) 995 { 996 filler.addBoundElement(this, printElement, evaluationTime); 997 } 998 } 999 1000 printElement.initRecordedValues(delayedEvaluationsMap.keySet()); 1001 1002 if (delayedEvaluationsMap.containsKey(JREvaluationTime.EVALUATION_TIME_NOW)) 1003 { 1004 delayedEvaluate(printElement, JREvaluationTime.EVALUATION_TIME_NOW, currentEvaluation); 1005 } 1006 } 1007 1008 1009 protected void delayedEvaluate(JRRecordedValuesPrintElement printElement, JREvaluationTime evaluationTime, byte evaluation) throws JRException 1010 { 1011 JRRecordedValues recordedValues = printElement.getRecordedValues(); 1012 if (!recordedValues.lastEvaluationTime()) 1013 { 1014 DelayedEvaluations delayedEvaluations = (DelayedEvaluations) delayedEvaluationsMap.get(evaluationTime); 1015 1016 for (Iterator it = delayedEvaluations.fields.iterator(); it.hasNext();) 1017 { 1018 String fieldName = (String ) it.next(); 1019 JRFillField field = getField(fieldName); 1020 recordedValues.recordFieldValue(fieldName, field.getValue(evaluation)); 1021 } 1022 1023 for (Iterator it = delayedEvaluations.variables.iterator(); it.hasNext();) 1024 { 1025 String variableName = (String ) it.next(); 1026 JRFillVariable variable = getVariable(variableName); 1027 recordedValues.recordVariableValue(variableName, variable.getValue(evaluation)); 1028 } 1029 } 1030 1031 recordedValues.doneEvaluation(evaluationTime); 1032 1033 if (recordedValues.finishedEvaluations()) 1034 { 1035 overwriteWithRecordedValues(recordedValues, evaluation); 1036 resolveElement(printElement, evaluation); 1037 restoreValues(recordedValues, evaluation); 1038 printElement.deleteRecordedValues(); 1039 } 1040 } 1041 1042 1043 private void overwriteWithRecordedValues(JRRecordedValues recordedValues, byte evaluation) 1044 { 1045 Map fieldValues = recordedValues.getRecordedFieldValues(); 1046 if (fieldValues != null) 1047 { 1048 for (Iterator it = fieldValues.entrySet().iterator(); it.hasNext();) 1049 { 1050 Map.Entry entry = (Map.Entry ) it.next(); 1051 String fieldName = (String ) entry.getKey(); 1052 Object fieldValue = entry.getValue(); 1053 JRFillField field = getField(fieldName); 1054 field.overwriteValue(fieldValue, evaluation); 1055 } 1056 } 1057 1058 Map variableValues = recordedValues.getRecordedVariableValues(); 1059 if (variableValues != null) 1060 { 1061 for (Iterator it = variableValues.entrySet().iterator(); it.hasNext();) 1062 { 1063 Map.Entry entry = (Map.Entry ) it.next(); 1064 String variableName = (String ) entry.getKey(); 1065 Object variableValue = entry.getValue(); 1066 JRFillVariable variable = getVariable(variableName); 1067 variable.overwriteValue(variableValue, evaluation); 1068 } 1069 } 1070 } 1071 1072 private void restoreValues(JRRecordedValues recordedValues, byte evaluation) 1073 { 1074 Map fieldValues = recordedValues.getRecordedFieldValues(); 1075 if (fieldValues != null) 1076 { 1077 for (Iterator it = fieldValues.keySet().iterator(); it.hasNext();) 1078 { 1079 String fieldName = (String ) it.next(); 1080 JRFillField field = getField(fieldName); 1081 field.restoreValue(evaluation); 1082 } 1083 } 1084 1085 Map variableValues = recordedValues.getRecordedVariableValues(); 1086 if (variableValues != null) 1087 { 1088 for (Iterator it = variableValues.keySet().iterator(); it.hasNext();) 1089 { 1090 String variableName = (String ) it.next(); 1091 JRFillVariable variable = getVariable(variableName); 1092 variable.restoreValue(evaluation); 1093 } 1094 } 1095 } 1096 1097 1098 1101 protected void setConditionalStylesContainer(JRFillElementContainer conditionalStylesContainer) 1102 { 1103 this.conditionalStylesContainer = conditionalStylesContainer; 1104 } 1105 1106 1109 public JRStyle getStyle() 1110 { 1111 JRStyle crtStyle = initStyle; 1112 1113 boolean isUsingDefaultStyle = false; 1114 1115 if (crtStyle == null) 1116 { 1117 crtStyle = filler.getDefaultStyle(); 1118 isUsingDefaultStyle = true; 1119 } 1120 1121 JRStyle evalStyle = crtStyle; 1122 1123 if (conditionalStylesContainer != null) 1124 evalStyle = conditionalStylesContainer.getEvaluatedConditionalStyle(crtStyle); 1125 1126 if (isUsingDefaultStyle && evalStyle == crtStyle) 1127 evalStyle = null; 1128 1129 return evalStyle; 1130 } 1131 1132 1135 protected JRTemplateElement getTemplate(JRStyle style) 1136 { 1137 return (JRTemplateElement) templates.get(style); 1138 } 1139 1140 1143 protected void registerTemplate(JRStyle style, JRTemplateElement template) 1144 { 1145 templates.put(style, template); 1146 } 1147 1148 1149 1156 protected final void setShrinkable(boolean shrinkable) 1157 { 1158 this.shrinkable = shrinkable; 1159 } 1160 1161 1162 1166 protected void stretchHeightFinal() 1167 { 1168 } 1170 1171 1172 protected boolean isEvaluateNow() 1173 { 1174 boolean evaluateNow; 1175 switch (getEvaluationTime()) 1176 { 1177 case JRExpression.EVALUATION_TIME_NOW: 1178 evaluateNow = true; 1179 break; 1180 1181 case JRExpression.EVALUATION_TIME_AUTO: 1182 evaluateNow = isAutoEvaluateNow(); 1183 break; 1184 1185 default: 1186 evaluateNow = false; 1187 break; 1188 } 1189 return evaluateNow; 1190 } 1191 1192 1193 protected boolean isAutoEvaluateNow() 1194 { 1195 return delayedEvaluationsMap == null || delayedEvaluationsMap.isEmpty() 1196 || (delayedEvaluationsMap.size() == 1 1197 && delayedEvaluationsMap.containsKey(JREvaluationTime.EVALUATION_TIME_NOW)); 1198 } 1199 1200 1201 protected boolean isEvaluateAuto() 1202 { 1203 return getEvaluationTime() == JRExpression.EVALUATION_TIME_AUTO && !isAutoEvaluateNow(); 1204 } 1205} 1206 | Popular Tags |