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;