1 package org.apache.turbine; 2 3 56 57 import java.util.ArrayList ; 58 import java.util.Enumeration ; 59 import java.util.Vector ; 60 61 import javax.servlet.http.HttpServletRequest ; 62 import javax.servlet.http.HttpServletResponse ; 63 64 import org.apache.fulcrum.parser.ParameterParser; 65 66 90 public class DynamicURI 91 { 92 93 public static final String HTTP = "http"; 94 95 96 public static final String HTTPS = "https"; 97 98 99 public static final int ANCHOR_STATIC_PART_LENGTH 100 = "<a HREF=\"\"></a>".length(); 101 102 103 protected RunData data = null; 104 105 106 public HttpServletResponse res = null; 107 108 109 protected ArrayList pathInfo = new ArrayList (); 110 111 112 protected ArrayList queryData = new ArrayList (); 113 114 115 protected boolean redirect = false; 116 117 118 protected static final int PATH_INFO = 0; 119 120 121 protected static final int QUERY_DATA = 1; 122 123 124 private boolean isRelative = false; 125 126 130 private boolean encodeUrl = true; 131 132 137 public DynamicURI(RunData data) 138 { 139 init(data); 140 } 141 142 146 public DynamicURI() 147 { 148 } 149 150 156 public DynamicURI(RunData data, 157 String screen) 158 { 159 this(data); 160 setScreen(screen); 161 } 162 163 170 public DynamicURI(RunData data, 171 String screen, 172 String action) 173 { 174 this(data, screen); 175 setAction(action); 176 } 177 178 186 public DynamicURI(RunData data, 187 String screen, 188 String action, 189 boolean redirect) 190 { 191 this(data, screen, action); 192 this.redirect = redirect; 193 } 194 195 202 public DynamicURI(RunData data, 203 String screen, 204 boolean redirect) 205 { 206 this(data, screen); 207 this.redirect = redirect; 208 } 209 210 216 public DynamicURI(RunData data, 217 boolean redirect) 218 { 219 this(data); 220 this.redirect = redirect; 221 } 222 223 228 public void init(RunData data) 229 { 230 this.data = data; 231 this.res = data.getResponse(); 232 init(); 233 } 234 235 246 protected void add(int type, 247 String name, 248 String value) 249 { 250 Object [] tmp = new Object [2]; 251 252 tmp[0] = data.getParameters().convertAndTrim(name); 253 tmp[1] = value; 254 255 if ( type == PATH_INFO ) 256 { 257 this.pathInfo.add(tmp); 258 } 259 else if ( type == QUERY_DATA ) 260 { 261 this.queryData.add(tmp); 262 } 263 } 264 265 273 protected void addPair(ArrayList list, 274 String name, 275 String value) 276 { 277 Object [] tmp = new Object [2]; 278 279 tmp[0] = data.getParameters().convertAndTrim(name); 280 tmp[1] = value; 281 282 list.add(tmp); 283 } 284 285 292 protected void add(ArrayList list, 293 ParameterParser pp) 294 { 295 Enumeration e = pp.keys(); 296 while (e.hasMoreElements()) 297 { 298 String key = (String ) e.nextElement(); 299 300 if (!key.equalsIgnoreCase(Turbine.ACTION) && 301 !key.equalsIgnoreCase(Turbine.SCREEN) && 302 !key.equalsIgnoreCase(Turbine.TEMPLATE)) 303 { 304 String [] values = pp.getStrings(key); 305 for (int i = 0; i < values.length; i++) 306 { 307 addPair(list, key, values[i]); 308 } 309 } 310 } 311 } 312 313 326 protected void add(int type, 327 ParameterParser pp) 328 { 329 if ( type == PATH_INFO ) 330 { 331 add( pathInfo, pp); 332 } 333 else if ( type == QUERY_DATA ) 334 { 335 add( queryData, pp); 336 } 337 } 338 339 345 public DynamicURI addPathInfo(String name, Object value) 346 { 347 addPathInfo(name, value.toString()); 348 return this; 349 } 350 351 357 public DynamicURI addPathInfo(String name, String value) 358 { 359 addPair( pathInfo, name, value); 360 return this; 361 } 362 363 369 public DynamicURI addPathInfo(String name, double value) 370 { 371 addPathInfo(name, Double.toString(value)); 372 return this; 373 } 374 375 381 public DynamicURI addPathInfo(String name, int value) 382 { 383 addPathInfo(name, new Integer (value).toString()); 384 return this; 385 } 386 387 393 public DynamicURI addPathInfo(String name, long value) 394 { 395 addPathInfo(name, new Long (value).toString()); 396 return this; 397 } 398 399 405 public DynamicURI addPathInfo(String name, boolean value) 406 { 407 addPathInfo(name, (value ? "true" : "false")); 408 return this; 409 } 410 411 417 public DynamicURI addPathInfo(ParameterParser pp) 418 { 419 add(pathInfo, pp); 420 return this; 421 } 422 423 429 public DynamicURI addQueryData(String name, Object value) 430 { 431 addQueryData(name, value.toString()); 432 return this; 433 } 434 435 441 public DynamicURI addQueryData(String name, String value) 442 { 443 addPair( queryData, name, value); 444 return this; 445 } 446 447 453 public DynamicURI addQueryData(String name, double value) 454 { 455 addQueryData(name, Double.toString(value)); 456 return this; 457 } 458 459 465 public DynamicURI addQueryData(String name, int value) 466 { 467 addQueryData(name, new Integer (value).toString()); 468 return this; 469 } 470 471 477 public DynamicURI addQueryData(String name, long value) 478 { 479 addQueryData(name, new Long (value).toString()); 480 return this; 481 } 482 483 489 public DynamicURI addQueryData(ParameterParser pp) 490 { 491 add(queryData, pp); 492 return this; 493 } 494 495 511 public String getA(String name) 512 { 513 final String s = this.toString(); 514 515 518 final int size = ANCHOR_STATIC_PART_LENGTH + s.length() + name.length(); 519 520 return new StringBuffer ( size ) 521 .append("<a HREF=\"") 522 .append(s) 523 .append("\">") 524 .append(name) 525 .append("</a>") 526 .toString(); 527 } 528 529 534 public String getScriptName() 535 { 536 return data.getScriptName(); 537 } 538 539 544 public String getServerName() 545 { 546 return data.getServerName(); 547 } 548 549 554 public int getServerPort() 555 { 556 return data.getServerPort(); 557 } 558 559 564 public String getServerScheme() 565 { 566 return data.getServerScheme(); 567 } 568 569 572 protected void init() 573 { 574 this.pathInfo.clear(); 575 this.queryData.clear(); 576 } 577 578 588 protected void remove(int type, 589 String name) 590 { 591 try 592 { 593 if ( type == PATH_INFO ) 594 { 595 removePathInfo( name ); 596 } 597 else if ( type == QUERY_DATA ) 598 { 599 removeQueryData( name ); 600 } 601 } 602 catch (Exception e) 603 { 604 } 605 } 606 607 613 protected void removePairByName(ArrayList pairs, String name) 614 { 615 name = data.getParameters().convertAndTrim(name); 616 for (int i = 0; i < pairs.size(); i++) 619 { 620 Object [] pair = (Object [])pairs.get(i); 621 if ( name.equals( (String )pair[0] ) ) 622 { 623 pairs.remove(i); 624 } 625 } 626 } 627 628 631 public void removePathInfo() 632 { 633 this.pathInfo.clear(); 634 } 635 636 641 public void removePathInfo(String name) 642 { 643 removePairByName( pathInfo, name );; 644 } 645 646 649 public void removeQueryData() 650 { 651 this.queryData.clear(); 652 } 653 654 659 public void removeQueryData(String name) 660 { 661 removePairByName( queryData, name ); 662 } 663 664 672 protected String renderPathInfo(Vector data) 673 { 674 StringBuffer out = new StringBuffer (); 675 676 renderPathInfo(new ArrayList (data), out); 677 678 return out.toString(); 679 } 680 681 688 protected void renderPathInfo(ArrayList pairs, StringBuffer out) 689 { 690 renderPairs( pairs, out, '/', '/' ); 691 } 692 693 701 protected String renderQueryString(Vector data) 702 { 703 StringBuffer out = new StringBuffer (); 704 705 renderQueryString(new ArrayList (data), out); 706 707 return out.toString(); 708 } 709 710 717 protected void renderQueryString(ArrayList data, StringBuffer out) 718 { 719 renderPairs( data, out, '&', '=' ); 720 } 721 722 734 protected void renderPairs(ArrayList pairs, StringBuffer out, 735 char pairSep, char keyValSep) 736 { 737 boolean first = true; 738 739 final int count = pairs.size(); 740 for (int i = 0; i < count; i++) 741 { 742 Object [] pair = (Object []) pairs.get(i); 743 744 if ( first ) 745 { 746 first = false; 747 } 748 else 749 { 750 out.append(pairSep); 751 } 752 753 writeFastEncoded((String ) pair[0], out); 754 out.append(keyValSep); 755 writeFastEncoded((String ) pair[1], out); 756 } 757 } 758 759 768 public DynamicURI setAction(String action) 769 { 770 addPathInfo(Turbine.ACTION, action); 771 return this; 772 } 773 774 783 public DynamicURI setScreen(String screen) 784 { 785 addPathInfo(Turbine.SCREEN, screen); 786 return this; 787 } 788 789 798 public DynamicURI setTemplate(String template) 799 { 800 addPathInfo(Turbine.TEMPLATE, template); 801 return this; 802 } 803 804 810 public DynamicURI setRedirect(boolean doRedirect) 811 { 812 this.redirect = doRedirect; 813 return this; 814 } 815 816 823 public DynamicURI setSecure() 824 { 825 return setSecure(443); 826 } 827 828 835 public DynamicURI setSecure(int port) 836 { 837 boolean isSSL = Turbine.getConfiguration() 838 .getBoolean(Turbine.USE_SSL, true); 839 if (isSSL) 840 { 841 data.setServerScheme(DynamicURI.HTTPS); 842 data.setServerPort(port); 843 } 844 return this; 845 } 846 847 854 public DynamicURI setRelative(boolean b) 855 { 856 isRelative = b; 857 return this; 858 } 859 860 866 public boolean isRelative() 867 { 868 return isRelative; 869 } 870 871 877 public DynamicURI setEncodeUrl(boolean b) 878 { 879 encodeUrl = b; 880 return this; 881 } 882 883 890 public boolean isEncodeUrl() 891 { 892 return encodeUrl; 893 } 894 895 913 public String toString() 914 { 915 StringBuffer output = new StringBuffer (); 916 if (!isRelative()) 917 { 918 output.append(getServerScheme()); 919 output.append("://"); 920 output.append(getServerName()); 921 if ((getServerScheme().equals(HTTP) && getServerPort() != 80) 922 || (getServerScheme().equals(HTTPS) && getServerPort() != 443)) 923 { 924 output.append(':'); 925 output.append(getServerPort()); 926 } 927 } 928 929 output.append(getScriptName()); 930 931 if (this.hasPathInfo()) 932 { 933 output.append('/'); 934 renderPathInfo(this.pathInfo, output); 935 } 936 if (this.hasQueryData()) 937 { 938 output.append('?'); 939 renderQueryString(this.queryData, output); 940 } 941 942 if (this.res != null && isEncodeUrl()) 946 { 947 if (this.redirect) 948 { 949 return res.encodeRedirectURL(output.toString()); 950 } 951 else 952 { 953 return res.encodeURL(output.toString()); 954 } 955 } 956 else 957 { 958 return output.toString(); 959 } 960 } 961 962 972 public static String toString(RunData data) 973 { 974 return toString(data, true); 975 } 976 977 988 public static String toString(RunData data, boolean isAbsolute) 989 { 990 StringBuffer output = new StringBuffer ( 128 ); 991 HttpServletRequest request = data.getRequest(); 992 993 if (isAbsolute) 994 { 995 output.append(data.getServerScheme()); 996 output.append("://"); 997 output.append(data.getServerName()); 998 999 if ((data.getServerScheme().equals(HTTP) && 1000 data.getServerPort() != 80) || 1001 (data.getServerScheme().equals(HTTPS) && 1002 data.getServerPort() != 443)) 1003 { 1004 output.append(':'); 1005 output.append(data.getServerPort()); 1006 } 1007 } 1008 1009 output.append(data.getScriptName()); 1010 1011 if (request.getPathInfo() != null) 1012 { 1013 output.append(request.getPathInfo()); 1014 } 1015 1016 if (request.getQueryString() != null) 1017 { 1018 output.append('?'); 1019 output.append(request.getQueryString()); 1020 } 1021 return output.toString(); 1022 } 1023 1024 1038 protected static final void writeFastEncoded(String in, StringBuffer out) 1039 { 1040 if (in == null || in.length() == 0) 1041 { 1042 out.append("null"); 1043 return; 1044 } 1045 1046 char[] chars = in.toCharArray(); 1047 1048 for (int i = 0; i < chars.length; i++) 1049 { 1050 char c = chars[i]; 1051 1052 if ( c < 128 && safe[ c ] ) 1053 { 1054 out.append(c); 1055 } 1056 else if (c == ' ') 1057 { 1058 out.append('+'); 1059 } 1060 else 1061 { 1062 writeEncoded(new String (chars, i, chars.length-i), out); 1065 break; 1066 } 1067 } 1068 } 1069 1070 1077 protected static final void writeEncoded(String in, StringBuffer out) 1078 { 1079 if (in == null || in.length() == 0) 1080 { 1081 out.append("null"); 1082 return; 1083 } 1084 1085 1087 byte[] bytes = in.getBytes(); 1088 1089 for (int i = 0; i < bytes.length; i++) 1090 { 1091 char c = (char) bytes[i]; 1092 1093 if ( c < 128 && safe[ c ] ) 1094 { 1095 out.append(c); 1096 } 1097 else if (c == ' ') 1098 { 1099 out.append('+'); 1100 } 1101 else 1102 { 1103 byte toEscape = bytes[i]; 1104 out.append('%'); 1105 int low = (int) (toEscape & 0x0f); 1106 int high = (int) ((toEscape & 0xf0) >> 4); 1107 out.append(hexadecimal[high]); 1108 out.append(hexadecimal[low]); 1109 } 1110 } 1111 } 1112 1113 1116 public boolean hasPathInfo() 1117 { 1118 return ! pathInfo.isEmpty(); 1119 } 1120 1121 1124 public boolean hasQueryData() 1125 { 1126 return ! queryData.isEmpty(); 1127 } 1128 1129 1130 1132 1135 private static final char[] hexadecimal = 1136 { 1137 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 1138 'A', 'B', 'C', 'D', 'E', 'F' 1139 }; 1140 1141 1145 private static boolean[] safe = new boolean[ 128 ]; 1146 1147 1148 static 1149 { 1150 for (int i = 'a'; i <= 'z'; i++) 1151 { 1152 safe[ i ] = true; 1153 } 1154 for (int i = 'A'; i <= 'Z'; i++) 1155 { 1156 safe[ i ] = true; 1157 } 1158 for (int i = '0'; i <= '9'; i++) 1159 { 1160 safe[ i ] = true; 1161 } 1162 1163 safe['-'] = true; 1164 safe['_'] = true; 1165 safe['.'] = true; 1166 safe['!'] = true; 1167 safe['~'] = true; 1168 safe['*'] = true; 1169 safe['\''] = true; 1170 safe['('] = true; 1171 safe[')'] = true; 1172 } 1173} 1174 | Popular Tags |