1 17 18 19 package org.apache.catalina.core; 20 21 22 import java.io.File ; 23 import java.io.InputStream ; 24 import java.net.MalformedURLException ; 25 import java.net.URL ; 26 import java.util.ArrayList ; 27 import java.util.Enumeration ; 28 import java.util.Iterator ; 29 import java.util.Map ; 30 import java.util.Set ; 31 import java.util.concurrent.ConcurrentHashMap ; 32 33 import javax.naming.Binding ; 34 import javax.naming.NamingException ; 35 import javax.naming.directory.DirContext ; 36 import javax.servlet.RequestDispatcher ; 37 import javax.servlet.Servlet ; 38 import javax.servlet.ServletContext ; 39 import javax.servlet.ServletContextAttributeEvent ; 40 import javax.servlet.ServletContextAttributeListener ; 41 42 import org.apache.catalina.Context; 43 import org.apache.catalina.Host; 44 import org.apache.catalina.Wrapper; 45 import org.apache.catalina.deploy.ApplicationParameter; 46 import org.apache.catalina.util.Enumerator; 47 import org.apache.catalina.util.ResourceSet; 48 import org.apache.catalina.util.ServerInfo; 49 import org.apache.catalina.util.StringManager; 50 import org.apache.naming.resources.DirContextURLStreamHandler; 51 import org.apache.naming.resources.Resource; 52 import org.apache.tomcat.util.buf.CharChunk; 53 import org.apache.tomcat.util.buf.MessageBytes; 54 import org.apache.tomcat.util.http.mapper.MappingData; 55 56 57 66 67 public class ApplicationContext 68 implements ServletContext { 69 70 72 73 79 public ApplicationContext(String basePath, StandardContext context) { 80 super(); 81 this.context = context; 82 this.basePath = basePath; 83 } 84 85 86 88 89 92 protected Map attributes = new ConcurrentHashMap (); 93 94 95 98 private Map readOnlyAttributes = new ConcurrentHashMap (); 99 100 101 104 private StandardContext context = null; 105 106 107 111 private static final ArrayList empty = new ArrayList (); 112 113 114 117 private ServletContext facade = new ApplicationContextFacade(this); 118 119 120 123 private Map parameters = null; 124 125 126 129 private static final StringManager sm = 130 StringManager.getManager(Constants.Package); 131 132 133 136 private String basePath = null; 137 138 139 142 private ThreadLocal localMappingData = new ThreadLocal (); 143 144 145 148 private ThreadLocal localUriMB = new ThreadLocal (); 149 150 151 153 154 159 public DirContext getResources() { 160 161 return context.getResources(); 162 163 } 164 165 166 168 169 175 public Object getAttribute(String name) { 176 177 return (attributes.get(name)); 178 179 } 180 181 182 186 public Enumeration getAttributeNames() { 187 188 return new Enumerator(attributes.keySet(), true); 189 190 } 191 192 193 203 public ServletContext getContext(String uri) { 204 205 if ((uri == null) || (!uri.startsWith("/"))) 207 return (null); 208 209 Context child = null; 210 try { 211 Host host = (Host) context.getParent(); 212 String mapuri = uri; 213 while (true) { 214 child = (Context ) host.findChild(mapuri); 215 if (child != null) 216 break; 217 int slash = mapuri.lastIndexOf('/'); 218 if (slash < 0) 219 break; 220 mapuri = mapuri.substring(0, slash); 221 } 222 } catch (Throwable t) { 223 return (null); 224 } 225 226 if (child == null) 227 return (null); 228 229 if (context.getCrossContext()) { 230 return child.getServletContext(); 232 } else if (child == context) { 233 return context.getServletContext(); 235 } else { 236 return (null); 238 } 239 } 240 241 242 245 public String getContextPath() { 246 return context.getPath(); 247 } 248 249 250 256 public String getInitParameter(final String name) { 257 258 mergeParameters(); 259 return ((String ) parameters.get(name)); 260 261 } 262 263 264 268 public Enumeration getInitParameterNames() { 269 270 mergeParameters(); 271 return (new Enumerator(parameters.keySet())); 272 273 } 274 275 276 279 public int getMajorVersion() { 280 281 return (Constants.MAJOR_VERSION); 282 283 } 284 285 286 289 public int getMinorVersion() { 290 291 return (Constants.MINOR_VERSION); 292 293 } 294 295 296 302 public String getMimeType(String file) { 303 304 if (file == null) 305 return (null); 306 int period = file.lastIndexOf("."); 307 if (period < 0) 308 return (null); 309 String extension = file.substring(period + 1); 310 if (extension.length() < 1) 311 return (null); 312 return (context.findMimeMapping(extension)); 313 314 } 315 316 317 323 public RequestDispatcher getNamedDispatcher(String name) { 324 325 if (name == null) 327 return (null); 328 329 Wrapper wrapper = (Wrapper) context.findChild(name); 331 if (wrapper == null) 332 return (null); 333 334 return new ApplicationDispatcher(wrapper, null, null, null, null, name); 335 336 } 337 338 339 345 public String getRealPath(String path) { 346 347 if (!context.isFilesystemBased()) 348 return null; 349 350 if (path == null) { 351 return null; 352 } 353 354 File file = new File (basePath, path); 355 return (file.getAbsolutePath()); 356 357 } 358 359 360 367 public RequestDispatcher getRequestDispatcher(String path) { 368 369 if (path == null) 371 return (null); 372 if (!path.startsWith("/")) 373 throw new IllegalArgumentException 374 (sm.getString 375 ("applicationContext.requestDispatcher.iae", path)); 376 path = normalize(path); 377 if (path == null) 378 return (null); 379 380 MessageBytes uriMB = (MessageBytes) localUriMB.get(); 382 if (uriMB == null) { 383 uriMB = MessageBytes.newInstance(); 384 CharChunk uriCC = uriMB.getCharChunk(); 385 uriCC.setLimit(-1); 386 localUriMB.set(uriMB); 387 } else { 388 uriMB.recycle(); 389 } 390 391 String queryString = null; 393 int pos = path.indexOf('?'); 394 if (pos >= 0) { 395 queryString = path.substring(pos + 1); 396 } else { 397 pos = path.length(); 398 } 399 400 MappingData mappingData = (MappingData) localMappingData.get(); 402 if (mappingData == null) { 403 mappingData = new MappingData(); 404 localMappingData.set(mappingData); 405 } 406 407 CharChunk uriCC = uriMB.getCharChunk(); 409 try { 410 uriCC.append(context.getPath(), 0, context.getPath().length()); 411 415 int semicolon = path.indexOf(';'); 416 if (pos >= 0 && semicolon > pos) { 417 semicolon = -1; 418 } 419 uriCC.append(path, 0, semicolon > 0 ? semicolon : pos); 420 context.getMapper().map(uriMB, mappingData); 421 if (mappingData.wrapper == null) { 422 return (null); 423 } 424 429 if (semicolon > 0) { 430 uriCC.append(path, semicolon, pos - semicolon); 431 } 432 } catch (Exception e) { 433 log(sm.getString("applicationContext.mapping.error"), e); 435 return (null); 436 } 437 438 Wrapper wrapper = (Wrapper) mappingData.wrapper; 439 String wrapperPath = mappingData.wrapperPath.toString(); 440 String pathInfo = mappingData.pathInfo.toString(); 441 442 mappingData.recycle(); 443 444 return new ApplicationDispatcher 446 (wrapper, uriCC.toString(), wrapperPath, pathInfo, 447 queryString, null); 448 449 } 450 451 452 453 463 public URL getResource(String path) 464 throws MalformedURLException { 465 466 if (path == null || !path.startsWith("/")) { 467 throw new MalformedURLException (sm.getString("applicationContext.requestDispatcher.iae", path)); 468 } 469 470 path = normalize(path); 471 if (path == null) 472 return (null); 473 474 String libPath = "/WEB-INF/lib/"; 475 if ((path.startsWith(libPath)) && (path.endsWith(".jar"))) { 476 File jarFile = null; 477 if (context.isFilesystemBased()) { 478 jarFile = new File (basePath, path); 479 } else { 480 jarFile = new File (context.getWorkPath(), path); 481 } 482 if (jarFile.exists()) { 483 return jarFile.toURL(); 484 } else { 485 return null; 486 } 487 } else { 488 489 DirContext resources = context.getResources(); 490 if (resources != null) { 491 String fullPath = context.getName() + path; 492 String hostName = context.getParent().getName(); 493 try { 494 resources.lookup(path); 495 return new URL 496 ("jndi", "", 0, getJNDIUri(hostName, fullPath), 497 new DirContextURLStreamHandler(resources)); 498 } catch (Exception e) { 499 } 501 } 502 } 503 504 return (null); 505 506 } 507 508 509 517 public InputStream getResourceAsStream(String path) { 518 519 path = normalize(path); 520 if (path == null) 521 return (null); 522 523 DirContext resources = context.getResources(); 524 if (resources != null) { 525 try { 526 Object resource = resources.lookup(path); 527 if (resource instanceof Resource) 528 return (((Resource) resource).streamContent()); 529 } catch (Exception e) { 530 } 531 } 532 return (null); 533 534 } 535 536 537 544 public Set getResourcePaths(String path) { 545 546 if (path == null) { 548 return null; 549 } 550 if (!path.startsWith("/")) { 551 throw new IllegalArgumentException 552 (sm.getString("applicationContext.resourcePaths.iae", path)); 553 } 554 555 path = normalize(path); 556 if (path == null) 557 return (null); 558 559 DirContext resources = context.getResources(); 560 if (resources != null) { 561 return (getResourcePathsInternal(resources, path)); 562 } 563 return (null); 564 565 } 566 567 568 574 private Set getResourcePathsInternal(DirContext resources, String path) { 575 576 ResourceSet set = new ResourceSet(); 577 try { 578 listCollectionPaths(set, resources, path); 579 } catch (NamingException e) { 580 return (null); 581 } 582 set.setLocked(true); 583 return (set); 584 585 } 586 587 588 591 public String getServerInfo() { 592 593 return (ServerInfo.getServerInfo()); 594 595 } 596 597 598 601 public Servlet getServlet(String name) { 602 603 return (null); 604 605 } 606 607 608 611 public String getServletContextName() { 612 613 return (context.getDisplayName()); 614 615 } 616 617 618 621 public Enumeration getServletNames() { 622 return (new Enumerator(empty)); 623 } 624 625 626 629 public Enumeration getServlets() { 630 return (new Enumerator(empty)); 631 } 632 633 634 639 public void log(String message) { 640 641 context.getLogger().info(message); 642 643 } 644 645 646 655 public void log(Exception exception, String message) { 656 657 context.getLogger().error(message, exception); 658 659 } 660 661 662 668 public void log(String message, Throwable throwable) { 669 670 context.getLogger().error(message, throwable); 671 672 } 673 674 675 680 public void removeAttribute(String name) { 681 682 Object value = null; 683 boolean found = false; 684 685 if (readOnlyAttributes.containsKey(name)) 688 return; 689 found = attributes.containsKey(name); 690 if (found) { 691 value = attributes.get(name); 692 attributes.remove(name); 693 } else { 694 return; 695 } 696 697 Object listeners[] = context.getApplicationEventListeners(); 699 if ((listeners == null) || (listeners.length == 0)) 700 return; 701 ServletContextAttributeEvent event = 702 new ServletContextAttributeEvent (context.getServletContext(), 703 name, value); 704 for (int i = 0; i < listeners.length; i++) { 705 if (!(listeners[i] instanceof ServletContextAttributeListener )) 706 continue; 707 ServletContextAttributeListener listener = 708 (ServletContextAttributeListener ) listeners[i]; 709 try { 710 context.fireContainerEvent("beforeContextAttributeRemoved", 711 listener); 712 listener.attributeRemoved(event); 713 context.fireContainerEvent("afterContextAttributeRemoved", 714 listener); 715 } catch (Throwable t) { 716 context.fireContainerEvent("afterContextAttributeRemoved", 717 listener); 718 log(sm.getString("applicationContext.attributeEvent"), t); 720 } 721 } 722 723 } 724 725 726 733 public void setAttribute(String name, Object value) { 734 735 if (name == null) 737 throw new IllegalArgumentException 738 (sm.getString("applicationContext.setAttribute.namenull")); 739 740 if (value == null) { 742 removeAttribute(name); 743 return; 744 } 745 746 Object oldValue = null; 747 boolean replaced = false; 748 749 if (readOnlyAttributes.containsKey(name)) 752 return; 753 oldValue = attributes.get(name); 754 if (oldValue != null) 755 replaced = true; 756 attributes.put(name, value); 757 758 Object listeners[] = context.getApplicationEventListeners(); 760 if ((listeners == null) || (listeners.length == 0)) 761 return; 762 ServletContextAttributeEvent event = null; 763 if (replaced) 764 event = 765 new ServletContextAttributeEvent (context.getServletContext(), 766 name, oldValue); 767 else 768 event = 769 new ServletContextAttributeEvent (context.getServletContext(), 770 name, value); 771 772 for (int i = 0; i < listeners.length; i++) { 773 if (!(listeners[i] instanceof ServletContextAttributeListener )) 774 continue; 775 ServletContextAttributeListener listener = 776 (ServletContextAttributeListener ) listeners[i]; 777 try { 778 if (replaced) { 779 context.fireContainerEvent 780 ("beforeContextAttributeReplaced", listener); 781 listener.attributeReplaced(event); 782 context.fireContainerEvent("afterContextAttributeReplaced", 783 listener); 784 } else { 785 context.fireContainerEvent("beforeContextAttributeAdded", 786 listener); 787 listener.attributeAdded(event); 788 context.fireContainerEvent("afterContextAttributeAdded", 789 listener); 790 } 791 } catch (Throwable t) { 792 if (replaced) 793 context.fireContainerEvent("afterContextAttributeReplaced", 794 listener); 795 else 796 context.fireContainerEvent("afterContextAttributeAdded", 797 listener); 798 log(sm.getString("applicationContext.attributeEvent"), t); 800 } 801 } 802 803 } 804 805 806 808 809 812 void clearAttributes() { 813 814 ArrayList list = new ArrayList (); 816 Iterator iter = attributes.keySet().iterator(); 817 while (iter.hasNext()) { 818 list.add(iter.next()); 819 } 820 821 Iterator keys = list.iterator(); 824 while (keys.hasNext()) { 825 String key = (String ) keys.next(); 826 removeAttribute(key); 827 } 828 829 } 830 831 832 835 protected ServletContext getFacade() { 836 837 return (this.facade); 838 839 } 840 841 842 845 void setAttributeReadOnly(String name) { 846 847 if (attributes.containsKey(name)) 848 readOnlyAttributes.put(name, name); 849 850 } 851 852 853 855 856 865 private String normalize(String path) { 866 867 if (path == null) { 868 return null; 869 } 870 871 String normalized = path; 872 873 if (normalized.indexOf('\\') >= 0) 875 normalized = normalized.replace('\\', '/'); 876 877 while (true) { 879 int index = normalized.indexOf("/../"); 880 if (index < 0) 881 break; 882 if (index == 0) 883 return (null); int index2 = normalized.lastIndexOf('/', index - 1); 885 normalized = normalized.substring(0, index2) + 886 normalized.substring(index + 3); 887 } 888 889 return (normalized); 891 892 } 893 894 895 901 private void mergeParameters() { 902 903 if (parameters != null) 904 return; 905 Map results = new ConcurrentHashMap (); 906 String names[] = context.findParameters(); 907 for (int i = 0; i < names.length; i++) 908 results.put(names[i], context.findParameter(names[i])); 909 ApplicationParameter params[] = 910 context.findApplicationParameters(); 911 for (int i = 0; i < params.length; i++) { 912 if (params[i].getOverride()) { 913 if (results.get(params[i].getName()) == null) 914 results.put(params[i].getName(), params[i].getValue()); 915 } else { 916 results.put(params[i].getName(), params[i].getValue()); 917 } 918 } 919 parameters = results; 920 921 } 922 923 924 928 private static void listCollectionPaths 929 (Set set, DirContext resources, String path) 930 throws NamingException { 931 932 Enumeration childPaths = resources.listBindings(path); 933 while (childPaths.hasMoreElements()) { 934 Binding binding = (Binding ) childPaths.nextElement(); 935 String name = binding.getName(); 936 StringBuffer childPath = new StringBuffer (path); 937 if (!"/".equals(path) && !path.endsWith("/")) 938 childPath.append("/"); 939 childPath.append(name); 940 Object object = binding.getObject(); 941 if (object instanceof DirContext ) { 942 childPath.append("/"); 943 } 944 set.add(childPath.toString()); 945 } 946 947 } 948 949 950 953 private static String getJNDIUri(String hostName, String path) { 954 if (!path.startsWith("/")) 955 return "/" + hostName + "/" + path; 956 else 957 return "/" + hostName + path; 958 } 959 960 961 } 962 | Popular Tags |