1 package fr.improve.struts.taglib.layout.collection; 2 3 import java.text.DecimalFormat ; 4 import java.text.DecimalFormatSymbols ; 5 import java.util.List ; 6 7 import javax.servlet.jsp.JspException ; 8 9 import org.apache.commons.logging.Log; 10 import org.apache.commons.logging.LogFactory; 11 import org.apache.struts.Globals; 12 import org.apache.struts.action.ActionMessages; 13 import org.apache.struts.util.ResponseUtils; 14 15 import fr.improve.struts.taglib.layout.BodyLayoutTagSupport; 16 import fr.improve.struts.taglib.layout.WriteTag; 17 import fr.improve.struts.taglib.layout.collection.header.CollectionItemEvent; 18 import fr.improve.struts.taglib.layout.collection.header.MultiLevelHeader; 19 import fr.improve.struts.taglib.layout.el.EvaluationException; 20 import fr.improve.struts.taglib.layout.el.Expression; 21 import fr.improve.struts.taglib.layout.field.AbstractFieldTag; 22 import fr.improve.struts.taglib.layout.field.AbstractModeFieldTag; 23 import fr.improve.struts.taglib.layout.policy.AbstractPolicy; 24 import fr.improve.struts.taglib.layout.util.FormUtils; 25 import fr.improve.struts.taglib.layout.util.LayoutUtils; 26 import fr.improve.struts.taglib.layout.util.TagUtils; 27 48 public class CollectionInputTag extends BodyLayoutTagSupport { 49 protected static final Log LOG = LogFactory.getLog(CollectionInputTag.class); 50 public static final String MATH_ID_PREFIX = "mathData_"; 51 52 private boolean filter = true; 53 54 protected String name; 55 protected String property; 56 protected String title; 57 protected boolean sortable = false; 58 protected String width; 59 protected String size; 60 protected String maxlength; 61 protected String styleClass; 62 63 protected String formName; 64 protected String formProperty; 65 protected String formIndex; 66 protected String keyProperty; 67 68 protected String onchange; 69 protected String onfocus; 70 protected String mathOperation; 71 protected String mathPattern; 72 75 protected boolean useCollectionSelection = false; 76 77 80 protected String policy; 81 82 85 protected short fieldDisplayMode = 2; 86 87 90 protected String inspectFormatter; 91 92 95 protected String editFormatter; 96 protected String jspEditFormatter; 97 protected String jspOnChange; 98 protected String jspStyleClass; 99 100 103 protected String createFormatter; 104 105 108 protected String formatter; 109 110 protected String fieldName; 111 112 115 protected String mode = "E,E,I"; 116 117 120 protected boolean skip = false; 121 public static final String SPAN_KEY = CollectionItemTag.SPAN_KEY; 122 123 126 protected String tooltip; 127 128 131 protected SimpleItemContext context = createItemContext(); 132 133 136 protected CollectionTag parentCollectionTag; 137 138 141 protected SimpleItemContext createItemContext() { 142 return new SimpleItemContext(); 143 } 144 145 148 protected void computeDisplayMode() throws JspException { 149 Integer lc_userDisplayMode = LayoutUtils.getSkin(pageContext.getSession()).getFormUtils().getFieldDisplayMode(pageContext, property); 151 152 if (lc_userDisplayMode == null) { 154 fieldDisplayMode = LayoutUtils.getSkin(pageContext.getSession()).getFormUtils().computeFieldDisplayMode(pageContext, mode); 155 } else { 156 fieldDisplayMode = lc_userDisplayMode.shortValue(); 157 } 158 159 if (fieldDisplayMode!=AbstractModeFieldTag.MODE_NODISPLAY && 161 fieldDisplayMode!=AbstractModeFieldTag.MODE_EDIT && 162 fieldDisplayMode!=AbstractModeFieldTag.MODE_INSPECT) { 163 throw new JspException ("collectionInput only supports edit (E), inspect (I) and not display (N) modes"); 164 } 165 166 int lc_formMode = FormUtils.getFormDisplayMode(pageContext); 168 switch (lc_formMode) { 169 case FormUtils.CREATE_MODE : 170 formatter = createFormatter; 171 break; 172 case FormUtils.EDIT_MODE : 173 formatter = editFormatter; 174 break; 175 case FormUtils.INSPECT_MODE : 176 formatter = inspectFormatter; 177 break; 178 } 179 180 if (formatter==null || formatter.length()==0) formatter = editFormatter; 181 182 } 183 186 protected String doAfterValue() throws JspException { 187 return ""; 189 } 190 193 protected String doBeforeValue() throws JspException { 194 return ""; 196 } 197 198 protected short getEditAuthorizedMode() { 199 if (policy == null) 200 return fr.improve.struts.taglib.layout.field.AbstractFieldTag.MODE_EDIT; 201 202 AbstractPolicy lc_policy = LayoutUtils.getSkin(pageContext.getSession()).getPolicy(); 203 return lc_policy.getAuthorizedDisplayMode(policy, name, property, pageContext); 204 } 205 protected short getInspectAuthorizedMode() { 206 if (policy == null) 207 return fr.improve.struts.taglib.layout.field.AbstractFieldTag.MODE_INSPECT; 208 209 AbstractPolicy lc_policy = LayoutUtils.getSkin(pageContext.getSession()).getPolicy(); 210 short lc_allowedDisplayMode; 211 switch (lc_policy.getAuthorizedDisplayMode(policy, name, property, pageContext)) { 212 case AbstractFieldTag.MODE_DISABLED: 213 lc_allowedDisplayMode = AbstractFieldTag.MODE_DISABLED; 214 break; 215 case AbstractFieldTag.MODE_READONLY: 216 lc_allowedDisplayMode = AbstractFieldTag.MODE_READONLY; 217 break; 218 case AbstractFieldTag.MODE_EDIT: 219 case AbstractFieldTag.MODE_INSPECT : 220 lc_allowedDisplayMode = AbstractFieldTag.MODE_INSPECT; 221 break; 222 case AbstractFieldTag.MODE_HIDDEN: 223 lc_allowedDisplayMode = AbstractFieldTag.MODE_HIDDEN; 224 break; 225 case AbstractFieldTag.MODE_INSPECT_ONLY: 226 lc_allowedDisplayMode = AbstractFieldTag.MODE_INSPECT_ONLY; 227 break; 228 case AbstractFieldTag.MODE_NODISPLAY: 229 lc_allowedDisplayMode = AbstractFieldTag.MODE_NODISPLAY; 230 break; 231 default: 232 throw new IllegalStateException (lc_policy.getClass().getName() + " returns an illegal value"); 233 234 } 235 return lc_allowedDisplayMode; 236 } 237 238 public int doEndLayoutTag() throws JspException { 239 if (skip) { 240 skip = false; 242 parentCollectionTag.incrementColumn(); 243 reset(); 244 return EVAL_PAGE; 245 } 246 247 computeDisplayMode(); 249 250 if (fieldDisplayMode == AbstractFieldTag.MODE_NODISPLAY) { 251 reset(); 253 return EVAL_PAGE; 254 } 255 256 StringBuffer buffer = new StringBuffer (); 258 259 context.title = Expression.evaluate(title, pageContext); 261 context.width = width; 262 context.property = property; 263 context.sortProperty = sortable?property:null; 264 context.mathOperation = mathOperation; 265 context.mathPattern = mathPattern; 266 267 if (parentCollectionTag.isFirst()) { 269 parentCollectionTag.addItem(buffer, context); 270 TagUtils.write(pageContext, buffer.toString()); 271 reset(); 272 return EVAL_PAGE; 273 } 274 275 switch (fieldDisplayMode) { 277 case AbstractFieldTag.MODE_EDIT : 278 fieldDisplayMode = getEditAuthorizedMode(); 279 break; 280 case AbstractFieldTag.MODE_INSPECT : 281 fieldDisplayMode = getInspectAuthorizedMode(); 282 break; 283 } 284 285 if (useCollectionSelection && fieldDisplayMode == AbstractFieldTag.MODE_EDIT && !parentCollectionTag.isCurrentBeanSelected()) { 287 fieldDisplayMode = AbstractFieldTag.MODE_INSPECT; 288 } 289 290 if (fieldDisplayMode == AbstractFieldTag.MODE_NODISPLAY) { 291 context.item = ""; 293 parentCollectionTag.addItem(buffer, context); 294 TagUtils.write(pageContext, buffer.toString()); 295 reset(); 296 return EVAL_PAGE; 297 } else 298 try { 299 300 Object value = null; 302 303 try { 305 fieldName = buildInputFieldName(parentCollectionTag); 306 } catch (EvaluationException e) { 307 TagUtils.saveException(pageContext, e); 308 throw new JspException (e.getMessage()); 309 } 310 311 boolean anyError = false; 313 ActionMessages lc_errors = (ActionMessages) pageContext.findAttribute(Globals.ERROR_KEY); 314 if (lc_errors !=null && lc_errors.get(formProperty)!=null && lc_errors.get(formProperty).hasNext()) { 315 anyError = true; 316 } 317 318 List l_error = LayoutUtils.retrieveErrors(pageContext, Globals.MESSAGES_KEY, fieldName); 321 322 value = buildInputFieldValue(parentCollectionTag, anyError); 324 double lc_mathValue = 0; 325 326 if (mathOperation!=null) { 327 lc_mathValue = LayoutUtils.getDouble(value); 328 parentCollectionTag.storeMathData(lc_mathValue); 329 } 330 331 StringBuffer l_field = new StringBuffer (doBeforeValue()); 333 Object formattedValue = null; 334 if (mathPattern!=null){ 335 DecimalFormatSymbols lc_symbols = new DecimalFormatSymbols (LayoutUtils.getLocale(pageContext)); 336 lc_symbols.setDecimalSeparator('.'); 338 lc_symbols.setMonetaryDecimalSeparator('.'); 339 formattedValue = new DecimalFormat (mathPattern, lc_symbols).format(lc_mathValue); 340 } else { 341 formattedValue = (formatter==null || anyError) ? filter(value) : WriteTag.write(pageContext, value, formatter); 343 } 344 if (fieldDisplayMode == AbstractFieldTag.MODE_EDIT || 345 fieldDisplayMode == AbstractFieldTag.MODE_DISABLED || 346 fieldDisplayMode == AbstractFieldTag.MODE_READONLY) { 347 appendFieldStart(l_field); 349 l_field.append(" name=\""); 350 l_field.append(fieldName); 351 if (l_error != null && !l_error.isEmpty()) { 352 l_field.append("\" class=\"ERROR"); 353 } else { 354 if (styleClass!=null && styleClass.length()!=0) 355 l_field.append("\" class=\""+ styleClass); 356 } 357 if (mathOperation!=null && mathOperation.length()>0){ 358 l_field.append("\" id=\""); 360 if (fieldName!=null) { 361 l_field.append(MATH_ID_PREFIX); 362 l_field.append("t" + parentCollectionTag.getMathOperationId()); 363 l_field.append("l" + parentCollectionTag.getIndex()); 364 l_field.append("c" + parentCollectionTag.getColumn()); 365 } 366 } 367 if (size != null) { 368 l_field.append("\" size=\""); 369 l_field.append(size); 370 } 371 if (maxlength != null) { 372 l_field.append("\" maxlength=\""); 373 l_field.append(maxlength); 374 } 375 if (tooltip!=null) { 376 l_field.append("\" title=\""); 377 l_field.append(LayoutUtils.getLabel(pageContext, Expression.evaluate(tooltip, pageContext), null)); 378 } 379 if (onchange != null) { 380 l_field.append("\" onchange=\""); 381 l_field.append(Expression.evaluate(onchange, pageContext)); 382 } 383 if (onfocus != null) { 384 l_field.append("\" onfocus=\""); 385 l_field.append(Expression.evaluate(onfocus, pageContext)); 386 } 387 l_field.append("\""); 388 if (fieldDisplayMode == AbstractFieldTag.MODE_DISABLED){ 389 l_field.append(" disabled"); 390 } 391 if (fieldDisplayMode == AbstractFieldTag.MODE_READONLY){ 392 l_field.append(" readonly=\"true\""); 393 } 394 appendFieldValue(l_field, formattedValue); 395 String addition = buildAdditionalAttributes(parentCollectionTag); 396 l_field.append(addition!=null && addition.length()>0 ? " " + addition : ""); 397 l_field.append(">"); 398 } else if (fieldDisplayMode == AbstractFieldTag.MODE_INSPECT) { 399 l_field.append("<input type=\"hidden\" name=\""); 401 l_field.append(fieldName); 402 l_field.append("\" value=\""); 403 l_field.append(formattedValue==null ? "" : formattedValue); 404 l_field.append("\">"); 405 appendInspectFieldValue(l_field, formattedValue); 406 } else { 407 appendInspectFieldValue(l_field, formattedValue); 408 } 409 410 l_field.append(doAfterValue()); 411 412 context.item = l_field.toString(); 414 parentCollectionTag.addItem(buffer, context); 415 416 TagUtils.write(pageContext, buffer.toString()); 418 419 } catch (ClassCastException e) { 420 LOG.error("Fail to build input column", e); 421 TagUtils.saveException(pageContext, e); 422 throw new JspException ("Invalid use of collectionInput tag"); 423 } catch (NullPointerException e) { 424 LOG.error("Fail to build input column", e); 425 TagUtils.saveException(pageContext, e); 426 throw new JspException ("Invalid use of collectionInput tag"); 427 } 428 reset(); 429 return EVAL_PAGE; 430 } 431 432 protected void appendInspectFieldValue(StringBuffer in_buffer, Object in_value) { 433 in_buffer.append(in_value == null ? "" : in_value); 434 } 435 436 protected void appendFieldValue(StringBuffer in_buffer, Object in_value) { 437 in_buffer.append(" value=\""); 438 in_buffer.append(in_value==null ? "": in_value); 439 in_buffer.append("\""); 440 } 441 442 protected void appendFieldStart(StringBuffer in_buffer) { 443 in_buffer.append("<input type=\""); 444 in_buffer.append(getType()); 445 in_buffer.append("\""); 446 } 447 protected Object buildInputFieldValue(CollectionTag in_parent, boolean in_anyError) throws JspException { 448 449 Object value = null; 451 452 String lc_fieldName = buildInputFieldName(in_parent); 453 value = LayoutUtils.getBeanFromPageContext(pageContext, lc_fieldName); 454 455 if (value == null) { 457 458 if (bodyContent != null && bodyContent.getString().length() > 0) { 459 value = bodyContent.getString(); 461 462 } else { 463 if (name == null) { 464 value = LayoutUtils.getProperty(in_parent.getBean(), property); 466 } else { 467 value = LayoutUtils.getBeanFromPageContext(pageContext, name, property); 469 } 470 } 471 } 472 473 return value; 474 } 475 476 protected String getType() { 477 return "text"; 478 } 479 480 protected String buildAdditionalAttributes(CollectionTag in_parent) throws JspException { 481 return ""; 482 } 483 484 public int doStartLayoutTag() throws JspException { 485 try { 486 initDynamicValues(); 487 context.reset(); 488 if (parentCollectionTag.isFirst()) { 489 MultiLevelHeader lc_header = new MultiLevelHeader(title, null, null, styleClass, true); 490 lc_header.setWidth(width); 491 lc_header.setSortProperty(sortable ? property : null); 492 new CollectionItemEvent(this, lc_header).send(); 493 return evaluateFirstBody(); 494 } 495 496 if (name!=null) { 497 if (parentCollectionTag.isNestedIteration() && !parentCollectionTag.getSpans().containsKey(name)) { 499 skip = true; 500 return SKIP_BODY; 501 } else { 502 pageContext.setAttribute(SPAN_KEY, parentCollectionTag.getSpans().get(name)); 503 } 504 } 505 } catch (ClassCastException e) { 506 LOG.error(e); 507 throw new JspException ("Invalid use of collectionInput tag"); 508 } catch (NullPointerException e) { 509 LOG.error(e); 510 throw new JspException ("Invalid use of collectionInput tag"); 511 } 512 return evaluateNextBody(); 513 } 514 515 protected int evaluateFirstBody() { 516 return SKIP_BODY; 517 } 518 protected int evaluateNextBody() { 519 return EVAL_BODY_TAG; 520 } 521 522 protected void initDynamicValues() throws JspException { 523 parentCollectionTag = (CollectionTag) findAncestorWithClass(this, CollectionTag.class); 524 String lc_col = String.valueOf(parentCollectionTag.getColumn()); 525 jspEditFormatter = editFormatter; 526 527 jspStyleClass = styleClass; 528 if (styleClass==null){ 529 styleClass = LayoutUtils.getSkin(pageContext.getSession()).getProperty("styleclass.collection",null); 530 } 531 editFormatter = Expression.evaluate(editFormatter, pageContext); 532 if (mathOperation!=null){ 533 534 try { 536 fieldName = buildInputFieldName(parentCollectionTag); 537 } catch (EvaluationException e) { 538 TagUtils.saveException(pageContext, e); 539 throw new JspException (e.getMessage()); 540 } 541 542 boolean anyError = false; 544 ActionMessages lc_errors = (ActionMessages) pageContext.findAttribute(Globals.ERROR_KEY); 545 if (lc_errors !=null && lc_errors.get(formProperty)!=null && lc_errors.get(formProperty).hasNext()) { 546 anyError = true; 547 } 548 double lc_value = LayoutUtils.getDouble(buildInputFieldValue(parentCollectionTag, anyError)); 549 550 String lc_result = String.valueOf(lc_value); 551 if (mathPattern!=null){ 552 DecimalFormatSymbols lc_symbols = new DecimalFormatSymbols (LayoutUtils.getLocale(pageContext)); 553 lc_symbols.setDecimalSeparator('.'); 554 lc_symbols.setMonetaryDecimalSeparator('.'); 555 lc_result = new DecimalFormat (mathPattern, lc_symbols).format(lc_value); 556 } 557 558 jspOnChange = onchange; 559 onchange = Expression.evaluate(onchange,pageContext); 560 onchange = (onchange==null?"":onchange + ";") 561 + "mathDataUpdate('" 562 + mathOperation 563 + "','" 564 + MATH_ID_PREFIX + "t" + parentCollectionTag.getMathOperationId() + "r" + lc_col 565 + "','" 566 + parentCollectionTag.getMathOperationId() 567 + "','" 568 + lc_col 569 + "','" 570 + parentCollectionTag.getSize() 571 + "','" 572 + lc_result 573 + "')"; 574 } 575 } 576 577 protected void reset() { 578 editFormatter = jspEditFormatter; 579 jspEditFormatter = null; 580 styleClass = jspStyleClass; 581 jspStyleClass = null; 582 if (mathOperation!=null){ 583 onchange = jspOnChange; 584 jspOnChange = null; 585 } 586 parentCollectionTag = null; 587 } 588 589 590 595 public java.lang.String getCreateFormatter() { 596 return createFormatter; 597 } 598 603 public java.lang.String getEditFormatter() { 604 return editFormatter; 605 } 606 611 public java.lang.String getFormIndex() { 612 return formIndex; 613 } 614 619 public java.lang.String getFormProperty() { 620 return formProperty; 621 } 622 627 public java.lang.String getInspectFormatter() { 628 return inspectFormatter; 629 } 630 635 public java.lang.String getSize() { 636 return size; 637 } 638 639 public java.lang.String getMaxlength() { 640 return maxlength; 641 } 642 public void release() { 643 super.release(); 644 645 property = null; 647 title = null; 648 name = null; 649 size = null; 650 maxlength = null; 651 652 onchange = null; 654 onfocus = null; 655 656 sortable = false; 657 width = null; 658 659 inspectFormatter = null; 660 editFormatter = null; 661 662 formIndex = null; 664 formName = null; 665 formProperty = null; 666 keyProperty = null; 667 tooltip = null; 668 669 fieldDisplayMode = 2; 671 policy = null; 672 useCollectionSelection = false; 673 mode = "E,E,I"; 674 675 fieldName = null; 676 skip = false; 677 filter = true; 678 679 mathOperation = null; 680 mathPattern = null; 681 } 682 683 688 public void setCreateFormatter(java.lang.String newCreateFormatter) { 689 createFormatter = newCreateFormatter; 690 } 691 696 public void setEditFormatter(java.lang.String newEditFormatter) { 697 editFormatter = newEditFormatter; 698 } 699 704 public void setFormIndex(java.lang.String newFormIndex) { 705 formIndex = newFormIndex; 706 } 707 712 public void setFormProperty(java.lang.String newFormProperty) { 713 formProperty = newFormProperty; 714 } 715 720 public void setInspectFormatter(java.lang.String newInspectFormatter) { 721 inspectFormatter = newInspectFormatter; 722 } 723 727 public void setMode(String in_mode) throws JspException { 728 mode = in_mode; 729 } 730 public void setName(String name) { 731 this.name = name; 732 } 733 738 public void setProperty(java.lang.String newProperty) { 739 property = newProperty; 740 } 741 746 public void setSize(java.lang.String newSize) { 747 size = newSize; 748 } 749 public void setMaxlength(java.lang.String newMaxlength) { 750 maxlength = newMaxlength; 751 } 752 753 public void setSortable(String sortable) { 754 if ("true".equalsIgnoreCase(sortable)) this.sortable = true; 755 } 756 761 public void setTitle(java.lang.String newHeader) { 762 title = newHeader; 763 } 764 768 public String getWidth() { 769 return width; 770 } 771 772 776 public void setWidth(String width) { 777 this.width = width; 778 } 779 780 784 public void setKeyProperty(String keyProperty) { 785 this.keyProperty = keyProperty; 786 } 787 788 792 public void setOnchange(String onchange) { 793 this.onchange = onchange; 794 } 795 796 800 public void setOnfocus(String onfocus) { 801 this.onfocus = onfocus; 802 } 803 804 808 public String getPolicy() { 809 return policy; 810 } 811 812 816 public void setPolicy(String policy) { 817 this.policy = policy; 818 } 819 820 823 public void setTooltip(String tooltip) { 824 this.tooltip = tooltip; 825 } 826 827 831 public void setUseCollectionSelection(boolean useCollectionSelection) { 832 this.useCollectionSelection = useCollectionSelection; 833 } 834 835 public String getFormName() { 836 return formName; 837 } 838 839 public void setFormName(String in_string) { 840 formName = in_string; 841 } 842 843 public String getMathOperation() { 844 return mathOperation; 845 } 846 public String getStyleClass() { 847 return styleClass; 848 } 849 public void setStyleClass(String styleClass) { 850 this.styleClass = styleClass; 851 } 852 public void setMathOperation(String mathOperation) { 853 this.mathOperation = mathOperation; 854 } 855 856 public String getMathPattern() { 857 return mathPattern; 858 } 859 public void setMathPattern(String mathPattern) { 860 this.mathPattern = mathPattern; 861 } 862 protected String buildInputFieldName(CollectionTag in_parent) throws JspException , EvaluationException { 863 String lc_evaluatedFormProperty = Expression.evaluate(formProperty, pageContext); 864 if (lc_evaluatedFormProperty!=null && !lc_evaluatedFormProperty.equals(formProperty)) { 865 return lc_evaluatedFormProperty; 866 } else { 867 StringBuffer lc_fieldNameBuffer = new StringBuffer (); 868 if (formName!=null) { 869 lc_fieldNameBuffer.append(formName); 870 lc_fieldNameBuffer.append("."); 871 } 872 lc_fieldNameBuffer.append(formProperty); 873 if (keyProperty==null) { 874 lc_fieldNameBuffer.append("["); 875 if (formIndex == null) { 876 lc_fieldNameBuffer.append(in_parent.getIndex()); 877 } else { 878 lc_fieldNameBuffer.append(pageContext.findAttribute(formIndex)); 879 } 880 lc_fieldNameBuffer.append("]"); 881 } else { 882 lc_fieldNameBuffer.append("("); 883 lc_fieldNameBuffer.append(LayoutUtils.getProperty(in_parent.getBean(), keyProperty)); 884 lc_fieldNameBuffer.append(")"); 885 } 886 return lc_fieldNameBuffer.toString(); 887 } 888 } 889 890 893 protected Object filter(Object in_value) { 894 if (filter) { 895 if (in_value==null) { 896 return null; 897 } else { 898 return ResponseUtils.filter(in_value.toString()); 899 } 900 } else { 901 return in_value; 902 } 903 } 904 public boolean isFilter() { 905 return filter; 906 } 907 public void setFilter(boolean filter) { 908 this.filter = filter; 909 } 910 } 911 | Popular Tags |