1 16 17 package org.apache.struts.faces.taglib; 18 19 import java.io.IOException ; 20 import java.util.ArrayList ; 21 import java.util.Collections ; 22 import java.util.Comparator ; 23 import java.util.Iterator ; 24 import java.util.List ; 25 import java.util.Locale ; 26 import java.util.Map ; 27 28 import javax.faces.component.UIComponent; 29 import javax.faces.context.FacesContext; 30 import javax.faces.webapp.UIComponentTag; 31 import javax.servlet.http.HttpServletRequest ; 32 import javax.servlet.jsp.JspException ; 33 import javax.servlet.jsp.JspWriter ; 34 import javax.servlet.jsp.PageContext ; 35 import javax.servlet.jsp.tagext.BodyTagSupport ; 36 import javax.servlet.jsp.tagext.Tag ; 37 38 import org.apache.commons.validator.Field; 39 import org.apache.commons.validator.Form; 40 import org.apache.commons.validator.ValidatorAction; 41 import org.apache.commons.validator.ValidatorResources; 42 import org.apache.commons.validator.Var; 43 import org.apache.commons.validator.util.ValidatorUtils; 44 import org.apache.struts.Globals; 45 import org.apache.struts.config.ModuleConfig; 46 import org.apache.struts.faces.component.FormComponent; 47 import org.apache.struts.taglib.TagUtils; 48 import org.apache.struts.util.MessageResources; 49 import org.apache.struts.util.ModuleUtils; 50 import org.apache.struts.validator.Resources; 51 import org.apache.struts.validator.ValidatorPlugIn; 52 53 63 public class JavascriptValidatorTag extends BodyTagSupport { 64 65 67 70 protected String bundle = Globals.MESSAGES_KEY; 71 72 76 protected static Locale defaultLocale = Locale.getDefault(); 77 78 83 protected String formName = null; 84 85 88 protected static String lineEnd = System.getProperty("line.separator"); 89 90 94 protected int page = 0; 95 96 100 protected String methodName = null; 101 102 105 protected String staticJavascript = "true"; 106 107 110 protected String dynamicJavascript = "true"; 111 112 117 protected String src = null; 118 119 122 protected String htmlComment = "true"; 123 124 127 protected String cdata = "true"; 128 129 private String htmlBeginComment = "\n<!-- Begin \n"; 130 131 private String htmlEndComment = "//End --> \n"; 132 133 138 public String getFormName() { 139 return formName; 140 } 141 142 149 public void setFormName(String formName) { 150 this.formName = formName; 151 } 152 153 159 public int getPage() { 160 return page; 161 } 162 163 169 public void setPage(int page) { 170 this.page = page; 171 } 172 173 179 public String getMethod() { 180 return methodName; 181 } 182 183 189 public void setMethod(String methodName) { 190 this.methodName = methodName; 191 } 192 193 198 public String getStaticJavascript() { 199 return staticJavascript; 200 } 201 202 207 public void setStaticJavascript(String staticJavascript) { 208 this.staticJavascript = staticJavascript; 209 } 210 211 216 public String getDynamicJavascript() { 217 return dynamicJavascript; 218 } 219 220 225 public void setDynamicJavascript(String dynamicJavascript) { 226 this.dynamicJavascript = dynamicJavascript; 227 } 228 229 234 public String getHtmlComment() { 235 return htmlComment; 236 } 237 238 243 public void setHtmlComment(String htmlComment) { 244 this.htmlComment = htmlComment; 245 } 246 247 251 public String getSrc() { 252 return src; 253 } 254 255 260 public void setSrc(String src) { 261 this.src = src; 262 } 263 264 269 public int doStartTag() throws JspException { 270 StringBuffer results = new StringBuffer (); 271 272 HttpServletRequest request = (HttpServletRequest )pageContext.getRequest(); 273 ModuleConfig config = ModuleUtils.getInstance().getModuleConfig(request); 274 ValidatorResources resources = 275 (ValidatorResources) pageContext.getAttribute( 276 ValidatorPlugIn.VALIDATOR_KEY + config.getPrefix(), 277 PageContext.APPLICATION_SCOPE); 278 279 Locale locale = TagUtils.getInstance().getUserLocale(pageContext, null); 280 281 Form form = resources.getForm(locale, formName); 282 if (form != null) { 283 if ("true".equalsIgnoreCase(dynamicJavascript)) { 284 MessageResources messages = 285 (MessageResources) pageContext.getAttribute( 286 bundle + config.getPrefix(), 287 PageContext.APPLICATION_SCOPE); 288 289 List lActions = new ArrayList (); 290 List lActionMethods = new ArrayList (); 291 292 for (Iterator i = form.getFields().iterator(); i.hasNext();) { 294 Field field = (Field) i.next(); 295 296 for (Iterator x = field.getDependencyList().iterator(); x.hasNext();) { 297 Object o = x.next(); 298 299 if (o != null && !lActionMethods.contains(o)) { 300 lActionMethods.add(o); 301 } 302 } 303 304 } 305 306 for (Iterator i = lActionMethods.iterator(); i.hasNext();) { 308 String depends = (String ) i.next(); 309 ValidatorAction va = resources.getValidatorAction(depends); 310 311 if (va == null) { 313 throw new NullPointerException ( 314 "Depends string \"" 315 + depends 316 + "\" was not found in validator-rules.xml."); 317 } 318 319 String javascript = va.getJavascript(); 320 if (javascript != null && javascript.length() > 0) { 321 lActions.add(va); 322 } else { 323 i.remove(); 324 } 325 } 326 327 Collections.sort(lActions, new Comparator () { 328 public int compare(Object o1, Object o2) { 329 ValidatorAction va1 = (ValidatorAction) o1; 330 ValidatorAction va2 = (ValidatorAction) o2; 331 332 if ((va1.getDepends() == null || va1.getDepends().length() == 0) 333 && (va2.getDepends() == null || va2.getDepends().length() == 0)) { 334 return 0; 335 } else if ( 336 (va1.getDepends() != null && va1.getDepends().length() > 0) 337 && (va2.getDepends() == null || va2.getDepends().length() == 0)) { 338 return 1; 339 } else if ( 340 (va1.getDepends() == null || va1.getDepends().length() == 0) 341 && (va2.getDepends() != null && va2.getDepends().length() > 0)) { 342 return -1; 343 } else { 344 return va1.getDependencyList().size() - va2.getDependencyList().size(); 345 } 346 } 347 }); 348 349 String methods = null; 350 for (Iterator i = lActions.iterator(); i.hasNext();) { 351 ValidatorAction va = (ValidatorAction) i.next(); 352 353 if (methods == null) { 354 methods = va.getMethod() + "(form)"; 355 } else { 356 methods += " && " + va.getMethod() + "(form)"; 357 } 358 } 359 360 results.append(getJavascriptBegin(methods)); 361 362 for (Iterator i = lActions.iterator(); i.hasNext();) { 363 ValidatorAction va = (ValidatorAction) i.next(); 364 String jscriptVar = null; 365 String functionName = null; 366 367 if (va.getJsFunctionName() != null && va.getJsFunctionName().length() > 0) { 368 functionName = va.getJsFunctionName(); 369 } else { 370 functionName = va.getName(); 371 } 372 373 if (isStruts11()) { 374 results.append(" function " + 375 functionName + " () { \n"); 376 } else { 377 results.append(" function " + 378 formName + "_" + functionName + " () { \n"); 379 } 380 for (Iterator x = form.getFields().iterator(); x.hasNext();) { 381 Field field = (Field) x.next(); 382 383 if (field.isIndexed() 386 || field.getPage() != page 387 || !field.isDependency(va.getName())) { 388 389 continue; 390 } 391 392 String message = 393 Resources.getMessage(messages, locale, va, field); 394 395 message = (message != null) ? message : ""; 396 397 jscriptVar = this.getNextVar(jscriptVar); 398 399 results.append( 400 " this." 401 + jscriptVar 402 + " = new Array(\"" 403 + getFormClientId() 404 + ":" 405 + field.getKey() 406 + "\", \"" 407 + message 408 + "\", "); 409 410 results.append("new Function (\"varName\", \""); 411 412 Map vars = field.getVars(); 413 Iterator varsIterator = vars.keySet().iterator(); 415 while (varsIterator.hasNext()) { 416 String varName = (String ) varsIterator.next(); 417 Var var = (Var) vars.get(varName); 418 String varValue = var.getValue(); 419 String jsType = var.getJsType(); 420 421 if (varName.startsWith("field")) { 423 continue; 424 } 425 426 if (Var.JSTYPE_INT.equalsIgnoreCase(jsType)) { 427 results.append( 428 "this." 429 + varName 430 + "=" 431 + ValidatorUtils.replace( 432 varValue, 433 "\\", 434 "\\\\") 435 + "; "); 436 } else if (Var.JSTYPE_REGEXP.equalsIgnoreCase(jsType)) { 437 results.append( 438 "this." 439 + varName 440 + "=/" 441 + ValidatorUtils.replace( 442 varValue, 443 "\\", 444 "\\\\") 445 + "/; "); 446 } else if (Var.JSTYPE_STRING.equalsIgnoreCase(jsType)) { 447 results.append( 448 "this." 449 + varName 450 + "='" 451 + ValidatorUtils.replace( 452 varValue, 453 "\\", 454 "\\\\") 455 + "'; "); 456 } else if ("mask".equalsIgnoreCase(varName)) { 458 results.append( 459 "this." 460 + varName 461 + "=/" 462 + ValidatorUtils.replace( 463 varValue, 464 "\\", 465 "\\\\") 466 + "/; "); 467 } else { 468 results.append( 469 "this." 470 + varName 471 + "='" 472 + ValidatorUtils.replace( 473 varValue, 474 "\\", 475 "\\\\") 476 + "'; "); 477 } 478 } 479 480 results.append(" return this[varName];\"));\n"); 481 } 482 results.append(" } \n\n"); 483 } 484 } else if ("true".equalsIgnoreCase(staticJavascript)) { 485 results.append(this.getStartElement()); 486 if ("true".equalsIgnoreCase(htmlComment)) { 487 results.append(htmlBeginComment); 488 } 489 } 490 } 491 492 if ("true".equalsIgnoreCase(staticJavascript)) { 493 results.append(getJavascriptStaticMethods(resources)); 494 } 495 496 if (form != null 497 && ("true".equalsIgnoreCase(dynamicJavascript) 498 || "true".equalsIgnoreCase(staticJavascript))) { 499 500 results.append(getJavascriptEnd()); 501 } 502 503 504 JspWriter writer = pageContext.getOut(); 505 try { 506 writer.print(results.toString()); 507 } catch (IOException e) { 508 throw new JspException (e.getMessage()); 509 } 510 511 return (EVAL_BODY_TAG); 512 513 } 514 515 518 public void release() { 519 super.release(); 520 bundle = Globals.MESSAGES_KEY; 521 formName = null; 522 page = 0; 523 methodName = null; 524 staticJavascript = "true"; 525 dynamicJavascript = "true"; 526 htmlComment = "true"; 527 cdata = "true"; 528 src = null; 529 formClientId = null; 530 } 531 532 535 protected String getJavascriptBegin(String methods) { 536 StringBuffer sb = new StringBuffer (); 537 String name = 538 formName.substring(0, 1).toUpperCase() 539 + formName.substring(1, formName.length()); 540 541 sb.append(this.getStartElement()); 542 543 if (this.isXhtml() && "true".equalsIgnoreCase(this.cdata)) { 544 sb.append("<![CDATA[\r\n"); 545 } 546 547 if (!this.isXhtml() && "true".equals(htmlComment)) { 548 sb.append(htmlBeginComment); 549 } 550 sb.append("\n var bCancel = false; \n\n"); 551 552 if (methodName == null || methodName.length() == 0) { 553 sb.append( 554 " function validate" 555 + name 556 + "(form) { \n"); 557 } else { 558 sb.append( 559 " function " 560 + methodName 561 + "(form) { \n"); 562 } 563 sb.append(" if (bCancel) \n"); 564 sb.append(" return true; \n"); 565 sb.append(" else \n"); 566 567 if (methods == null || methods.length() == 0) { 569 sb.append(" return true; \n"); 570 } else { 571 sb.append(" return " + methods + "; \n"); 572 } 573 574 sb.append(" } \n\n"); 575 576 return sb.toString(); 577 } 578 579 protected String getJavascriptStaticMethods(ValidatorResources resources) { 580 StringBuffer sb = new StringBuffer (); 581 582 sb.append("\n\n"); 583 584 Iterator actions = resources.getValidatorActions().values().iterator(); 585 while (actions.hasNext()) { 586 ValidatorAction va = (ValidatorAction) actions.next(); 587 if (va != null) { 588 String javascript = va.getJavascript(); 589 if (javascript != null && javascript.length() > 0) { 590 sb.append(javascript + "\n"); 591 } 592 } 593 } 594 595 return sb.toString(); 596 } 597 598 601 protected String getJavascriptEnd() { 602 StringBuffer sb = new StringBuffer (); 603 604 sb.append("\n"); 605 if (!this.isXhtml() && "true".equals(htmlComment)){ 606 sb.append(htmlEndComment); 607 } 608 609 if (this.isXhtml() && "true".equalsIgnoreCase(this.cdata)) { 610 sb.append("]]>\r\n"); 611 } 612 613 sb.append("</script>\n\n"); 614 615 return sb.toString(); 616 } 617 618 622 private String getNextVar(String input) { 623 if (input == null) { 624 return "aa"; 625 } 626 627 input = input.toLowerCase(); 628 629 for (int i = input.length(); i > 0; i--) { 630 int pos = i - 1; 631 632 char c = input.charAt(pos); 633 c++; 634 635 if (c <= 'z') { 636 if (i == 0) { 637 return c + input.substring(pos, input.length()); 638 } else if (i == input.length()) { 639 return input.substring(0, pos) + c; 640 } else { 641 return input.substring(0, pos) + c + input.substring(pos, input.length() - 1); 642 } 643 } else { 644 input = replaceChar(input, pos, 'a'); 645 } 646 647 } 648 649 return null; 650 651 } 652 653 656 private String replaceChar(String input, int pos, char c) { 657 if (pos == 0) { 658 return c + input.substring(pos, input.length()); 659 } else if (pos == input.length()) { 660 return input.substring(0, pos) + c; 661 } else { 662 return input.substring(0, pos) + c + input.substring(pos, input.length() - 1); 663 } 664 } 665 666 669 private String getStartElement() { 670 StringBuffer start = new StringBuffer ("<script type=\"text/javascript\""); 671 672 if (!this.isXhtml()) { 674 start.append(" language=\"Javascript1.1\""); 675 } 676 677 if (this.src != null) { 678 start.append(" SRC=\"" + src + "\""); 679 } 680 681 start.append("> \n"); 682 return start.toString(); 683 } 684 685 688 private boolean isXhtml() { 689 return TagUtils.getInstance().isXhtml(this.pageContext); 690 } 691 692 696 public String getCdata() { 697 return cdata; 698 } 699 700 704 public void setCdata(String cdata) { 705 this.cdata = cdata; 706 } 707 708 709 private String formClientId = null; 710 711 718 private String getFormClientId(){ 719 720 if (formClientId != null) { 722 return (formClientId); 723 } 724 725 Tag parent = getParent(); 727 while (parent != null) { 728 if (parent instanceof UIComponentTag) { 729 break; 730 } 731 parent = parent.getParent(); 732 } 733 if (parent == null) { 734 throw new IllegalArgumentException 735 ("Not nested inside a UIComponentTag"); 736 } 737 738 UIComponent parentComponent = 740 ((UIComponentTag) parent).getComponentInstance(); 741 if (parentComponent instanceof FormComponent) { 742 if (formName.equals(parentComponent.getAttributes().get("beanName"))) { 743 formClientId = parentComponent.getClientId 744 (FacesContext.getCurrentInstance()); 745 return (formClientId); 746 } 747 } 748 749 Iterator kids = ((UIComponentTag) parent). 751 getComponentInstance().getChildren().iterator(); 752 while (kids.hasNext()) { 753 UIComponent kid = (UIComponent) kids.next(); 754 if (!(kid instanceof FormComponent)) { 755 continue; 756 } 757 if (formName.equals(kid.getAttributes().get("beanName"))) { 758 formClientId = 759 kid.getClientId(FacesContext.getCurrentInstance()); 760 return (formClientId); 761 } 762 } 763 throw new IllegalArgumentException 764 ("Cannot find child FormComponent for form '" + formName + "'"); 765 766 } 767 768 769 771 772 private static boolean struts11; 773 774 static { 775 try { 776 JavascriptValidatorTag.class.getClassLoader().loadClass 777 ("org.apache.struts.taglib.TagUtils"); 778 struts11 = false; 779 } catch (Exception e) { 780 struts11 = true; 781 } 782 } 783 784 785 788 private static boolean isStruts11() { 789 return struts11; 790 } 791 792 793 } 794 | Popular Tags |