blob: c25e03e044e735760b4d573f8e4bd3a892720f24 [file] [log] [blame]
package org.eclipse.equinox.http.servlet.internal;
import java.io.File;
import java.util.*;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import org.osgi.service.http.HttpContext;
/**
* The ProxyContext provides something similar to a ServletContext for all servlets and resources under a particular ProxyServlet.
* In particular it holds and represent the concept of "context path" through the Proxy Servlets servlet path.
* The Http Service also requires a ServletContext namespaced by each individual HttpContext. The ProxyContext provides support for the
* attribute map of a ServletContext again namespaced by HttpContext as specified in the Http Service specification. The ContextAttributes
* are reference counted so that when the HttpContext is no longer referenced the associated context attributes can be
* garbage collected and the context temp dir deleteted.
*/
public class ProxyContext {
private static final String JAVAX_SERVLET_CONTEXT_TEMPDIR = "javax.servlet.context.tempdir"; //$NON-NLS-1$
private String servletPath;
private HashMap attributesMap = new HashMap();
File proxyContextTempDir;
public ProxyContext(ServletContext servletContext) {
File tempDir = (File) servletContext.getAttribute(JAVAX_SERVLET_CONTEXT_TEMPDIR);
if (tempDir != null) {
proxyContextTempDir = new File(tempDir, "proxytemp"); //$NON-NLS-1$
deleteDirectory(proxyContextTempDir);
proxyContextTempDir.mkdirs();
}
}
public void destroy() {
if (proxyContextTempDir != null)
deleteDirectory(proxyContextTempDir);
}
synchronized void initializeServletPath(HttpServletRequest req) {
if (servletPath == null)
servletPath = HttpServletRequestAdaptor.getDispatchServletPath(req);
}
synchronized String getServletPath() {
return servletPath;
}
synchronized void createContextAttributes(HttpContext httpContext) {
ContextAttributes attributes = (ContextAttributes) attributesMap.get(httpContext);
if (attributes == null) {
attributes = new ContextAttributes(httpContext);
attributesMap.put(httpContext, attributes);
}
attributes.addReference();
}
synchronized void destroyContextAttributes(HttpContext httpContext) {
ContextAttributes attributes = (ContextAttributes) attributesMap.get(httpContext);
attributes.removeReference();
if (attributes.referenceCount() == 0) {
attributesMap.remove(httpContext);
attributes.destroy();
}
}
synchronized Dictionary getContextAttributes(HttpContext httpContext) {
return (Dictionary) attributesMap.get(httpContext);
}
/**
* deleteDirectory is a convenience method to recursively delete a directory
* @param directory - the directory to delete.
* @return was the delete succesful
*/
protected static boolean deleteDirectory(File directory) {
if (directory.exists() && directory.isDirectory()) {
File[] files = directory.listFiles();
for (int i = 0; i < files.length; i++) {
if (files[i].isDirectory()) {
deleteDirectory(files[i]);
} else {
files[i].delete();
}
}
}
return directory.delete();
}
public class ContextAttributes extends Hashtable {
private static final long serialVersionUID = 1916670423277243587L;
private int referenceCount;
public ContextAttributes(HttpContext httpContext) {
if (proxyContextTempDir != null) {
File contextTempDir = new File(proxyContextTempDir, "hc_" + httpContext.hashCode()); //$NON-NLS-1$
contextTempDir.mkdirs();
put(JAVAX_SERVLET_CONTEXT_TEMPDIR, contextTempDir);
}
}
public void destroy() {
File contextTempDir = (File) get(JAVAX_SERVLET_CONTEXT_TEMPDIR);
if (contextTempDir != null)
deleteDirectory(contextTempDir);
}
public void addReference() {
referenceCount++;
}
public void removeReference() {
referenceCount--;
}
public int referenceCount() {
return referenceCount;
}
}
}