1 17 18 package org.apache.tomcat.util.http.mapper; 19 20 import javax.naming.NamingException ; 21 import javax.naming.directory.DirContext ; 22 23 import org.apache.tomcat.util.buf.CharChunk; 24 import org.apache.tomcat.util.buf.MessageBytes; 25 import org.apache.tomcat.util.buf.Ascii; 26 import java.util.List ; 27 import java.util.ArrayList ; 28 29 35 public final class Mapper { 36 37 38 private static org.apache.commons.logging.Log logger = 39 org.apache.commons.logging.LogFactory.getLog(Mapper.class); 40 42 43 46 protected Host[] hosts = new Host[0]; 47 48 49 52 protected String defaultHostName = null; 53 54 57 protected Context context = new Context (); 58 59 60 62 63 68 public String getDefaultHostName() { 69 return defaultHostName; 70 } 71 72 73 78 public void setDefaultHostName(String defaultHostName) { 79 this.defaultHostName = defaultHostName; 80 } 81 82 88 public synchronized void addHost(String name, String [] aliases, 89 Object host) { 90 Host[] newHosts = new Host[hosts.length + 1]; 91 Host newHost = new Host(); 92 ContextList contextList = new ContextList(); 93 newHost.name = name; 94 newHost.contextList = contextList; 95 newHost.object = host; 96 if (insertMap(hosts, newHosts, newHost)) { 97 hosts = newHosts; 98 } 99 for (int i = 0; i < aliases.length; i++) { 100 newHosts = new Host[hosts.length + 1]; 101 newHost = new Host(); 102 newHost.name = aliases[i]; 103 newHost.contextList = contextList; 104 newHost.object = host; 105 if (insertMap(hosts, newHosts, newHost)) { 106 hosts = newHosts; 107 } 108 } 109 } 110 111 112 117 public synchronized void removeHost(String name) { 118 int pos = find(hosts, name); 120 if (pos < 0) { 121 return; 122 } 123 Object host = hosts[pos].object; 124 Host[] newHosts = new Host[hosts.length - 1]; 125 if (removeMap(hosts, newHosts, name)) { 126 hosts = newHosts; 127 } 128 for (int i = 0; i < newHosts.length; i++) { 130 if (newHosts[i].object == host) { 131 Host[] newHosts2 = new Host[hosts.length - 1]; 132 if (removeMap(hosts, newHosts2, newHosts[i].name)) { 133 hosts = newHosts2; 134 } 135 } 136 } 137 } 138 139 public String [] getHosts() { 140 String hostN[] = new String [hosts.length]; 141 for( int i = 0; i < hosts.length; i++ ) { 142 hostN[i] = hosts[i].name; 143 } 144 return hostN; 145 } 146 147 148 154 public void setContext(String path, String [] welcomeResources, 155 javax.naming.Context resources) { 156 context.name = path; 157 context.welcomeResources = welcomeResources; 158 context.resources = resources; 159 } 160 161 162 171 public void addContext 172 (String hostName, String path, Object context, 173 String [] welcomeResources, javax.naming.Context resources) { 174 175 Host[] hosts = this.hosts; 176 int pos = find(hosts, hostName); 177 if( pos <0 ) { 178 addHost(hostName, new String [0], ""); 179 hosts = this.hosts; 180 pos = find(hosts, hostName); 181 } 182 if (pos < 0) { 183 logger.error("No host found: " + hostName); 184 } 185 Host host = hosts[pos]; 186 if (host.name.equals(hostName)) { 187 int slashCount = slashCount(path); 188 synchronized (host) { 189 Context [] contexts = host.contextList.contexts; 190 if (slashCount > host.contextList.nesting) { 192 host.contextList.nesting = slashCount; 193 } 194 Context [] newContexts = new Context [contexts.length + 1]; 195 Context newContext = new Context (); 196 newContext.name = path; 197 newContext.object = context; 198 newContext.welcomeResources = welcomeResources; 199 newContext.resources = resources; 200 if (insertMap(contexts, newContexts, newContext)) { 201 host.contextList.contexts = newContexts; 202 } 203 } 204 } 205 206 } 207 208 209 215 public void removeContext(String hostName, String path) { 216 Host[] hosts = this.hosts; 217 int pos = find(hosts, hostName); 218 if (pos < 0) { 219 return; 220 } 221 Host host = hosts[pos]; 222 if (host.name.equals(hostName)) { 223 synchronized (host) { 224 Context [] contexts = host.contextList.contexts; 225 if( contexts.length == 0 ){ 226 return; 227 } 228 Context [] newContexts = new Context [contexts.length - 1]; 229 if (removeMap(contexts, newContexts, path)) { 230 host.contextList.contexts = newContexts; 231 host.contextList.nesting = 0; 233 for (int i = 0; i < newContexts.length; i++) { 234 int slashCount = slashCount(newContexts[i].name); 235 if (slashCount > host.contextList.nesting) { 236 host.contextList.nesting = slashCount; 237 } 238 } 239 } 240 } 241 } 242 } 243 244 245 250 public String [] getContextNames() { 251 List list=new ArrayList (); 252 for( int i=0; i<hosts.length; i++ ) { 253 for( int j=0; j<hosts[i].contextList.contexts.length; j++ ) { 254 String cname=hosts[i].contextList.contexts[j].name; 255 list.add("//" + hosts[i].name + 256 (cname.startsWith("/") ? cname : "/")); 257 } 258 } 259 String res[] = new String [list.size()]; 260 return (String [])list.toArray(res); 261 } 262 263 264 272 public void addWrapper(String hostName, String contextPath, String path, 273 Object wrapper) { 274 addWrapper(hostName, contextPath, path, wrapper, false); 275 } 276 277 278 public void addWrapper(String hostName, String contextPath, String path, 279 Object wrapper, boolean jspWildCard) { 280 Host[] hosts = this.hosts; 281 int pos = find(hosts, hostName); 282 if (pos < 0) { 283 return; 284 } 285 Host host = hosts[pos]; 286 if (host.name.equals(hostName)) { 287 Context [] contexts = host.contextList.contexts; 288 int pos2 = find(contexts, contextPath); 289 if( pos2<0 ) { 290 logger.error("No context found: " + contextPath ); 291 return; 292 } 293 Context context = contexts[pos2]; 294 if (context.name.equals(contextPath)) { 295 addWrapper(context, path, wrapper, jspWildCard); 296 } 297 } 298 } 299 300 301 307 public void addWrapper(String path, Object wrapper) { 308 addWrapper(context, path, wrapper); 309 } 310 311 312 public void addWrapper(String path, Object wrapper, boolean jspWildCard) { 313 addWrapper(context, path, wrapper, jspWildCard); 314 } 315 316 317 protected void addWrapper(Context context, String path, Object wrapper) { 318 addWrapper(context, path, wrapper, false); 319 } 320 321 322 331 protected void addWrapper(Context context, String path, Object wrapper, 332 boolean jspWildCard) { 333 334 synchronized (context) { 335 Wrapper newWrapper = new Wrapper(); 336 newWrapper.object = wrapper; 337 newWrapper.jspWildCard = jspWildCard; 338 if (path.endsWith("/*")) { 339 newWrapper.name = path.substring(0, path.length() - 2); 341 Wrapper[] oldWrappers = context.wildcardWrappers; 342 Wrapper[] newWrappers = 343 new Wrapper[oldWrappers.length + 1]; 344 if (insertMap(oldWrappers, newWrappers, newWrapper)) { 345 context.wildcardWrappers = newWrappers; 346 int slashCount = slashCount(newWrapper.name); 347 if (slashCount > context.nesting) { 348 context.nesting = slashCount; 349 } 350 } 351 } else if (path.startsWith("*.")) { 352 newWrapper.name = path.substring(2); 354 Wrapper[] oldWrappers = context.extensionWrappers; 355 Wrapper[] newWrappers = 356 new Wrapper[oldWrappers.length + 1]; 357 if (insertMap(oldWrappers, newWrappers, newWrapper)) { 358 context.extensionWrappers = newWrappers; 359 } 360 } else if (path.equals("/")) { 361 newWrapper.name = ""; 363 context.defaultWrapper = newWrapper; 364 } else { 365 newWrapper.name = path; 367 Wrapper[] oldWrappers = context.exactWrappers; 368 Wrapper[] newWrappers = 369 new Wrapper[oldWrappers.length + 1]; 370 if (insertMap(oldWrappers, newWrappers, newWrapper)) { 371 context.exactWrappers = newWrappers; 372 } 373 } 374 } 375 } 376 377 378 383 public void removeWrapper(String path) { 384 removeWrapper(context, path); 385 } 386 387 388 395 public void removeWrapper 396 (String hostName, String contextPath, String path) { 397 Host[] hosts = this.hosts; 398 int pos = find(hosts, hostName); 399 if (pos < 0) { 400 return; 401 } 402 Host host = hosts[pos]; 403 if (host.name.equals(hostName)) { 404 Context [] contexts = host.contextList.contexts; 405 int pos2 = find(contexts, contextPath); 406 if (pos2 < 0) { 407 return; 408 } 409 Context context = contexts[pos2]; 410 if (context.name.equals(contextPath)) { 411 removeWrapper(context, path); 412 } 413 } 414 } 415 416 protected void removeWrapper(Context context, String path) { 417 synchronized (context) { 418 if (path.endsWith("/*")) { 419 String name = path.substring(0, path.length() - 2); 421 Wrapper[] oldWrappers = context.wildcardWrappers; 422 Wrapper[] newWrappers = 423 new Wrapper[oldWrappers.length - 1]; 424 if (removeMap(oldWrappers, newWrappers, name)) { 425 context.nesting = 0; 427 for (int i = 0; i < newWrappers.length; i++) { 428 int slashCount = slashCount(newWrappers[i].name); 429 if (slashCount > context.nesting) { 430 context.nesting = slashCount; 431 } 432 } 433 context.wildcardWrappers = newWrappers; 434 } 435 } else if (path.startsWith("*.")) { 436 String name = path.substring(2); 438 Wrapper[] oldWrappers = context.extensionWrappers; 439 Wrapper[] newWrappers = 440 new Wrapper[oldWrappers.length - 1]; 441 if (removeMap(oldWrappers, newWrappers, name)) { 442 context.extensionWrappers = newWrappers; 443 } 444 } else if (path.equals("/")) { 445 context.defaultWrapper = null; 447 } else { 448 String name = path; 450 Wrapper[] oldWrappers = context.exactWrappers; 451 Wrapper[] newWrappers = 452 new Wrapper[oldWrappers.length - 1]; 453 if (removeMap(oldWrappers, newWrappers, name)) { 454 context.exactWrappers = newWrappers; 455 } 456 } 457 } 458 } 459 460 public String getWrappersString( String host, String context ) { 461 String names[]=getWrapperNames(host, context); 462 StringBuffer sb=new StringBuffer (); 463 for( int i=0; i<names.length; i++ ) { 464 sb.append(names[i]).append(":"); 465 } 466 return sb.toString(); 467 } 468 469 public String [] getWrapperNames( String host, String context ) { 470 List list=new ArrayList (); 471 if( host==null ) host=""; 472 if( context==null ) context=""; 473 for( int i=0; i<hosts.length; i++ ) { 474 if( ! host.equals( hosts[i].name )) 475 continue; 476 for( int j=0; j<hosts[i].contextList.contexts.length; j++ ) { 477 if( ! context.equals( hosts[i].contextList.contexts[j].name)) 478 continue; 479 Context ctx=hosts[i].contextList.contexts[j]; 481 list.add( ctx.defaultWrapper.path); 482 for( int k=0; k<ctx.exactWrappers.length; k++ ) { 483 list.add( ctx.exactWrappers[k].path); 484 } 485 for( int k=0; k<ctx.wildcardWrappers.length; k++ ) { 486 list.add( ctx.wildcardWrappers[k].path + "*"); 487 } 488 for( int k=0; k<ctx.extensionWrappers.length; k++ ) { 489 list.add( "*." + ctx.extensionWrappers[k].path); 490 } 491 } 492 } 493 String res[]=new String [list.size()]; 494 return (String [])list.toArray(res); 495 } 496 497 498 499 507 public void map(MessageBytes host, MessageBytes uri, 508 MappingData mappingData) 509 throws Exception { 510 511 if (host.isNull()) { 512 host.getCharChunk().append(defaultHostName); 513 } 514 host.toChars(); 515 uri.toChars(); 516 internalMap(host.getCharChunk(), uri.getCharChunk(), mappingData); 517 518 } 519 520 521 529 public void map(MessageBytes uri, MappingData mappingData) 530 throws Exception { 531 532 uri.toChars(); 533 CharChunk uricc = uri.getCharChunk(); 534 uricc.setLimit(-1); 535 internalMapWrapper(context, uricc, mappingData); 536 537 } 538 539 540 542 543 546 private final void internalMap(CharChunk host, CharChunk uri, 547 MappingData mappingData) 548 throws Exception { 549 550 uri.setLimit(-1); 551 552 Context [] contexts = null; 553 Context context = null; 554 int nesting = 0; 555 556 if (mappingData.host == null) { 558 Host[] hosts = this.hosts; 559 int pos = findIgnoreCase(hosts, host); 560 if ((pos != -1) && (host.equalsIgnoreCase(hosts[pos].name))) { 561 mappingData.host = hosts[pos].object; 562 contexts = hosts[pos].contextList.contexts; 563 nesting = hosts[pos].contextList.nesting; 564 } else { 565 if (defaultHostName == null) { 566 return; 567 } 568 pos = find(hosts, defaultHostName); 569 if ((pos != -1) && (defaultHostName.equals(hosts[pos].name))) { 570 mappingData.host = hosts[pos].object; 571 contexts = hosts[pos].contextList.contexts; 572 nesting = hosts[pos].contextList.nesting; 573 } else { 574 return; 575 } 576 } 577 } 578 579 if (mappingData.context == null) { 581 int pos = find(contexts, uri); 582 if (pos == -1) { 583 return; 584 } 585 586 int lastSlash = -1; 587 int uriEnd = uri.getEnd(); 588 int length = -1; 589 boolean found = false; 590 while (pos >= 0) { 591 if (uri.startsWith(contexts[pos].name)) { 592 length = contexts[pos].name.length(); 593 if (uri.getLength() == length) { 594 found = true; 595 break; 596 } else if (uri.startsWithIgnoreCase("/", length)) { 597 found = true; 598 break; 599 } 600 } 601 if (lastSlash == -1) { 602 lastSlash = nthSlash(uri, nesting + 1); 603 } else { 604 lastSlash = lastSlash(uri); 605 } 606 uri.setEnd(lastSlash); 607 pos = find(contexts, uri); 608 } 609 uri.setEnd(uriEnd); 610 611 if (!found) { 612 if (contexts[0].name.equals("")) { 613 context = contexts[0]; 614 } 615 } else { 616 context = contexts[pos]; 617 } 618 if (context != null) { 619 mappingData.context = context.object; 620 mappingData.contextPath.setString(context.name); 621 } 622 } 623 624 if ((context != null) && (mappingData.wrapper == null)) { 626 internalMapWrapper(context, uri, mappingData); 627 } 628 629 } 630 631 632 635 private final void internalMapWrapper(Context context, CharChunk path, 636 MappingData mappingData) 637 throws Exception { 638 639 int pathOffset = path.getOffset(); 640 int pathEnd = path.getEnd(); 641 int servletPath = pathOffset; 642 boolean noServletPath = false; 643 644 int length = context.name.length(); 645 if (length != (pathEnd - pathOffset)) { 646 servletPath = pathOffset + length; 647 } else { 648 noServletPath = true; 649 path.append('/'); 650 pathOffset = path.getOffset(); 651 pathEnd = path.getEnd(); 652 servletPath = pathOffset+length; 653 } 654 655 path.setOffset(servletPath); 656 657 Wrapper[] exactWrappers = context.exactWrappers; 659 internalMapExactWrapper(exactWrappers, path, mappingData); 660 661 boolean checkJspWelcomeFiles = false; 663 Wrapper[] wildcardWrappers = context.wildcardWrappers; 664 if (mappingData.wrapper == null) { 665 internalMapWildcardWrapper(wildcardWrappers, context.nesting, 666 path, mappingData); 667 if (mappingData.wrapper != null && mappingData.jspWildCard) { 668 char[] buf = path.getBuffer(); 669 if (buf[pathEnd - 1] == '/') { 670 678 mappingData.wrapper = null; 679 checkJspWelcomeFiles = true; 680 } else { 681 mappingData.wrapperPath.setChars(buf, path.getStart(), 683 path.getLength()); 684 mappingData.pathInfo.recycle(); 685 } 686 } 687 } 688 689 if(mappingData.wrapper == null && noServletPath) { 690 mappingData.redirectPath.setChars 692 (path.getBuffer(), pathOffset, pathEnd); 693 path.setEnd(pathEnd - 1); 694 return; 695 } 696 697 Wrapper[] extensionWrappers = context.extensionWrappers; 699 if (mappingData.wrapper == null && !checkJspWelcomeFiles) { 700 internalMapExtensionWrapper(extensionWrappers, path, mappingData); 701 } 702 703 if (mappingData.wrapper == null) { 705 boolean checkWelcomeFiles = checkJspWelcomeFiles; 706 if (!checkWelcomeFiles) { 707 char[] buf = path.getBuffer(); 708 checkWelcomeFiles = (buf[pathEnd - 1] == '/'); 709 } 710 if (checkWelcomeFiles) { 711 for (int i = 0; (i < context.welcomeResources.length) 712 && (mappingData.wrapper == null); i++) { 713 path.setOffset(pathOffset); 714 path.setEnd(pathEnd); 715 path.append(context.welcomeResources[i], 0, 716 context.welcomeResources[i].length()); 717 path.setOffset(servletPath); 718 719 internalMapExactWrapper(exactWrappers, path, mappingData); 721 722 if (mappingData.wrapper == null) { 724 internalMapWildcardWrapper 725 (wildcardWrappers, context.nesting, 726 path, mappingData); 727 } 728 729 if (mappingData.wrapper == null 732 && context.resources != null) { 733 Object file = null; 734 String pathStr = path.toString(); 735 try { 736 file = context.resources.lookup(pathStr); 737 } catch(NamingException nex) { 738 } 740 if (file != null && !(file instanceof DirContext ) ) { 741 internalMapExtensionWrapper(extensionWrappers, 742 path, mappingData); 743 if (mappingData.wrapper == null 744 && context.defaultWrapper != null) { 745 mappingData.wrapper = 746 context.defaultWrapper.object; 747 mappingData.requestPath.setChars 748 (path.getBuffer(), path.getStart(), 749 path.getLength()); 750 mappingData.wrapperPath.setChars 751 (path.getBuffer(), path.getStart(), 752 path.getLength()); 753 mappingData.requestPath.setString(pathStr); 754 mappingData.wrapperPath.setString(pathStr); 755 } 756 } 757 } 758 } 759 760 path.setOffset(servletPath); 761 path.setEnd(pathEnd); 762 } 763 764 } 765 766 767 if (mappingData.wrapper == null && !checkJspWelcomeFiles) { 769 if (context.defaultWrapper != null) { 770 mappingData.wrapper = context.defaultWrapper.object; 771 mappingData.requestPath.setChars 772 (path.getBuffer(), path.getStart(), path.getLength()); 773 mappingData.wrapperPath.setChars 774 (path.getBuffer(), path.getStart(), path.getLength()); 775 } 776 char[] buf = path.getBuffer(); 778 if (context.resources != null && buf[pathEnd -1 ] != '/') { 779 Object file = null; 780 String pathStr = path.toString(); 781 try { 782 file = context.resources.lookup(pathStr); 783 } catch(NamingException nex) { 784 } 786 if (file != null && file instanceof DirContext ) { 787 path.setOffset(pathOffset); 791 path.append('/'); 792 mappingData.redirectPath.setChars 793 (path.getBuffer(), path.getStart(), path.getLength()); 794 } else { 795 mappingData.requestPath.setString(pathStr); 796 mappingData.wrapperPath.setString(pathStr); 797 } 798 } 799 } 800 801 path.setOffset(pathOffset); 802 path.setEnd(pathEnd); 803 804 } 805 806 807 810 private final void internalMapExactWrapper 811 (Wrapper[] wrappers, CharChunk path, MappingData mappingData) { 812 int pos = find(wrappers, path); 813 if ((pos != -1) && (path.equals(wrappers[pos].name))) { 814 mappingData.requestPath.setString(wrappers[pos].name); 815 mappingData.wrapperPath.setString(wrappers[pos].name); 816 mappingData.wrapper = wrappers[pos].object; 817 } 818 } 819 820 821 824 private final void internalMapWildcardWrapper 825 (Wrapper[] wrappers, int nesting, CharChunk path, 826 MappingData mappingData) { 827 828 int pathEnd = path.getEnd(); 829 int pathOffset = path.getOffset(); 830 831 int lastSlash = -1; 832 int length = -1; 833 int pos = find(wrappers, path); 834 if (pos != -1) { 835 boolean found = false; 836 while (pos >= 0) { 837 if (path.startsWith(wrappers[pos].name)) { 838 length = wrappers[pos].name.length(); 839 if (path.getLength() == length) { 840 found = true; 841 break; 842 } else if (path.startsWithIgnoreCase("/", length)) { 843 found = true; 844 break; 845 } 846 } 847 if (lastSlash == -1) { 848 lastSlash = nthSlash(path, nesting + 1); 849 } else { 850 lastSlash = lastSlash(path); 851 } 852 path.setEnd(lastSlash); 853 pos = find(wrappers, path); 854 } 855 path.setEnd(pathEnd); 856 if (found) { 857 mappingData.wrapperPath.setString(wrappers[pos].name); 858 if (path.getLength() > length) { 859 mappingData.pathInfo.setChars 860 (path.getBuffer(), 861 path.getOffset() + length, 862 path.getLength() - length); 863 } 864 mappingData.requestPath.setChars 865 (path.getBuffer(), path.getOffset(), path.getLength()); 866 mappingData.wrapper = wrappers[pos].object; 867 mappingData.jspWildCard = wrappers[pos].jspWildCard; 868 } 869 } 870 } 871 872 873 876 private final void internalMapExtensionWrapper 877 (Wrapper[] wrappers, CharChunk path, MappingData mappingData) { 878 char[] buf = path.getBuffer(); 879 int pathEnd = path.getEnd(); 880 int servletPath = path.getOffset(); 881 int slash = -1; 882 for (int i = pathEnd - 1; i >= servletPath; i--) { 883 if (buf[i] == '/') { 884 slash = i; 885 break; 886 } 887 } 888 if (slash >= 0) { 889 int period = -1; 890 for (int i = pathEnd - 1; i > slash; i--) { 891 if (buf[i] == '.') { 892 period = i; 893 break; 894 } 895 } 896 if (period >= 0) { 897 path.setOffset(period + 1); 898 path.setEnd(pathEnd); 899 int pos = find(wrappers, path); 900 if ((pos != -1) 901 && (path.equals(wrappers[pos].name))) { 902 mappingData.wrapperPath.setChars 903 (buf, servletPath, pathEnd - servletPath); 904 mappingData.requestPath.setChars 905 (buf, servletPath, pathEnd - servletPath); 906 mappingData.wrapper = wrappers[pos].object; 907 } 908 path.setOffset(servletPath); 909 path.setEnd(pathEnd); 910 } 911 } 912 } 913 914 915 920 private static final int find(MapElement[] map, CharChunk name) { 921 return find(map, name, name.getStart(), name.getEnd()); 922 } 923 924 925 930 private static final int find(MapElement[] map, CharChunk name, 931 int start, int end) { 932 933 int a = 0; 934 int b = map.length - 1; 935 936 if (b == -1) { 938 return -1; 939 } 940 941 if (compare(name, start, end, map[0].name) < 0 ) { 942 return -1; 943 } 944 if (b == 0) { 945 return 0; 946 } 947 948 int i = 0; 949 while (true) { 950 i = (b + a) / 2; 951 int result = compare(name, start, end, map[i].name); 952 if (result == 1) { 953 a = i; 954 } else if (result == 0) { 955 return i; 956 } else { 957 b = i; 958 } 959 if ((b - a) == 1) { 960 int result2 = compare(name, start, end, map[b].name); 961 if (result2 < 0) { 962 return a; 963 } else { 964 return b; 965 } 966 } 967 } 968 969 } 970 971 976 private static final int findIgnoreCase(MapElement[] map, CharChunk name) { 977 return findIgnoreCase(map, name, name.getStart(), name.getEnd()); 978 } 979 980 981 986 private static final int findIgnoreCase(MapElement[] map, CharChunk name, 987 int start, int end) { 988 989 int a = 0; 990 int b = map.length - 1; 991 992 if (b == -1) { 994 return -1; 995 } 996 if (compareIgnoreCase(name, start, end, map[0].name) < 0 ) { 997 return -1; 998 } 999 if (b == 0) { 1000 return 0; 1001 } 1002 1003 int i = 0; 1004 while (true) { 1005 i = (b + a) / 2; 1006 int result = compareIgnoreCase(name, start, end, map[i].name); 1007 if (result == 1) { 1008 a = i; 1009 } else if (result == 0) { 1010 return i; 1011 } else { 1012 b = i; 1013 } 1014 if ((b - a) == 1) { 1015 int result2 = compareIgnoreCase(name, start, end, map[b].name); 1016 if (result2 < 0) { 1017 return a; 1018 } else { 1019 return b; 1020 } 1021 } 1022 } 1023 1024 } 1025 1026 1027 1032 private static final int find(MapElement[] map, String name) { 1033 1034 int a = 0; 1035 int b = map.length - 1; 1036 1037 if (b == -1) { 1039 return -1; 1040 } 1041 1042 if (name.compareTo(map[0].name) < 0) { 1043 return -1; 1044 } 1045 if (b == 0) { 1046 return 0; 1047 } 1048 1049 int i = 0; 1050 while (true) { 1051 i = (b + a) / 2; 1052 int result = name.compareTo(map[i].name); 1053 if (result > 0) { 1054 a = i; 1055 } else if (result == 0) { 1056 return i; 1057 } else { 1058 b = i; 1059 } 1060 if ((b - a) == 1) { 1061 int result2 = name.compareTo(map[b].name); 1062 if (result2 < 0) { 1063 return a; 1064 } else { 1065 return b; 1066 } 1067 } 1068 } 1069 1070 } 1071 1072 1073 1077 private static final int compare(CharChunk name, int start, int end, 1078 String compareTo) { 1079 int result = 0; 1080 char[] c = name.getBuffer(); 1081 int len = compareTo.length(); 1082 if ((end - start) < len) { 1083 len = end - start; 1084 } 1085 for (int i = 0; (i < len) && (result == 0); i++) { 1086 if (c[i + start] > compareTo.charAt(i)) { 1087 result = 1; 1088 } else if (c[i + start] < compareTo.charAt(i)) { 1089 result = -1; 1090 } 1091 } 1092 if (result == 0) { 1093 if (compareTo.length() > (end - start)) { 1094 result = -1; 1095 } else if (compareTo.length() < (end - start)) { 1096 result = 1; 1097 } 1098 } 1099 return result; 1100 } 1101 1102 1103 1107 private static final int compareIgnoreCase(CharChunk name, int start, int end, 1108 String compareTo) { 1109 int result = 0; 1110 char[] c = name.getBuffer(); 1111 int len = compareTo.length(); 1112 if ((end - start) < len) { 1113 len = end - start; 1114 } 1115 for (int i = 0; (i < len) && (result == 0); i++) { 1116 if (Ascii.toLower(c[i + start]) > Ascii.toLower(compareTo.charAt(i))) { 1117 result = 1; 1118 } else if (Ascii.toLower(c[i + start]) < Ascii.toLower(compareTo.charAt(i))) { 1119 result = -1; 1120 } 1121 } 1122 if (result == 0) { 1123 if (compareTo.length() > (end - start)) { 1124 result = -1; 1125 } else if (compareTo.length() < (end - start)) { 1126 result = 1; 1127 } 1128 } 1129 return result; 1130 } 1131 1132 1133 1136 private static final int lastSlash(CharChunk name) { 1137 1138 char[] c = name.getBuffer(); 1139 int end = name.getEnd(); 1140 int start = name.getStart(); 1141 int pos = end; 1142 1143 while (pos > start) { 1144 if (c[--pos] == '/') { 1145 break; 1146 } 1147 } 1148 1149 return (pos); 1150 1151 } 1152 1153 1154 1157 private static final int nthSlash(CharChunk name, int n) { 1158 1159 char[] c = name.getBuffer(); 1160 int end = name.getEnd(); 1161 int start = name.getStart(); 1162 int pos = start; 1163 int count = 0; 1164 1165 while (pos < end) { 1166 if ((c[pos++] == '/') && ((++count) == n)) { 1167 pos--; 1168 break; 1169 } 1170 } 1171 1172 return (pos); 1173 1174 } 1175 1176 1177 1180 private static final int slashCount(String name) { 1181 int pos = -1; 1182 int count = 0; 1183 while ((pos = name.indexOf('/', pos + 1)) != -1) { 1184 count++; 1185 } 1186 return count; 1187 } 1188 1189 1190 1194 private static final boolean insertMap 1195 (MapElement[] oldMap, MapElement[] newMap, MapElement newElement) { 1196 int pos = find(oldMap, newElement.name); 1197 if ((pos != -1) && (newElement.name.equals(oldMap[pos].name))) { 1198 return false; 1199 } 1200 System.arraycopy(oldMap, 0, newMap, 0, pos + 1); 1201 newMap[pos + 1] = newElement; 1202 System.arraycopy 1203 (oldMap, pos + 1, newMap, pos + 2, oldMap.length - pos - 1); 1204 return true; 1205 } 1206 1207 1208 1211 private static final boolean removeMap 1212 (MapElement[] oldMap, MapElement[] newMap, String name) { 1213 int pos = find(oldMap, name); 1214 if ((pos != -1) && (name.equals(oldMap[pos].name))) { 1215 System.arraycopy(oldMap, 0, newMap, 0, pos); 1216 System.arraycopy(oldMap, pos + 1, newMap, pos, 1217 oldMap.length - pos - 1); 1218 return true; 1219 } 1220 return false; 1221 } 1222 1223 1224 1226 1227 protected static abstract class MapElement { 1228 1229 public String name = null; 1230 public Object object = null; 1231 1232 } 1233 1234 1235 1237 1238 protected static final class Host 1239 extends MapElement { 1240 1241 public ContextList contextList = null; 1242 1243 } 1244 1245 1246 1248 1249 protected static final class ContextList { 1250 1251 public Context [] contexts = new Context [0]; 1252 public int nesting = 0; 1253 1254 } 1255 1256 1257 1259 1260 protected static final class Context 1261 extends MapElement { 1262 1263 public String path = null; 1264 public String [] welcomeResources = new String [0]; 1265 public javax.naming.Context resources = null; 1266 public Wrapper defaultWrapper = null; 1267 public Wrapper[] exactWrappers = new Wrapper[0]; 1268 public Wrapper[] wildcardWrappers = new Wrapper[0]; 1269 public Wrapper[] extensionWrappers = new Wrapper[0]; 1270 public int nesting = 0; 1271 1272 } 1273 1274 1275 1277 1278 protected static class Wrapper 1279 extends MapElement { 1280 1281 public String path = null; 1282 public boolean jspWildCard = false; 1283 } 1284 1285 1286 1288 1395 1396 1397} 1398 | Popular Tags |