package com.foundation.web; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.security.KeyManagementException; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import com.common.io.StreamSupport; import com.common.util.IHashMap; import com.common.util.LiteHashMap; import com.foundation.web.WebApplication.SessionHandler; import com.foundation.web.WebApplication.PathSubstitution; import com.foundation.web.interfaces.IBadSessionHandler; public class WebOptions { private SessionHandler sessionHandler = null; private String[] domains = null; private String[] services = null; private SslMapping[] sslMappings = null; /** The directory where public static resources can be found - images, html, etc. */ private File baseDirectory = null; /** An optional directory where files are externally stored. These files are not part of the webapp's general distribution. */ private File externalBaseDirectory = null; /** An optional directory where cache files are stored. These files are not part of the webapp's general distribution and are fully re-creatable. */ private File cacheBaseDirectory = null; private IHashMap nameSubstitutionMap = new LiteHashMap(10); private IHashMap pathSubstitutionMap = new LiteHashMap(10); private String defaultPackageName = null; private long sessionTimeout = 3600000; private long sessionCheckInterval = 3600000; private IBadSessionHandler badSessionHandler = null; /** Replaces the default handling of a user's access to static (file system based) resources. Allows for permission validation. */ private IResourceRequestHandler resourceRequestHandler = null; /** Replaces the default handling of web dav requests. */ private IWebdavRequestHandler webdavRequestHandler = null; /** Sets the cutoff size for caching a file in memory. This may be zero to stop caching resources alltogether. Defaults to 10KB. */ private long cacheCutoffSize = 10000; /** Whether responses should be compressed by default when possible. Certain resources that compress poorly will of course ignore this directive. */ private boolean compressResponses = false; /** The handler called by the web server when deciding whether to retain a request's full byte buffer (exactly what bytes make up the request as received). A null value will turn this feature off entirely. */ private IRetainRequestBufferHandler retainRequestBufferHandler = null; /** * Maps an SSL Context to a domain. */ public static class SslMapping implements WebApplication.ISslMapping { private String[] domains; private SSLContext sslContext; private SslMapping(String[] domains, SSLContext sslContext) { this.domains = domains; this.sslContext = sslContext; }//SslMapping()// public String[] getDomains() { return domains; }//getDomains()// public SSLContext getSslContext() { return sslContext; }//getSslContext()// }//SslMapping// /** * Creates an SSL Mapping. * @param domains The domain(s) the mapping applies to. This is not case sensitive. These must be exact matches (wild cards not yet supported). * @param keyStore The path to the keystore for the SSL. * @param keyStorePassword The password for the keystore. * @param keyPassword The key's password. * @return The ssl mapping that can be passed to the web application's constructor. */ public static SslMapping createSslMapping(String[] domains, File keyStore, String keyStorePassword, String keyPassword) throws KeyStoreException, NoSuchAlgorithmException, NoSuchProviderException, IOException, CertificateException, UnrecoverableKeyException, KeyManagementException { //FileInputStream fin = null; try { KeyStore keystore = KeyStore.getInstance("JKS"); KeyManagerFactory keyManagerFactory; SSLContext sslContext; ByteArrayInputStream bin = new ByteArrayInputStream(StreamSupport.readBytes(keyStore)); //fin = new FileInputStream(keyStore); keystore.load(bin, keyStorePassword.toCharArray()); keyManagerFactory = KeyManagerFactory.getInstance("SunX509", "SunJSSE"); keyManagerFactory.init(keystore, keyPassword.toCharArray()); sslContext = SSLContext.getInstance("TLSv1", "SunJSSE"); //SSLv3 sslContext.init(keyManagerFactory.getKeyManagers(), null, null); for(int index = 0; index < domains.length; index++) { domains[index] = domains[index].toLowerCase(); }//for// return new SslMapping((String[]) domains.clone(), sslContext); }//try// finally { //if(fin != null) try {fin.close();} catch(Throwable e) {} }//finally// }//createSslMapping()// /** * WebOptions constructor. */ public WebOptions() { }//WebOptions()// public SessionHandler getSessionHandler() { return sessionHandler; }//getSessionHandler()// /** * Sets the session handler providing the user of the web application an easy way to add session functionality. * @param sessionHandler The session application code. */ public void setSessionHandler(SessionHandler sessionHandler) { this.sessionHandler = sessionHandler; }//setSessionHandler()// public String[] getDomains() { return domains; }//getDomains()// /** * Sets the domains the web application services. These are exact match only, wild cards are not yet supported. * @param domains The domains serviced. */ public void setDomains(String[] domains) { this.domains = domains; }//setDomains()// public String[] getServices() { return services; }//getServices()// /** * Sets the web server services (defined when setting up the webserver) that this application uses. * @param services The names of the services used by the application. */ public void setServices(String[] services) { this.services = services; }//setServices()// public SslMapping[] getSslMappings() { return sslMappings; }//getSslMappings()// /** * Sets the SSL mappings used by the application. * @param sslMappings Usually only one mapping between the domain(s) and a keystore. */ public void setSslMappings(SslMapping[] sslMappings) { this.sslMappings = sslMappings; }//setSslMappings()// public File getBaseDirectory() { return baseDirectory; }//getBaseDirectory()// /** * Sets the base *web* directory for the web application, where all the static resources can be found. This should be null if unknown. * @param baseDirectory The base directory, or null if the process's base directory should be used. */ public void setBaseDirectory(File baseDirectory) { this.baseDirectory = baseDirectory; }//setBaseDirectory()// public File getExternalBaseDirectory() { return externalBaseDirectory; }//getExternalBaseDirectory()// /** * Sets the optional, externally located base *web* directory for the web application. The files located here are not part of the webapp's distribution. * @param externalBaseDirectory The external base directory, or null if not used. */ public void setExternalBaseDirectory(File externalBaseDirectory) { this.externalBaseDirectory = externalBaseDirectory; }//setExternalBaseDirectory()// public File getCacheBaseDirectory() { return cacheBaseDirectory; }//getCacheBaseDirectory()// /** * Sets the optional base cache directory for the web application. The files located here are not part of the webapp's distribution and are fully re-creatable. * @param cacheBaseDirectory The cache base directory, or null if not used. */ public void setCacheBaseDirectory(File cacheBaseDirectory) { this.cacheBaseDirectory = cacheBaseDirectory; }//setCacheBaseDirectory()// public boolean getCompressResponses() { return compressResponses; }//getCompressResponses()// /** * Sets whether responses should be compressed by default when possible. Certain resources that compress poorly will of course ignore this directive. * @param compressResponses Whether responses that can be compressed should be by default. */ public void setCompressResponses(boolean compressResponses) { this.compressResponses = compressResponses; }//setCompressResponses()// public IHashMap getNameSubstitutionMap() { return nameSubstitutionMap; }//getNameSubstitutionMap()// /** * Sets the mapping between old resource names and new ones. * This is used to substitute just the ending name for another ending name. * It is not recommended to use this. *
TODO: Replace this with something that uses a regular expression like language.
* @param nameSubstitutionMap */ public void setNameSubstitutionMap(LiteHashMap nameSubstitutionMap) { this.nameSubstitutionMap = nameSubstitutionMap; }//setNameSubstitutionMap()// public IHashMap getPathSubstitutionMap() { return pathSubstitutionMap; }//getPathSubstitutionMap()// /** * Sets the mapping between old resource request paths and new ones. * This is used to substitute a *full* resource requested by the client with another *full* resource request. * For example: "/" -> "/index.html" will only alter http://mydomain.com/ to become http://mydomain.com/index.html, but won't modify http://mydomain.com/path/ at all. *TODO: Replace this with something that uses a regular expression like language.
* @param pathSubstitutionMap */ public void setPathSubstitutionMap(LiteHashMap pathSubstitutionMap) { this.pathSubstitutionMap = pathSubstitutionMap == null ? new LiteHashMap(10) : pathSubstitutionMap; }//setPathSubstitutionMap()// public String getDefaultPackageName() { return defaultPackageName; }//getDefaultPackageName()// /** * Sets the package fragment used as the base for all java class calls by the web client. * The web client can request a resource such as "controller.Login.java" (anything ending in .java) and this package name will be pre-pended to create the complete class name. * The class should implement IWebRequestHandler for the call to work. * @param defaultPackageName The package name fragment prefixed to java calls (generally should end with a dot). */ public void setDefaultPackageName(String defaultPackageName) { this.defaultPackageName = defaultPackageName; }//setDefaultPackageName()// public long getSessionTimeout() { return sessionTimeout; }//getSessionTimeout()// /** * Sets the amount of time (in milliseconds) before the session may be discarded. This defaults to 3600000 (1 hour). * @param sessionTimeout The number of milliseconds before the session garbage collector can release the session and all related resources. */ public void setSessionTimeout(long sessionTimeout) { this.sessionTimeout = sessionTimeout; }//setSessionTimeout()// public long getSessionCheckInterval() { return sessionCheckInterval; }//getSessionCheckInterval()// /** * Sets the number of milliseconds between checks to the sessions for stale ones. This defaults to 3600000 (1 hour). * @param sessionCheckInterval The amount of time between checking for and discarding old sessions. */ public void setSessionCheckInterval(long sessionCheckInterval) { this.sessionCheckInterval = sessionCheckInterval; }//setSessionCheckInterval()// public IBadSessionHandler getBadSessionHandler() { return badSessionHandler; }//getBadSessionHandler()// /** * ? * @param badSessionHandler */ public void setBadSessionHandler(IBadSessionHandler badSessionHandler) { this.badSessionHandler = badSessionHandler; }//setBadSessionHandler()// /** * Adds a resource name subtitution mapping where the old resource name will be replaced by the new resource name automatically prior to the request being processed. * @param oldName The old resource name. * @param newName The new resource name. */ public void addResourceNameSubstitution(String oldName, String newName) { nameSubstitutionMap.put(oldName, newName); }//addResourceNameSubstitution()// /** * Adds a path subtitution mapping where the old path will be replaced by the new path automatically prior to the request being processed. * @param oldPath The old resource name. eg: "/" * @param newPath The new resource name. eg: "/subdir/index.html" * @param forward Whether the substitution should constitute a forward (where the client is told of the new path) versus a redirect. */ public void addPathSubstitution(String oldPath, String newPath, boolean forward) { pathSubstitutionMap.put(oldPath, new PathSubstitution(newPath, forward)); }//addPathSubstitution()// /** * Gets the resource request handler which allows the application control over how users access static resources via the web server. * @return Replaces the default handling of a user's access to static (file system based) resources. Allows for permission validation. */ public IResourceRequestHandler getResourceRequestHandler() { return resourceRequestHandler; }//getResourceRequestHandler()// /** * Sets the resource request handler which allows the application control over how users access static resources via the web server. * @param resourceRequestHandler Replaces the default handling of a user's access to static (file system based) resources. Allows for permission validation. */ public void setResourceRequestHandler(IResourceRequestHandler resourceRequestHandler) { this.resourceRequestHandler = resourceRequestHandler; }//setResourceRequestHandler()// /** * Gets the web dav request handler. * @return Replaces the default handling of web dav commands. */ public IWebdavRequestHandler getWebdavRequestHandler() { return webdavRequestHandler; }//getWebdavRequestHandler()// /** * Sets the web dav request handler. * @param webdavRequestHandler Replaces the default handling of web dav commands. */ public void setWebdavRequestHandler(IWebdavRequestHandler webdavRequestHandler) { this.webdavRequestHandler = webdavRequestHandler; }//setWebdavRequestHandler()// public long getCacheCutoffSize() { return cacheCutoffSize; }//getCacheCutoffSize()// /** * Sets the cutoff size of a file qualifying it for caching. * @param cacheCutoffSize The number of bytes a file may contain in order to qualify for caching in memory. A zero indicates no caching will be performed. A value of less than zero is invalid and will default to zero. */ public void setCacheCutoffSize(long cacheCutoffSize) { this.cacheCutoffSize = cacheCutoffSize < 0 ? 0 : cacheCutoffSize; }//setCacheCutoffSize()// public IRetainRequestBufferHandler getRetainRequestBufferHandler() { return retainRequestBufferHandler; }//getRetainRequestBufferHandler()// /** * Gets the handler called by the web server when deciding whether to retain a request's full byte buffer (exactly what bytes make up the request as received). A null value will turn this feature off entirely. * @param retainRequestBufferHandler The handler used by the webserver to determine when to save the incoming request bytes. */ public void setRetainRequestBufferHandler(IRetainRequestBufferHandler retainRequestBufferHandler) { this.retainRequestBufferHandler = retainRequestBufferHandler; }//setRetainRequestBufferHandler()// }//WebOptions//