A crapload of changes: load more stuff from servlet config; message

manager now supports site-specific translation messages; application
automatically configures Velocity to use things like the
SiteResourceManager and the ImportDirective.


git-svn-id: https://samskivert.googlecode.com/svn/trunk@434 6335cc39-0255-0410-8fd6-9bcaacd3b74c
This commit is contained in:
mdb
2001-11-06 20:16:47 +00:00
parent ef8376124a
commit 383632dd53
5 changed files with 300 additions and 193 deletions
@@ -1,5 +1,5 @@
//
// $Id: MessageManager.java,v 1.3 2001/11/06 05:35:54 mdb Exp $
// $Id: MessageManager.java,v 1.4 2001/11/06 20:16:46 mdb Exp $
//
// samskivert library - useful routines for java programs
// Copyright (C) 2001 Michael Bayne
@@ -20,11 +20,14 @@
package com.samskivert.servlet;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.*;
import javax.servlet.http.HttpServletRequest;
import com.samskivert.Log;
import com.samskivert.util.StringUtil;
/**
* The message manager handles the translation messages for a web
@@ -48,6 +51,29 @@ public class MessageManager
_bundlePath = bundlePath;
}
/**
* If the message manager is to be used in a multi-site environment,
* it can be configured to load site-specific message resources in
* addition to the default application message resources. It must be
* configured with the facilities to load site-specific resources by a
* call to this function.
*
* @param siteBundlePath the path to the site-specific message
* resources.
* @param siteLoader a site-specific resource loader, properly
* configured with a site identifier.
* @param siteIdent a site identifier that can be used to identify the
* site via which an http request was made.
*/
public void activateSiteSpecificMessages (String siteBundlePath,
SiteResourceLoader siteLoader,
SiteIdentifier siteIdent)
{
_siteBundlePath = siteBundlePath;
_siteLoader = siteLoader;
_siteIdent = siteIdent;
}
/**
* Looks up the message with the specified path in the resource bundle
* most appropriate for the locales described as preferred by the
@@ -55,22 +81,26 @@ public class MessageManager
*/
public String getMessage (HttpServletRequest req, String path)
{
try {
// use the locale preferred by the client if possible
ResourceBundle bundle = resolveBundle(req);
if (bundle != null) {
return bundle.getString(path);
// load up the matching resource bundles (the array will contain
// the site-specific resources first and the application resources
// second); use the locale preferred by the client if possible
ResourceBundle[] bundles = resolveBundles(req);
if (bundles != null) {
int blength = bundles.length;
for (int i = 0; i < blength; i++) {
try {
if (bundles[i] != null) {
return bundles[i].getString(path);
}
} catch (MissingResourceException mre) {
// no complaints, just try the bundle in the enclosing
// scope
}
}
// if we couldn't find a bundle, things are way wacked out,
// but we've already complained about it so we just fall
// through and return the path back to the caller
} catch (MissingResourceException mre) {
// if there's no translation for this path, complain about it
Log.warning("Missing translation message [path=" + path + "].");
}
// if there's no translation for this path, complain about it
Log.warning("Missing translation message [path=" + path + "].");
return path;
}
@@ -85,44 +115,63 @@ public class MessageManager
public String getMessage (HttpServletRequest req, String path,
Object[] args)
{
try {
// use the locale preferred by the client if possible
ResourceBundle bundle = resolveBundle(req);
if (bundle != null) {
String msg = bundle.getString(path);
// we may cache message formatters later, but for now just
// use the static convenience function
return MessageFormat.format(msg, args);
}
// if we couldn't find a bundle, things are way wacked out,
// but we've already complained about it so we just fall
// through and return the path back to the caller
} catch (MissingResourceException mre) {
// if there's no translation for this path, complain about it
Log.warning("Missing translation message [path=" + path + "].");
}
return path;
String msg = getMessage(req, path);
// we may cache message formatters later, but for now just
// use the static convenience function
return MessageFormat.format(msg, args);
}
/**
* Finds the closest matching resource bundle for the locales
* specified as preferred by the client in the supplied http request.
*/
protected ResourceBundle resolveBundle (HttpServletRequest req)
throws MissingResourceException
protected ResourceBundle[] resolveBundles (HttpServletRequest req)
{
// first look to see if we've cached the bundle for this request
// first look to see if we've cached the bundles for this request
// in the request object
ResourceBundle bundle = (ResourceBundle)
ResourceBundle[] bundles = (ResourceBundle[])
req.getAttribute(BUNDLE_CACHE_NAME);
if (bundle != null) {
return bundle;
if (bundles != null) {
return bundles;
}
// otherwise try looking up the appropriate bundle
int siteId = _siteIdent.identifySite(req);
ClassLoader siteLoader = null;
try {
siteLoader = _siteLoader.getSiteClassLoader(siteId);
} catch (IOException ioe) {
Log.warning("Unable to fetch site-specific classloader " +
"[siteId=" + siteId + ", error=" + ioe + "].");
}
// otherwise try looking up the appropriate bundles
bundles = new ResourceBundle[2];
// first from the site-specific classloader (if we've got one)
if (siteLoader != null) {
bundles[0] = resolveBundle(req, _siteBundlePath, siteLoader);
}
// then from the default classloader
bundles[1] = resolveBundle(req, _bundlePath,
getClass().getClassLoader());
// if we found either or both bundles, cache 'em
if (bundles[0] != null || bundles[1] != null) {
req.setAttribute(BUNDLE_CACHE_NAME, bundles);
}
return bundles;
}
/**
* Resolves the default resource bundle based on the locale
* information provided in the supplied http request object.
*/
protected ResourceBundle resolveBundle (
HttpServletRequest req, String bundlePath, ClassLoader loader)
{
ResourceBundle bundle = null;
Enumeration locales = req.getLocales();
while (locales.hasMoreElements()) {
@@ -137,7 +186,8 @@ public class MessageManager
// matches on any of the preferred locales specified by
// the client. if we don't, then we can rely on java's
// fallback mechanisms
bundle = ResourceBundle.getBundle(_bundlePath, locale);
bundle = ResourceBundle.getBundle(
bundlePath, locale, loader);
// if it's an exact match, off we go
if (bundle.getLocale().equals(locale)) {
@@ -156,28 +206,36 @@ public class MessageManager
if (bundle == null) {
try {
bundle = ResourceBundle.getBundle(
_bundlePath, req.getLocale());
bundlePath, req.getLocale(), loader);
} catch (MissingResourceException mre) {
// if we were unable even to find a default bundle, we've
// got real problems. time to freak out
Log.warning("Unable to resolve any message bundle " +
"[bundlePath=" + _bundlePath +
", locale=" + req.getLocale() + "].");
"[bundlePath=" + bundlePath +
", locale=" + req.getLocale() +
", loader=" + loader + "].");
}
}
// if we found a bundle, cache it
if (bundle != null) {
req.setAttribute(BUNDLE_CACHE_NAME, bundle);
}
return bundle;
}
/** The path, relative to the classpath, to our resource bundles. */
protected String _bundlePath;
/** The path to the site-specific message bundles, fetched via the
* site-specific resource loader. */
protected String _siteBundlePath;
/** The resource loader with which to fetch our site-specific message
* bundles. */
protected SiteResourceLoader _siteLoader;
/** The site identifier we use to determine through which site a
* request was made. */
protected SiteIdentifier _siteIdent;
/** The attribute name that we use for caching resource bundles in
* request objects. */
protected static final String BUNDLE_CACHE_NAME =
@@ -1,5 +1,5 @@
//
// $Id: SiteResourceLoader.java,v 1.5 2001/11/06 05:37:57 mdb Exp $
// $Id: SiteResourceLoader.java,v 1.6 2001/11/06 20:16:46 mdb Exp $
//
// samskivert library - useful routines for java programs
// Copyright (C) 2001 Michael Bayne
@@ -28,7 +28,6 @@ import java.io.InputStream;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import com.samskivert.Log;
@@ -39,9 +38,7 @@ import com.samskivert.util.HashIntMap;
* on which they are running is allowed to override a resource with a
* site-specific version (a header, footer or navigation template for
* example). The site resource loader provides this capability by loading
* resources, first from a site-specific jar file and if that doesn't
* contain an overriding resource, it loads the resource via the servlet
* context.
* resources from a site-specific jar file.
*
* <p> The site resource loader must be configured with the path to the
* site-specific jar files, the names of which are dictated by the string
@@ -52,12 +49,6 @@ import com.samskivert.util.HashIntMap;
* returns <code>samskivert</code> as the site identifier for a particular
* request, site-specific resources will be loaded from
* <code>/usr/share/java/webapps/site-data/samskivert.jar</code>.
*
* <p> Also note that if the site identifier returns {@link
* SiteIdentifier#DEFAULT_SITE_ID} as the site for a particular request,
* no site-specific jar file will be searched and the default version of
* the resource will assumed to have been provided by the webapp itself
* and be available via the servlet context.
*/
public class SiteResourceLoader
{
@@ -66,37 +57,20 @@ public class SiteResourceLoader
*
* @param siteIdent the site identifier to be used to identify which
* site through which a request was made when loading resources.
* @param context the servlet context from which site-agnostic
* resources will be loaded and from which configuration information
* will be obtained.
* @param siteJarPath the path to the site-specific jar files.
*/
public SiteResourceLoader (
SiteIdentifier siteIdent, ServletContext context)
SiteIdentifier siteIdent, String siteJarPath)
{
// keep this stuff around
_siteIdent = siteIdent;
_context = context;
// obtain the path to the site-specific jar files
_jarPath = context.getInitParameter(SITE_JAR_PATH);
if (_jarPath == null) {
// use the default
_jarPath = DEFAULT_SITE_JAR_PATH;
// and complain about it
Log.warning("Site resource loader not configured with a " +
"site-specific jar path. Will use default " +
"[path=" + _jarPath + "], but you should provide " +
"a proper value via a servlet context init " +
"parameter named '" + SITE_JAR_PATH + "' to " +
"quiet this warning message.");
}
_jarPath = siteJarPath;
}
/**
* Loads the specific resource, from the site-specific jar file if one
* exists and contains the specified resource, or via the servlet
* context. If no resource exists with that path in either location,
* null will be returned.
* exists and contains the specified resource. If no resource exists
* with that path, null will be returned.
*
* @param req the http request for which we are loading a resource
* (this will be used to determine for which site the resource will be
@@ -118,9 +92,8 @@ public class SiteResourceLoader
/**
* Loads the specific resource, from the site-specific jar file if one
* exists and contains the specified resource, or via the servlet
* context. If no resource exists with that path in either location,
* null will be returned.
* exists and contains the specified resource. If no resource exists
* with that path, null will be returned.
*
* @param siteId the unique identifer for the site for which we are
* loading the resource.
@@ -135,51 +108,22 @@ public class SiteResourceLoader
public InputStream getResourceAsStream (int siteId, String path)
throws IOException
{
return getResourceAsStream(siteId, path, true);
}
// Log.info("Loading site resource [siteId=" + siteId +
// ", path=" + path + "].");
/**
* Loads the specific resource, from the site-specific jar file if one
* exists and contains the specified resource, or via the servlet
* context (if <code>fallbackToServletContext</code> is true). If no
* resource exists with that path in either location, null will be
* returned.
*
* @param siteId the unique identifer for the site for which we are
* loading the resource.
* @param path the path to the desired resource.
* @param fallbackToServletContext if true, the servlet context will
* be searched for the resource if there is no site-specific
* resource. If false, it will not.
*
* @return an input stream via which the resource can be read or null
* if no resource could be located with the specified path.
*
* @exception IOException thrown if an I/O error occurs while loading
* a resource.
*/
public InputStream getResourceAsStream (int siteId, String path,
boolean fallbackToServletContext)
throws IOException
{
InputStream stream = null;
// synchronize on the lock to ensure that only one thread per site
// is concurrently executing
synchronized (getLock(siteId)) {
SiteResourceBundle bundle = getBundle(siteId);
// if we identified a non-default site, we first look for a
// site-specific resource
if (siteId != SiteIdentifier.DEFAULT_SITE_ID) {
// and fetch the site specific resource
stream = getSiteResourceAsStream(siteId, path);
// make sure the path has no leading slash
if (path.startsWith("/")) {
path = path.substring(1);
}
// obtain our resource from the bundle
return bundle.getResourceAsStream(path);
}
// if we didn't find a site-specific resource (or didn't look for
// one because we're loading for the default site), we need to
// attempt to load the resource from the servlet context
if (stream == null && fallbackToServletContext) {
stream = _context.getResourceAsStream(path);
}
// that's all she wrote
return stream;
}
/**
@@ -200,27 +144,32 @@ public class SiteResourceLoader
}
/**
* Fetches the resource with the specified path from the site-specific
* jar file associated with the specified site.
* Returns a class loader that loads resources from the site-specific
* jar file for the specified site. If no site-specific jar file
* exists for the specified site, null will be returned.
*/
protected InputStream getSiteResourceAsStream (int siteId, String path)
public ClassLoader getSiteClassLoader (int siteId)
throws IOException
{
// Log.info("Loading site resource [siteId=" + siteId +
// ", path=" + path + "].");
// synchronize on the lock to ensure that only one thread per site
// is concurrently executing
synchronized (getLock(siteId)) {
SiteResourceBundle bundle = getBundle(siteId);
// see if we've already got one
ClassLoader loader = (ClassLoader)_loaders.get(siteId);
// make sure the path has no leading slash
if (path.startsWith("/")) {
path = path.substring(1);
// create one if we've not
if (loader == null) {
SiteResourceBundle bundle = getBundle(siteId);
if (bundle == null) {
// no bundle... no classloader.
return null;
}
loader = new JarFileClassLoader(bundle.jarFile);
_loaders.put(siteId, loader);
}
// obtain our resource from the bundle
return bundle.getResourceAsStream(path);
return loader;
}
}
@@ -313,7 +262,7 @@ public class SiteResourceLoader
// now load up the resource
JarEntry entry = jarFile.getJarEntry(path);
return entry == null ? null : jarFile.getInputStream(entry);
return (entry == null) ? null : jarFile.getInputStream(entry);
}
/**
@@ -353,8 +302,7 @@ public class SiteResourceLoader
jarFile.close();
}
// Log.info("Opening site-specific jar file " +
// "[path=" + file + "].");
Log.info("Opened site bundle [path=" + file.getPath() + "].");
// and open a new one
jarFile = new JarFile(file);
@@ -366,12 +314,34 @@ public class SiteResourceLoader
protected long _lastModified;
}
protected static class JarFileClassLoader extends ClassLoader
{
public JarFileClassLoader (JarFile jarFile)
{
_jarFile = jarFile;
}
public InputStream getResourceAsStream (String path)
{
// Log.info("Seeking resource [jarFile=" + _jarFile +
// ", path=" + path + "].");
try {
JarEntry entry = _jarFile.getJarEntry(path);
return (entry == null) ? null :
_jarFile.getInputStream(entry);
} catch (IOException ioe) {
Log.warning("Error loading resource from jarfile " +
"[jar=" + _jarFile + ", error=" + ioe + "].");
return null;
}
}
protected JarFile _jarFile;
}
/** The site identifier we use to identify requests. */
protected SiteIdentifier _siteIdent;
/** The servlet context via which we load resources. */
protected ServletContext _context;
/** The path to our site-specific jar files. */
protected String _jarPath;
@@ -381,9 +351,8 @@ public class SiteResourceLoader
/** The table of site-specific jar file information. */
protected HashIntMap _bundles = new HashIntMap();
/** The servlet context init parameter name that is used to load our
* site-specific jar path configuration parameter. */
protected static final String SITE_JAR_PATH = "siteJarPath";
/** The table of site-specific class loaders. */
protected HashIntMap _loaders = new HashIntMap();
/** The default path to the site-specific jar files. This won't be
* used without logging a complaint first. */
@@ -1,5 +1,5 @@
//
// $Id: Application.java,v 1.5 2001/11/06 04:49:32 mdb Exp $
// $Id: Application.java,v 1.6 2001/11/06 20:16:47 mdb Exp $
//
// samskivert library - useful routines for java programs
// Copyright (C) 2001 Michael Bayne
@@ -20,11 +20,14 @@
package com.samskivert.velocity;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import com.samskivert.Log;
import com.samskivert.servlet.IndiscriminateSiteIdentifier;
import com.samskivert.servlet.MessageManager;
import com.samskivert.servlet.SiteIdentifier;
import com.samskivert.servlet.SiteResourceLoader;
import com.samskivert.util.StringUtil;
/**
@@ -47,18 +50,21 @@ public class Application
* application to entities that might turn around and request a
* reference to our site identifier).
*
* @param config the servlet config from which the application will
* load configuration information.
* @param context the servlet context in which this application is
* operating.
* @param logicPkg the base package for all of the logic
* implementations for this application.
*/
public void init (ServletContext context, String logicPkg)
public void init (ServletConfig config, ServletContext context,
String logicPkg)
{
// keep this around for later
_context = context;
// let the derived application do pre-init stuff
willInit();
willInit(config);
// remove any trailing dot
if (logicPkg.endsWith(".")) {
@@ -67,17 +73,48 @@ public class Application
_logicPkg = logicPkg;
}
// instantiate our message manager if the application wants one
String bpath = getMessageBundlePath();
if (bpath != null) {
_msgmgr = new MessageManager(bpath);
}
// create our site identifier
_siteIdent = createSiteIdentifier(_context);
// create a site resource loader if the user set up the
// site-specific jar file path
String siteJarPath = config.getInitParameter(SITE_JAR_PATH_KEY);
if (!StringUtil.blank(siteJarPath)) {
Log.info("Creating site resource loader " +
"[siteJarPath=" + siteJarPath + "].");
_siteLoader = new SiteResourceLoader(_siteIdent, siteJarPath);
} else {
Log.info("No site resource loader");
}
// instantiate our message manager if the application wants one
String bundlePath = config.getInitParameter(MESSAGE_BUNDLE_PATH_KEY);
if (!StringUtil.blank(bundlePath)) {
Log.info("Creating message manager " +
"[bundlePath=" + bundlePath + "].");
_msgmgr = new MessageManager(bundlePath);
}
// if we have a site-specific resource loader, configure the
// message manager with it, so that it can load site-specific
// message resources
if (_msgmgr != null && _siteLoader != null) {
String siteBundlePath =
config.getInitParameter(SITE_MESSAGE_BUNDLE_PATH_KEY);
if (!StringUtil.blank(siteBundlePath)) {
_msgmgr.activateSiteSpecificMessages(
siteBundlePath, _siteLoader, _siteIdent);
} else {
Log.info("No '" + SITE_MESSAGE_BUNDLE_PATH_KEY + "' " +
"specified in servlet configuration. This is " +
"required to allow the message manager to load " +
"site-specific translation resources.");
}
}
// let the derived application do post-init stuff
didInit();
didInit(config);
}
/**
@@ -85,7 +122,7 @@ public class Application
* invoke any necessary pre-initialization code. They should be sure
* to call <code>super.willInit()</code>.
*/
protected void willInit ()
protected void willInit (ServletConfig config)
{
}
@@ -94,7 +131,7 @@ public class Application
* invoke any necessary post-initialization code. They should be sure
* to call <code>super.didInit()</code>.
*/
protected void didInit ()
protected void didInit (ServletConfig config)
{
}
@@ -134,16 +171,15 @@ public class Application
}
/**
* If an application wishes to make use of the translation facilities
* provided by the message manager, it need only provide the path to
* its message resource bundle via this member function. Using a
* message manager allows framework components like the
* <code>MsgTool</code> to make use of the application's message
* bundles.
* Returns a reference to the loader used to obtain site-specific
* resources. This is only valid if the user specified the
* site-specific jar file path in the servlet configuration.
*
* @see #SITE_JAR_PATH_KEY
*/
protected String getMessageBundlePath ()
public SiteResourceLoader getSiteResourceLoader ()
{
return null;
return _siteLoader;
}
/**
@@ -237,4 +273,20 @@ public class Application
/** A reference to our site identifier. */
protected SiteIdentifier _siteIdent;
/** Provides access to site-specific resources. */
protected SiteResourceLoader _siteLoader;
/** The servlet parameter key specifying the path to the application's
* translated message resources. */
protected static final String MESSAGE_BUNDLE_PATH_KEY = "messages_path";
/** The servlet parameter key specifying the path to the site-specific
* jar files. */
protected static final String SITE_JAR_PATH_KEY = "site_jar_path";
/** The servlet parameter key specifying the path to the site-specific
* translated message resources. */
protected static final String SITE_MESSAGE_BUNDLE_PATH_KEY =
"site_messages_path";
}
@@ -1,5 +1,5 @@
//
// $Id: DispatcherServlet.java,v 1.9 2001/11/06 04:49:32 mdb Exp $
// $Id: DispatcherServlet.java,v 1.10 2001/11/06 20:16:47 mdb Exp $
//
// samskivert library - useful routines for java programs
// Copyright (C) 2001 Michael Bayne
@@ -43,6 +43,7 @@ import com.samskivert.Log;
import com.samskivert.servlet.MessageManager;
import com.samskivert.servlet.RedirectException;
import com.samskivert.servlet.SiteIdentifier;
import com.samskivert.servlet.SiteResourceLoader;
import com.samskivert.servlet.util.ExceptionMap;
import com.samskivert.servlet.util.FriendlyException;
@@ -153,14 +154,6 @@ public class DispatcherServlet extends VelocityServlet
* We load our velocity properties from the classpath rather than from
* a file.
*/
protected Properties loadConfiguration (ServletConfig config)
throws IOException
{
String propsPath = config.getInitParameter(INIT_PROPS_KEY);
// config util loads properties files from the classpath
return ConfigUtil.loadProperties(propsPath);
}
/**
* Initialize ourselves and our application.
*/
@@ -169,9 +162,9 @@ public class DispatcherServlet extends VelocityServlet
{
// load up our application configuration
try {
String appcl = config.getInitParameter(APP_CLASS_PROPS_KEY);
String appcl = config.getInitParameter(APP_CLASS_KEY);
Log.info("Creating application [class=" + appcl + "].");
if (appcl == null) {
if (StringUtil.blank(appcl)) {
_app = new Application();
} else {
Class appclass = Class.forName(appcl);
@@ -179,11 +172,9 @@ public class DispatcherServlet extends VelocityServlet
}
// now initialize the applicaiton
String logicPkg = config.getInitParameter(LOGIC_PKG_PROPS_KEY);
if (StringUtil.blank(logicPkg)) {
logicPkg = "";
}
_app.init(getServletContext(), logicPkg);
String logicPkg = config.getInitParameter(LOGIC_PKG_KEY);
_app.init(config, getServletContext(),
StringUtil.blank(logicPkg) ? "" : logicPkg);
} catch (Throwable t) {
Log.warning("Error instantiating application.");
@@ -197,6 +188,29 @@ public class DispatcherServlet extends VelocityServlet
super.initVelocity(config);
}
protected Properties loadConfiguration (ServletConfig config)
throws IOException
{
String propsPath = config.getInitParameter(INIT_PROPS_KEY);
// config util loads properties files from the classpath
Properties props = ConfigUtil.loadProperties(propsPath);
// wire up our site resource manager if a site-specific jar file
// path was provided
SiteResourceLoader siteLoader = _app.getSiteResourceLoader();
if (siteLoader != null) {
Log.info("Wiring up site resource manager.");
props.put(RuntimeSingleton.RESOURCE_MANAGER_CLASS,
SiteResourceManager.class.getName());
}
// wire up our #import directive
props.put("userdirective", ImportDirective.class.getName());
// now return our augmented properties
return props;
}
/**
* Clean up after ourselves and our application.
*/
@@ -394,8 +408,8 @@ public class DispatcherServlet extends VelocityServlet
protected static final String FORMTOOL_KEY = "form";
/** The servlet parameter key specifying the application class. */
protected static final String APP_CLASS_PROPS_KEY = "app_class";
protected static final String APP_CLASS_KEY = "app_class";
/** The servlet parameter key specifying the base logic package. */
protected static final String LOGIC_PKG_PROPS_KEY = "logic_package";
protected static final String LOGIC_PKG_KEY = "logic_package";
}
@@ -1,5 +1,5 @@
//
// $Id: SiteResourceManager.java,v 1.3 2001/11/06 05:37:57 mdb Exp $
// $Id: SiteResourceManager.java,v 1.4 2001/11/06 20:16:47 mdb Exp $
//
// samskivert library - useful routines for java programs
// Copyright (C) 2001 Michael Bayne
@@ -32,14 +32,17 @@ import org.apache.velocity.runtime.resource.loader.ResourceLoader;
import com.samskivert.Log;
import com.samskivert.servlet.SiteIdentifier;
import com.samskivert.servlet.SiteResourceLoader;
import com.samskivert.util.StringUtil;
/**
* A resource manager implementation for Velocity that first loads site
* specific resources (via the {@link SiteResourceLoader}), but falls back
* to default resources if no site-specific resource loader is available.
* specific resources (via the {@link SiteJarResourceLoader}), but falls
* back to default resources if no site-specific resource loader is
* available.
*
* <p> If this resource manager is to be used, resources must be fetched
* using {@likn SiteResourceKey} objects as keys rather than simple
* using {@link SiteResourceKey} objects as keys rather than simple
* strings.
*/
public class SiteResourceManager extends ResourceManagerImpl
@@ -48,6 +51,7 @@ public class SiteResourceManager extends ResourceManagerImpl
throws Exception
{
super.initialize(rsvc);
rsvc.info("SiteResourceManager initializing.");
// the web framework was kind enough to slip this into the runtime
// instance when it started up
@@ -64,8 +68,16 @@ public class SiteResourceManager extends ResourceManagerImpl
_sctx = app.getServletContext();
_ident = app.getSiteIdentifier();
// make sure the app has a site resource loader
SiteResourceLoader loader = app.getSiteResourceLoader();
if (loader == null) {
rsvc.warn("SiteResourceManager: application must be " +
"configured with a site-specific resource loader " +
"that we can use to fetch site-specific resources.");
}
// create our resource loaders
_siteLoader = new SiteResourceLoader(_ident, _sctx);
_siteLoader = new SiteJarResourceLoader(loader);
_contextLoader = new ServletContextResourceLoader(_sctx);
// for now, turn caching on with the expectation that new
@@ -73,6 +85,8 @@ public class SiteResourceManager extends ResourceManagerImpl
// being reloaded and clearing out the cache
_siteLoader.setCachingOn(true);
_contextLoader.setCachingOn(true);
rsvc.info("SiteResourceManager initialization complete.");
}
protected Resource loadResource(
@@ -132,7 +146,7 @@ public class SiteResourceManager extends ResourceManagerImpl
protected SiteIdentifier _ident;
/** We use this to load site-specific resources. */
protected SiteResourceLoader _siteLoader;
protected SiteJarResourceLoader _siteLoader;
/** We use this to load default resources. */
protected ServletContextResourceLoader _contextLoader;