From 383632dd53547a9a3f34f4b91b19e7b447923f04 Mon Sep 17 00:00:00 2001 From: mdb Date: Tue, 6 Nov 2001 20:16:47 +0000 Subject: [PATCH] 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 --- .../samskivert/servlet/MessageManager.java | 158 +++++++++++------ .../servlet/SiteResourceLoader.java | 167 +++++++----------- .../com/samskivert/velocity/Application.java | 92 +++++++--- .../velocity/DispatcherServlet.java | 50 ++++-- .../velocity/SiteResourceManager.java | 26 ++- 5 files changed, 300 insertions(+), 193 deletions(-) diff --git a/projects/samskivert/src/java/com/samskivert/servlet/MessageManager.java b/projects/samskivert/src/java/com/samskivert/servlet/MessageManager.java index 13f73652..3792a622 100644 --- a/projects/samskivert/src/java/com/samskivert/servlet/MessageManager.java +++ b/projects/samskivert/src/java/com/samskivert/servlet/MessageManager.java @@ -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 = diff --git a/projects/samskivert/src/java/com/samskivert/servlet/SiteResourceLoader.java b/projects/samskivert/src/java/com/samskivert/servlet/SiteResourceLoader.java index 0de12dfb..a49ad841 100644 --- a/projects/samskivert/src/java/com/samskivert/servlet/SiteResourceLoader.java +++ b/projects/samskivert/src/java/com/samskivert/servlet/SiteResourceLoader.java @@ -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. * *

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 samskivert as the site identifier for a particular * request, site-specific resources will be loaded from * /usr/share/java/webapps/site-data/samskivert.jar. - * - *

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 fallbackToServletContext 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. */ diff --git a/projects/samskivert/src/java/com/samskivert/velocity/Application.java b/projects/samskivert/src/java/com/samskivert/velocity/Application.java index aa21dd32..0a240400 100644 --- a/projects/samskivert/src/java/com/samskivert/velocity/Application.java +++ b/projects/samskivert/src/java/com/samskivert/velocity/Application.java @@ -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 super.willInit(). */ - 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 super.didInit(). */ - 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 - * MsgTool 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"; } diff --git a/projects/samskivert/src/java/com/samskivert/velocity/DispatcherServlet.java b/projects/samskivert/src/java/com/samskivert/velocity/DispatcherServlet.java index 26579f2b..96ccd2dd 100644 --- a/projects/samskivert/src/java/com/samskivert/velocity/DispatcherServlet.java +++ b/projects/samskivert/src/java/com/samskivert/velocity/DispatcherServlet.java @@ -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"; } diff --git a/projects/samskivert/src/java/com/samskivert/velocity/SiteResourceManager.java b/projects/samskivert/src/java/com/samskivert/velocity/SiteResourceManager.java index 7a981840..2a0c6bee 100644 --- a/projects/samskivert/src/java/com/samskivert/velocity/SiteResourceManager.java +++ b/projects/samskivert/src/java/com/samskivert/velocity/SiteResourceManager.java @@ -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. * *

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;