📄 applicationcontext.java
字号:
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.catalina.core;
import java.io.File;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import javax.naming.Binding;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import javax.servlet.RequestDispatcher;
import javax.servlet.Servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import org.apache.catalina.Context;
import org.apache.catalina.Host;
import org.apache.catalina.Wrapper;
import org.apache.catalina.deploy.ApplicationParameter;
import org.apache.catalina.util.Enumerator;
import org.apache.catalina.util.ResourceSet;
import org.apache.catalina.util.ServerInfo;
import org.apache.catalina.util.StringManager;
import org.apache.naming.resources.DirContextURLStreamHandler;
import org.apache.naming.resources.Resource;
import org.apache.tomcat.util.buf.CharChunk;
import org.apache.tomcat.util.buf.MessageBytes;
import org.apache.tomcat.util.http.mapper.MappingData;
/**
* Standard implementation of <code>ServletContext</code> that represents
* a web application's execution environment. An instance of this class is
* associated with each instance of <code>StandardContext</code>.
*
* @author Craig R. McClanahan
* @author Remy Maucherat
* @version $Revision: 467222 $ $Date: 2006-10-24 05:17:11 +0200 (mar., 24 oct. 2006) $
*/
public class ApplicationContext
implements ServletContext {
// ----------------------------------------------------------- Constructors
/**
* Construct a new instance of this class, associated with the specified
* Context instance.
*
* @param context The associated Context instance
*/
public ApplicationContext(String basePath, StandardContext context) {
super();
this.context = context;
this.basePath = basePath;
}
// ----------------------------------------------------- Instance Variables
/**
* The context attributes for this context.
*/
protected Map attributes = new ConcurrentHashMap();
/**
* List of read only attributes for this context.
*/
private Map readOnlyAttributes = new ConcurrentHashMap();
/**
* The Context instance with which we are associated.
*/
private StandardContext context = null;
/**
* Empty collection to serve as the basis for empty enumerations.
* <strong>DO NOT ADD ANY ELEMENTS TO THIS COLLECTION!</strong>
*/
private static final ArrayList empty = new ArrayList();
/**
* The facade around this object.
*/
private ServletContext facade = new ApplicationContextFacade(this);
/**
* The merged context initialization parameters for this Context.
*/
private Map parameters = null;
/**
* The string manager for this package.
*/
private static final StringManager sm =
StringManager.getManager(Constants.Package);
/**
* Base path.
*/
private String basePath = null;
/**
* Thread local mapping data.
*/
private ThreadLocal localMappingData = new ThreadLocal();
/**
* Thread local URI message bytes.
*/
private ThreadLocal localUriMB = new ThreadLocal();
// --------------------------------------------------------- Public Methods
/**
* Return the resources object that is mapped to a specified path.
* The path must begin with a "/" and is interpreted as relative to the
* current context root.
*/
public DirContext getResources() {
return context.getResources();
}
// ------------------------------------------------- ServletContext Methods
/**
* Return the value of the specified context attribute, if any;
* otherwise return <code>null</code>.
*
* @param name Name of the context attribute to return
*/
public Object getAttribute(String name) {
return (attributes.get(name));
}
/**
* Return an enumeration of the names of the context attributes
* associated with this context.
*/
public Enumeration getAttributeNames() {
return new Enumerator(attributes.keySet(), true);
}
/**
* Return a <code>ServletContext</code> object that corresponds to a
* specified URI on the server. This method allows servlets to gain
* access to the context for various parts of the server, and as needed
* obtain <code>RequestDispatcher</code> objects or resources from the
* context. The given path must be absolute (beginning with a "/"),
* and is interpreted based on our virtual host's document root.
*
* @param uri Absolute URI of a resource on the server
*/
public ServletContext getContext(String uri) {
// Validate the format of the specified argument
if ((uri == null) || (!uri.startsWith("/")))
return (null);
Context child = null;
try {
Host host = (Host) context.getParent();
String mapuri = uri;
while (true) {
child = (Context) host.findChild(mapuri);
if (child != null)
break;
int slash = mapuri.lastIndexOf('/');
if (slash < 0)
break;
mapuri = mapuri.substring(0, slash);
}
} catch (Throwable t) {
return (null);
}
if (child == null)
return (null);
if (context.getCrossContext()) {
// If crossContext is enabled, can always return the context
return child.getServletContext();
} else if (child == context) {
// Can still return the current context
return context.getServletContext();
} else {
// Nothing to return
return (null);
}
}
/**
* Return the main path associated with this context.
*/
public String getContextPath() {
return context.getPath();
}
/**
* Return the value of the specified initialization parameter, or
* <code>null</code> if this parameter does not exist.
*
* @param name Name of the initialization parameter to retrieve
*/
public String getInitParameter(final String name) {
mergeParameters();
return ((String) parameters.get(name));
}
/**
* Return the names of the context's initialization parameters, or an
* empty enumeration if the context has no initialization parameters.
*/
public Enumeration getInitParameterNames() {
mergeParameters();
return (new Enumerator(parameters.keySet()));
}
/**
* Return the major version of the Java Servlet API that we implement.
*/
public int getMajorVersion() {
return (Constants.MAJOR_VERSION);
}
/**
* Return the minor version of the Java Servlet API that we implement.
*/
public int getMinorVersion() {
return (Constants.MINOR_VERSION);
}
/**
* Return the MIME type of the specified file, or <code>null</code> if
* the MIME type cannot be determined.
*
* @param file Filename for which to identify a MIME type
*/
public String getMimeType(String file) {
if (file == null)
return (null);
int period = file.lastIndexOf(".");
if (period < 0)
return (null);
String extension = file.substring(period + 1);
if (extension.length() < 1)
return (null);
return (context.findMimeMapping(extension));
}
/**
* Return a <code>RequestDispatcher</code> object that acts as a
* wrapper for the named servlet.
*
* @param name Name of the servlet for which a dispatcher is requested
*/
public RequestDispatcher getNamedDispatcher(String name) {
// Validate the name argument
if (name == null)
return (null);
// Create and return a corresponding request dispatcher
Wrapper wrapper = (Wrapper) context.findChild(name);
if (wrapper == null)
return (null);
return new ApplicationDispatcher(wrapper, null, null, null, null, name);
}
/**
* Return the real path for a given virtual path, if possible; otherwise
* return <code>null</code>.
*
* @param path The path to the desired resource
*/
public String getRealPath(String path) {
if (!context.isFilesystemBased())
return null;
if (path == null) {
return null;
}
File file = new File(basePath, path);
return (file.getAbsolutePath());
}
/**
* Return a <code>RequestDispatcher</code> instance that acts as a
* wrapper for the resource at the given path. The path must begin
* with a "/" and is interpreted as relative to the current context root.
*
* @param path The path to the desired resource.
*/
public RequestDispatcher getRequestDispatcher(String path) {
// Validate the path argument
if (path == null)
return (null);
if (!path.startsWith("/"))
throw new IllegalArgumentException
(sm.getString
("applicationContext.requestDispatcher.iae", path));
path = normalize(path);
if (path == null)
return (null);
// Retrieve the thread local URI
MessageBytes uriMB = (MessageBytes) localUriMB.get();
if (uriMB == null) {
uriMB = MessageBytes.newInstance();
CharChunk uriCC = uriMB.getCharChunk();
uriCC.setLimit(-1);
localUriMB.set(uriMB);
} else {
uriMB.recycle();
}
// Get query string
String queryString = null;
int pos = path.indexOf('?');
if (pos >= 0) {
queryString = path.substring(pos + 1);
} else {
pos = path.length();
}
// Retrieve the thread local mapping data
MappingData mappingData = (MappingData) localMappingData.get();
if (mappingData == null) {
mappingData = new MappingData();
localMappingData.set(mappingData);
}
// Map the URI
CharChunk uriCC = uriMB.getCharChunk();
try {
uriCC.append(context.getPath(), 0, context.getPath().length());
/*
* Ignore any trailing path params (separated by ';') for mapping
* purposes
*/
int semicolon = path.indexOf(';');
if (pos >= 0 && semicolon > pos) {
semicolon = -1;
}
uriCC.append(path, 0, semicolon > 0 ? semicolon : pos);
context.getMapper().map(uriMB, mappingData);
if (mappingData.wrapper == null) {
return (null);
}
/*
* Append any trailing path params (separated by ';') that were
* ignored for mapping purposes, so that they're reflected in the
* RequestDispatcher's requestURI
*/
if (semicolon > 0) {
uriCC.append(path, semicolon, pos - semicolon);
}
} catch (Exception e) {
// Should never happen
log(sm.getString("applicationContext.mapping.error"), e);
return (null);
}
Wrapper wrapper = (Wrapper) mappingData.wrapper;
String wrapperPath = mappingData.wrapperPath.toString();
String pathInfo = mappingData.pathInfo.toString();
mappingData.recycle();
// Construct a RequestDispatcher to process this request
return new ApplicationDispatcher
(wrapper, uriCC.toString(), wrapperPath, pathInfo,
queryString, null);
}
/**
* Return the URL to the resource that is mapped to a specified path.
* The path must begin with a "/" and is interpreted as relative to the
* current context root.
*
* @param path The path to the desired resource
*
* @exception MalformedURLException if the path is not given
* in the correct form
*/
public URL getResource(String path)
throws MalformedURLException {
if (path == null || !path.startsWith("/")) {
throw new MalformedURLException(sm.getString("applicationContext.requestDispatcher.iae", path));
}
path = normalize(path);
if (path == null)
return (null);
String libPath = "/WEB-INF/lib/";
if ((path.startsWith(libPath)) && (path.endsWith(".jar"))) {
File jarFile = null;
if (context.isFilesystemBased()) {
jarFile = new File(basePath, path);
} else {
jarFile = new File(context.getWorkPath(), path);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -