1 18 19 package org.apache.struts.taglib; 20 21 import java.io.IOException ; 22 import java.lang.reflect.InvocationTargetException ; 23 import java.net.MalformedURLException ; 24 import java.util.HashMap ; 25 import java.util.Iterator ; 26 import java.util.Locale ; 27 import java.util.Map ; 28 29 import javax.servlet.http.HttpServletRequest ; 30 import javax.servlet.http.HttpServletResponse ; 31 import javax.servlet.http.HttpSession ; 32 import javax.servlet.jsp.JspException ; 33 import javax.servlet.jsp.JspWriter ; 34 import javax.servlet.jsp.PageContext ; 35 import javax.servlet.jsp.tagext.BodyContent ; 36 37 import org.apache.commons.beanutils.PropertyUtils; 38 import org.apache.commons.logging.Log; 39 import org.apache.commons.logging.LogFactory; 40 import org.apache.struts.Globals; 41 import org.apache.struts.action.ActionErrors; 42 import org.apache.struts.action.ActionMessage; 43 import org.apache.struts.action.ActionMessages; 44 import org.apache.struts.config.ForwardConfig; 45 import org.apache.struts.config.ModuleConfig; 46 import org.apache.struts.taglib.html.Constants; 47 import org.apache.struts.util.MessageResources; 48 import org.apache.struts.util.ModuleUtils; 49 import org.apache.struts.util.RequestUtils; 50 import org.apache.struts.util.ResponseUtils; 51 52 58 public class TagUtils { 59 60 63 private static final TagUtils instance = new TagUtils(); 64 65 68 private static final Log log = LogFactory.getLog(TagUtils.class); 69 70 74 private static final MessageResources messages = 75 MessageResources.getMessageResources("org.apache.struts.taglib.LocalStrings"); 76 77 81 private static final Map scopes = new HashMap (); 82 83 86 static { 87 scopes.put("page", new Integer (PageContext.PAGE_SCOPE)); 88 scopes.put("request", new Integer (PageContext.REQUEST_SCOPE)); 89 scopes.put("session", new Integer (PageContext.SESSION_SCOPE)); 90 scopes.put("application", new Integer (PageContext.APPLICATION_SCOPE)); 91 } 92 93 96 protected TagUtils() { 97 super(); 98 } 99 100 103 public static TagUtils getInstance() { 104 return instance; 105 } 106 107 137 public Map computeParameters( 138 PageContext pageContext, 139 String paramId, 140 String paramName, 141 String paramProperty, 142 String paramScope, 143 String name, 144 String property, 145 String scope, 146 boolean transaction) 147 throws JspException { 148 149 if ((paramId == null) && (name == null) && !transaction) { 151 return (null); 152 } 153 154 Map map = null; 156 try { 157 if (name != null) { 158 map = 159 (Map ) TagUtils.getInstance().lookup( 160 pageContext, 161 name, 162 property, 163 scope); 164 } 165 } catch (ClassCastException e) { 166 saveException(pageContext, e); 167 throw new JspException ( 168 messages.getMessage("parameters.multi", name, property, scope)); 169 170 } catch (JspException e) { 171 saveException(pageContext, e); 172 throw e; 173 } 174 175 Map results = null; 177 if (map != null) { 178 results = new HashMap (map); 179 } else { 180 results = new HashMap (); 181 } 182 183 if ((paramId != null) && (paramName != null)) { 185 186 Object paramValue = null; 187 try { 188 paramValue = 189 TagUtils.getInstance().lookup( 190 pageContext, 191 paramName, 192 paramProperty, 193 paramScope); 194 195 } catch (JspException e) { 196 saveException(pageContext, e); 197 throw e; 198 } 199 200 if (paramValue != null) { 201 202 String paramString = null; 203 if (paramValue instanceof String ) { 204 paramString = (String ) paramValue; 205 } else { 206 paramString = paramValue.toString(); 207 } 208 209 Object mapValue = results.get(paramId); 210 if (mapValue == null) { 211 results.put(paramId, paramString); 212 213 } else if (mapValue instanceof String []) { 214 String oldValues[] = (String []) mapValue; 215 String newValues[] = new String [oldValues.length + 1]; 216 System.arraycopy(oldValues, 0, newValues, 0, oldValues.length); 217 newValues[oldValues.length] = paramString; 218 results.put(paramId, newValues); 219 220 } else { 221 String newValues[] = new String [2]; 222 newValues[0] = mapValue.toString(); 223 newValues[1] = paramString; 224 results.put(paramId, newValues); 225 } 226 227 } 228 229 } 230 231 if (transaction) { 233 HttpSession session = pageContext.getSession(); 234 String token = null; 235 if (session != null) { 236 token = (String ) session.getAttribute(Globals.TRANSACTION_TOKEN_KEY); 237 } 238 239 if (token != null) { 240 results.put(Constants.TOKEN_KEY, token); 241 } 242 } 243 244 return (results); 246 247 } 248 249 public String computeURL( 250 PageContext pageContext, 251 String forward, 252 String href, 253 String page, 254 String action, 255 String module, 256 Map params, 257 String anchor, 258 boolean redirect) 259 throws MalformedURLException { 260 return this.computeURLWithCharEncoding( 261 pageContext, 262 forward, 263 href, 264 page, 265 action, 266 module, 267 params, 268 anchor, 269 redirect, 270 false); 271 } 272 273 298 public String computeURLWithCharEncoding( 299 PageContext pageContext, 300 String forward, 301 String href, 302 String page, 303 String action, 304 String module, 305 Map params, 306 String anchor, 307 boolean redirect, 308 boolean useLocalEncoding) 309 throws MalformedURLException { 310 311 return computeURLWithCharEncoding( 312 pageContext, 313 forward, 314 href, 315 page, 316 action, 317 module, 318 params, 319 anchor, 320 redirect, 321 true, 322 useLocalEncoding); 323 } 324 325 public String computeURL( 326 PageContext pageContext, 327 String forward, 328 String href, 329 String page, 330 String action, 331 String module, 332 Map params, 333 String anchor, 334 boolean redirect, 335 boolean encodeSeparator) 336 throws MalformedURLException { 337 return computeURLWithCharEncoding( 338 pageContext, 339 forward, 340 href, 341 page, 342 action, 343 module, 344 params, 345 anchor, 346 redirect, 347 encodeSeparator, 348 false 349 ); 350 } 351 352 383 public String computeURLWithCharEncoding( 384 PageContext pageContext, 385 String forward, 386 String href, 387 String page, 388 String action, 389 String module, 390 Map params, 391 String anchor, 392 boolean redirect, 393 boolean encodeSeparator, 394 boolean useLocalEncoding) 395 throws MalformedURLException { 396 String charEncoding = "UTF-8"; 397 if(useLocalEncoding){ 398 charEncoding = pageContext.getResponse().getCharacterEncoding(); 399 } 400 401 403 int n = 0; 405 if (forward != null) { 406 n++; 407 } 408 if (href != null) { 409 n++; 410 } 411 if (page != null) { 412 n++; 413 } 414 if (action != null) { 415 n++; 416 } 417 if (n != 1) { 418 throw new MalformedURLException (messages.getMessage("computeURL.specifier")); 419 } 420 421 ModuleConfig moduleConfig = instance.getModuleConfig(module, pageContext); 423 424 StringBuffer url = new StringBuffer (); 426 HttpServletRequest request = (HttpServletRequest ) pageContext.getRequest(); 427 if (forward != null) { 428 ForwardConfig forwardConfig = moduleConfig.findForwardConfig(forward); 429 if (forwardConfig == null) { 430 throw new MalformedURLException (messages.getMessage("computeURL.forward", forward)); 431 } 432 if (forwardConfig.getRedirect()) { 433 redirect = true; 434 } 435 if (forwardConfig.getPath().startsWith("/")) { 436 url.append(request.getContextPath()); 437 url.append(RequestUtils.forwardURL(request, forwardConfig, moduleConfig)); 438 } else { 439 url.append(forwardConfig.getPath()); 440 } 441 } else if (href != null) { 442 url.append(href); 443 } else if (action != null) { 444 url.append(instance.getActionMappingURL(action, module, pageContext, false)); 445 446 } else { 447 url.append(request.getContextPath()); 448 url.append(this.pageURL(request, page, moduleConfig)); 449 } 450 451 if (anchor != null) { 453 String temp = url.toString(); 454 int hash = temp.indexOf('#'); 455 if (hash >= 0) { 456 url.setLength(hash); 457 } 458 url.append('#'); 459 url.append(this.encodeURL(anchor, charEncoding)); 460 } 461 462 if ((params != null) && (params.size() > 0)) { 464 465 String temp = url.toString(); 467 int hash = temp.indexOf('#'); 468 if (hash >= 0) { 469 anchor = temp.substring(hash + 1); 470 url.setLength(hash); 471 temp = url.toString(); 472 } else { 473 anchor = null; 474 } 475 476 String separator = null; 478 if (redirect) { 479 separator = "&"; 480 } else if (encodeSeparator) { 481 separator = "&"; 482 } else { 483 separator = "&"; 484 } 485 486 boolean question = temp.indexOf('?') >= 0; 488 Iterator keys = params.keySet().iterator(); 489 while (keys.hasNext()) { 490 String key = (String ) keys.next(); 491 Object value = params.get(key); 492 if (value == null) { 493 if (!question) { 494 url.append('?'); 495 question = true; 496 } else { 497 url.append(separator); 498 } 499 url.append(this.encodeURL(key, charEncoding)); 500 url.append('='); } else if (value instanceof String ) { 502 if (!question) { 503 url.append('?'); 504 question = true; 505 } else { 506 url.append(separator); 507 } 508 url.append(this.encodeURL(key, charEncoding)); 509 url.append('='); 510 url.append(this.encodeURL((String ) value, charEncoding)); 511 } else if (value instanceof String []) { 512 String values[] = (String []) value; 513 for (int i = 0; i < values.length; i++) { 514 if (!question) { 515 url.append('?'); 516 question = true; 517 } else { 518 url.append(separator); 519 } 520 url.append(this.encodeURL(key, charEncoding)); 521 url.append('='); 522 url.append(this.encodeURL(values[i], charEncoding)); 523 } 524 } else { 525 if (!question) { 526 url.append('?'); 527 question = true; 528 } else { 529 url.append(separator); 530 } 531 url.append(this.encodeURL(key, charEncoding)); 532 url.append('='); 533 url.append(this.encodeURL(value.toString(), charEncoding)); 534 } 535 } 536 537 if (anchor != null) { 539 url.append('#'); 540 url.append(this.encodeURL(anchor, charEncoding)); 541 } 542 543 } 544 545 if (( href == null ) && ( pageContext.getSession() != null )) { 548 HttpServletResponse response = (HttpServletResponse ) pageContext.getResponse(); 549 if (redirect) { 550 return (response.encodeRedirectURL(url.toString())); 551 } else { 552 return (response.encodeURL(url.toString())); 553 } 554 } else { 555 return (url.toString()); 556 } 557 558 } 559 560 561 567 public String encodeURL(String url) { 568 return encodeURL(url, "UTF-8"); 569 } 570 571 579 public String encodeURL(String url, String enc) { 580 return ResponseUtils.encodeURL(url, enc); 581 } 582 583 590 public String filter(String value) { 591 return ResponseUtils.filter(value); 592 } 593 594 605 public ActionErrors getActionErrors(PageContext pageContext, String paramName) 606 throws JspException { 607 608 ActionErrors errors = new ActionErrors(); 609 610 Object value = pageContext.findAttribute(paramName); 611 if (value != null) { 612 try { 613 if (value instanceof String ) { 614 errors.add( 615 ActionMessages.GLOBAL_MESSAGE, 616 new ActionMessage((String ) value)); 617 618 } else if (value instanceof String []) { 619 String keys[] = (String []) value; 620 for (int i = 0; i < keys.length; i++) { 621 errors.add( 622 ActionMessages.GLOBAL_MESSAGE, 623 new ActionMessage(keys[i])); 624 } 625 626 } else if (value instanceof ActionErrors) { 627 errors = (ActionErrors) value; 628 629 } else { 630 throw new JspException ( 631 messages.getMessage( 632 "actionErrors.errors", 633 value.getClass().getName())); 634 } 635 636 } catch (JspException e) { 637 throw e; 638 639 } catch (Exception e) { 640 log.debug(e, e); 641 } 642 } 643 return errors; 644 } 645 646 657 public String getActionMappingName(String action) { 658 659 String value = action; 660 int question = action.indexOf("?"); 661 if (question >= 0) { 662 value = value.substring(0, question); 663 } 664 665 int slash = value.lastIndexOf("/"); 666 int period = value.lastIndexOf("."); 667 if ((period >= 0) && (period > slash)) { 668 value = value.substring(0, period); 669 } 670 671 return value.startsWith("/") ? value : ("/" + value); 672 } 673 674 675 678 public String getActionMappingURL(String action, PageContext pageContext) { 679 return getActionMappingURL(action,null,pageContext,false); 680 } 681 682 683 686 public String getActionMappingURL(String action, String module, PageContext pageContext, boolean contextRelative) { 687 688 HttpServletRequest request = (HttpServletRequest ) pageContext.getRequest(); 689 690 String contextPath = request.getContextPath(); 691 StringBuffer value = new StringBuffer (); 692 if (contextPath.length() > 1) value.append(contextPath); 696 697 ModuleConfig moduleConfig = ModuleUtils.getInstance().getModuleConfig(module, request, pageContext.getServletContext()); 698 699 if ((moduleConfig != null) && (!contextRelative)) { 700 value.append(moduleConfig.getPrefix()); 701 } 702 703 String servletMapping = 705 (String ) pageContext.getAttribute( 706 Globals.SERVLET_KEY, 707 PageContext.APPLICATION_SCOPE); 708 709 if (servletMapping != null) { 710 711 String queryString = null; 712 int question = action.indexOf("?"); 713 if (question >= 0) { 714 queryString = action.substring(question); 715 } 716 717 String actionMapping = getActionMappingName(action); 718 if (servletMapping.startsWith("*.")) { 719 value.append(actionMapping); 720 value.append(servletMapping.substring(1)); 721 722 } else if (servletMapping.endsWith("/*")) { 723 value.append( 724 servletMapping.substring(0, servletMapping.length() - 2)); 725 value.append(actionMapping); 726 727 } else if (servletMapping.equals("/")) { 728 value.append(actionMapping); 729 } 730 if (queryString != null) { 731 value.append(queryString); 732 } 733 } 734 735 else { 738 if (!action.startsWith("/")) { 739 value.append("/"); 740 } 741 value.append(action); 742 } 743 744 return value.toString(); 745 } 746 747 756 public ActionMessages getActionMessages( 757 PageContext pageContext, 758 String paramName) 759 throws JspException { 760 761 ActionMessages am = new ActionMessages(); 762 763 Object value = pageContext.findAttribute(paramName); 764 if (value != null) { 765 try { 766 if (value instanceof String ) { 767 am.add( 768 ActionMessages.GLOBAL_MESSAGE, 769 new ActionMessage((String ) value)); 770 771 } else if (value instanceof String []) { 772 String keys[] = (String []) value; 773 for (int i = 0; i < keys.length; i++) { 774 am.add( 775 ActionMessages.GLOBAL_MESSAGE, 776 new ActionMessage(keys[i])); 777 } 778 779 } else if (value instanceof ActionErrors) { 780 ActionMessages m = (ActionMessages) value; 781 am.add(m); 782 783 } else if (value instanceof ActionMessages) { 784 am = (ActionMessages) value; 785 786 } else { 787 throw new JspException ( 788 messages.getMessage( 789 "actionMessages.errors", 790 value.getClass().getName())); 791 } 792 793 } catch (JspException e) { 794 throw e; 795 796 } catch (Exception e) { 797 log.warn("Unable to retieve ActionMessage for paramName : "+paramName,e); 798 } 799 } 800 return am; 801 } 802 803 808 public ModuleConfig getModuleConfig(PageContext pageContext) { 809 return getModuleConfig( 810 null, 811 pageContext); 812 } 813 814 820 public ModuleConfig getModuleConfig(String module, PageContext pageContext) { 821 return ModuleUtils.getInstance().getModuleConfig( 822 module, 823 (HttpServletRequest ) pageContext.getRequest(), 824 pageContext.getServletContext()); 825 } 826 827 834 public int getScope(String scopeName) throws JspException { 835 Integer scope = (Integer ) scopes.get(scopeName.toLowerCase()); 836 837 if (scope == null) { 838 throw new JspException (messages.getMessage("lookup.scope", scope)); 839 } 840 841 return scope.intValue(); 842 } 843 844 852 public Locale getUserLocale(PageContext pageContext, String locale) { 853 return RequestUtils.getUserLocale( 854 (HttpServletRequest ) pageContext.getRequest(), 855 locale); 856 } 857 858 861 public boolean isXhtml(PageContext pageContext) { 862 String xhtml = 863 (String ) pageContext.getAttribute( 864 Globals.XHTML_KEY, 865 PageContext.PAGE_SCOPE); 866 867 return "true".equalsIgnoreCase(xhtml); 868 } 869 870 884 public Object lookup(PageContext pageContext, String name, String scopeName) 885 throws JspException { 886 887 if (scopeName == null) { 888 return pageContext.findAttribute(name); 889 } 890 891 try { 892 return pageContext.getAttribute(name, instance.getScope(scopeName)); 893 894 } catch (JspException e) { 895 saveException(pageContext, e); 896 throw e; 897 } 898 899 } 900 901 922 public Object lookup( 923 PageContext pageContext, 924 String name, 925 String property, 926 String scope) 927 throws JspException { 928 929 Object bean = lookup(pageContext, name, scope); 931 if (bean == null) { 932 JspException e = null; 933 if (scope == null) { 934 e = new JspException (messages.getMessage("lookup.bean.any", name)); 935 } else { 936 e = 937 new JspException ( 938 messages.getMessage("lookup.bean", name, scope)); 939 } 940 saveException(pageContext, e); 941 throw e; 942 } 943 944 if (property == null) { 945 return bean; 946 } 947 948 try { 950 return PropertyUtils.getProperty(bean, property); 951 952 } catch (IllegalAccessException e) { 953 saveException(pageContext, e); 954 throw new JspException ( 955 messages.getMessage("lookup.access", property, name)); 956 957 } catch (IllegalArgumentException e) { 958 saveException(pageContext, e); 959 throw new JspException ( 960 messages.getMessage("lookup.argument", property, name)); 961 962 } catch (InvocationTargetException e) { 963 Throwable t = e.getTargetException(); 964 if (t == null) { 965 t = e; 966 } 967 saveException(pageContext, t); 968 throw new JspException ( 969 messages.getMessage("lookup.target", property, name)); 970 971 } catch (NoSuchMethodException e) { 972 saveException(pageContext, e); 973 throw new JspException ( 974 messages.getMessage("lookup.method", property, name)); 975 } 976 977 } 978 979 992 public String message( 993 PageContext pageContext, 994 String bundle, 995 String locale, 996 String key) 997 throws JspException { 998 999 return message(pageContext, bundle, locale, key, null); 1000 1001 } 1002 1003 1016 public String message( 1017 PageContext pageContext, 1018 String bundle, 1019 String locale, 1020 String key, 1021 Object args[]) 1022 throws JspException { 1023 1024 MessageResources resources = 1025 retrieveMessageResources(pageContext, bundle, false); 1026 1027 Locale userLocale = getUserLocale(pageContext, locale); 1028 String message = null; 1029 if (args == null) { 1030 message = resources.getMessage(userLocale, key); 1031 } else { 1032 message = resources.getMessage(userLocale, key, args); 1033 } 1034 if ((message == null) && log.isDebugEnabled()) { 1035 log.debug(resources.getMessage("message.resources", key, bundle, locale)); 1037 } 1038 return message; 1039 } 1040 1041 1053 public String pageURL(HttpServletRequest request, String page, ModuleConfig moduleConfig) { 1054 1055 StringBuffer sb = new StringBuffer (); 1056 String pagePattern = moduleConfig.getControllerConfig().getPagePattern(); 1057 1058 if (pagePattern == null) { 1059 sb.append(moduleConfig.getPrefix()); 1060 sb.append(page); 1061 1062 } else { 1063 boolean dollar = false; 1064 for (int i = 0; i < pagePattern.length(); i++) { 1065 char ch = pagePattern.charAt(i); 1066 if (dollar) { 1067 switch (ch) { 1068 case 'M': 1069 sb.append(moduleConfig.getPrefix()); 1070 break; 1071 case 'P': 1072 sb.append(page); 1073 break; 1074 case '$': 1075 sb.append('$'); 1076 break; 1077 default : 1078 ; } 1080 dollar = false; 1081 continue; 1082 1083 } else if (ch == '$') { 1084 dollar = true; 1085 1086 } else { 1087 sb.append(ch); 1088 } 1089 } 1090 } 1091 1092 return sb.toString(); 1093 } 1094 1095 1108 public boolean present( 1109 PageContext pageContext, 1110 String bundle, 1111 String locale, 1112 String key) 1113 throws JspException { 1114 1115 MessageResources resources = 1116 retrieveMessageResources(pageContext, bundle, true); 1117 1118 Locale userLocale = getUserLocale(pageContext, locale); 1119 1120 return resources.isPresent(userLocale, key); 1121 } 1122 1123 1133 public MessageResources retrieveMessageResources( 1134 PageContext pageContext, 1135 String bundle, 1136 boolean checkPageScope) 1137 throws JspException { 1138 1139 MessageResources resources = null; 1140 1141 if (bundle == null) { 1142 bundle = Globals.MESSAGES_KEY; 1143 } 1144 1145 if (checkPageScope) { 1146 resources = 1147 (MessageResources) pageContext.getAttribute( 1148 bundle, 1149 PageContext.PAGE_SCOPE); 1150 } 1151 1152 if (resources == null) { 1153 resources = 1154 (MessageResources) pageContext.getAttribute( 1155 bundle, 1156 PageContext.REQUEST_SCOPE); 1157 } 1158 1159 if (resources == null) { 1160 ModuleConfig moduleConfig = getModuleConfig(pageContext); 1161 resources = 1162 (MessageResources) pageContext.getAttribute( 1163 bundle + moduleConfig.getPrefix(), 1164 PageContext.APPLICATION_SCOPE); 1165 } 1166 1167 if (resources == null) { 1168 resources = 1169 (MessageResources) pageContext.getAttribute( 1170 bundle, 1171 PageContext.APPLICATION_SCOPE); 1172 } 1173 1174 if (resources == null) { 1175 JspException e = 1176 new JspException (messages.getMessage("message.bundle", bundle)); 1177 saveException(pageContext, e); 1178 throw e; 1179 } 1180 1181 return resources; 1182 } 1183 1184 1190 public void saveException(PageContext pageContext, Throwable exception) { 1191 1192 pageContext.setAttribute( 1193 Globals.EXCEPTION_KEY, 1194 exception, 1195 PageContext.REQUEST_SCOPE); 1196 1197 } 1198 1199 1211 public void write(PageContext pageContext, String text) 1212 throws JspException { 1213 1214 JspWriter writer = pageContext.getOut(); 1215 1216 try { 1217 writer.print(text); 1218 1219 } catch (IOException e) { 1220 TagUtils.getInstance().saveException(pageContext, e); 1221 throw new JspException 1222 (messages.getMessage("write.io", e.toString())); 1223 } 1224 1225 } 1226 1227 1228 1237 public void writePrevious(PageContext pageContext, String text) 1238 throws JspException { 1239 1240 JspWriter writer = pageContext.getOut(); 1241 if (writer instanceof BodyContent ) { 1242 writer = ((BodyContent ) writer).getEnclosingWriter(); 1243 } 1244 1245 try { 1246 writer.print(text); 1247 1248 } catch (IOException e) { 1249 TagUtils.getInstance().saveException(pageContext, e); 1250 throw new JspException 1251 (messages.getMessage("write.io", e.toString())); 1252 } 1253 1254 } 1255 1256} 1257 | Popular Tags |