Widened, made it possible to create a custom MessageManager.

git-svn-id: https://samskivert.googlecode.com/svn/trunk@2022 6335cc39-0255-0410-8fd6-9bcaacd3b74c
This commit is contained in:
mdb
2006-12-22 00:52:27 +00:00
parent 44452a0431
commit 48817344cc
+90 -145
View File
@@ -41,58 +41,50 @@ import com.samskivert.servlet.util.RequestUtils;
import com.samskivert.util.StringUtil; import com.samskivert.util.StringUtil;
/** /**
* The servlet API defines the concept of a web application and associates * The servlet API defines the concept of a web application and associates certain attributes with
* certain attributes with it like document root and so on. This * it like document root and so on. This application class extends that concept by providing a base
* application class extends that concept by providing a base class that * class that represents the web application. The application class is responsible for initializing
* represents the web application. The application class is responsible * services that will be used by the application's logic objects as well as cleaning them up when
* for initializing services that will be used by the application's logic * the application is shut down.
* objects as well as cleaning them up when the application is shut down.
* *
* <p><b>Error handling</b><br> * <p><b>Error handling</b><br>
* The application provides a common error handling mechanism. The design is to * The application provides a common error handling mechanism. The design is to catch any
* catch any exceptions thrown by the logic and to convert them into friendly * exceptions thrown by the logic and to convert them into friendly error messages that are
* error messages that are inserted into the invocation context with the key * inserted into the invocation context with the key <code>"error"</code> for easy display in the
* <code>"error"</code> for easy display in the resulting web page. * resulting web page.
* *
* <p> The default process of mapping exceptions to friendly error messages is * <p> The default process of mapping exceptions to friendly error messages is done using the
* done using the {@link ExceptionMap} class. This can be replaced by * {@link ExceptionMap} class. This can be replaced by overriding {@link #handleException}.
* overriding {@link #handleException}.
*/ */
public class Application public class Application
{ {
/** /**
* An initialized application automatically registers itself as a * An initialized application automatically registers itself as a Velocity application
* Velocity application attribute so that it can be retrieved by * attribute so that it can be retrieved by Velocity plugins using
* Velocity plugins using
* <code>getApplicationAttribute(VELOCITY_ATTR_KEY)</code>. * <code>getApplicationAttribute(VELOCITY_ATTR_KEY)</code>.
*/ */
public static final String VELOCITY_ATTR_KEY = "!application!"; public static final String VELOCITY_ATTR_KEY = "!application!";
/** /**
* Performs initializations common to all applications. Applications * Performs initializations common to all applications. Applications should override {@link
* should override {@link #willInit} to perform initializations that * #willInit} to perform initializations that need to take place before the common
* need to take place before the common initialization (which includes * initialization (which includes the creation of the site identifier and message manager) and
* the creation of the site identifier and message manager) and should * should override {@link #didInit} to perform initializations that need to take place after
* override {@link #didInit} to perform initializations that need to * the common initialization (like passing the application to entities that might turn around
* take place after the common initialization (like passing the * and request a reference to our site identifier).
* 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 * @param config the servlet config from which the application will load configuration
* load configuration information. * information.
* @param context the servlet context in which this application is * @param context the servlet context in which this application is operating.
* operating. * @param logicPkg the base package for all of the logic implementations for this application.
* @param logicPkg the base package for all of the logic
* implementations for this application.
*/ */
public void init (ServletConfig config, ServletContext context, public void init (ServletConfig config, ServletContext context, String logicPkg)
String logicPkg)
{ {
// keep this around for later // keep this around for later
_context = context; _context = context;
// stick ourselves into an application attribute so that we can be // stick ourselves into an application attribute so that we can be accessed by Velocity
// accessed by Velocity plugins // plugins
Velocity.setApplicationAttribute(VELOCITY_ATTR_KEY, this); Velocity.setApplicationAttribute(VELOCITY_ATTR_KEY, this);
// let the derived application do pre-init stuff // let the derived application do pre-init stuff
@@ -108,8 +100,7 @@ public class Application
// create our site identifier // create our site identifier
_siteIdent = createSiteIdentifier(_context); _siteIdent = createSiteIdentifier(_context);
// create a site resource loader if the user set up the // create a site resource loader if the user set up the site-specific jar file path
// site-specific jar file path
String siteJarPath = getInitParameter(config, SITE_JAR_PATH_KEY); String siteJarPath = getInitParameter(config, SITE_JAR_PATH_KEY);
if (!StringUtil.isBlank(siteJarPath)) { if (!StringUtil.isBlank(siteJarPath)) {
_siteLoader = new SiteResourceLoader(_siteIdent, siteJarPath); _siteLoader = new SiteResourceLoader(_siteIdent, siteJarPath);
@@ -118,23 +109,19 @@ public class Application
// instantiate our message manager if the application wants one // instantiate our message manager if the application wants one
String bundlePath = getInitParameter(config, MESSAGE_BUNDLE_PATH_KEY); String bundlePath = getInitParameter(config, MESSAGE_BUNDLE_PATH_KEY);
if (!StringUtil.isBlank(bundlePath)) { if (!StringUtil.isBlank(bundlePath)) {
_msgmgr = new MessageManager(bundlePath, null, _siteIdent); _msgmgr = createMessageManager(bundlePath);
} }
// if we have a site-specific resource loader, configure the // if we have a site-specific resource loader, configure the message manager with it, so
// message manager with it, so that it can load site-specific // that it can load site-specific message resources
// message resources
if (_msgmgr != null && _siteLoader != null) { if (_msgmgr != null && _siteLoader != null) {
String siteBundlePath = getInitParameter( String siteBundlePath = getInitParameter(config, SITE_MESSAGE_BUNDLE_PATH_KEY);
config, SITE_MESSAGE_BUNDLE_PATH_KEY);
if (!StringUtil.isBlank(siteBundlePath)) { if (!StringUtil.isBlank(siteBundlePath)) {
_msgmgr.activateSiteSpecificMessages( _msgmgr.activateSiteSpecificMessages(siteBundlePath, _siteLoader);
siteBundlePath, _siteLoader);
} else { } else {
Log.info("No '" + SITE_MESSAGE_BUNDLE_PATH_KEY + "' " + Log.info("No '" + SITE_MESSAGE_BUNDLE_PATH_KEY + "' specified in servlet " +
"specified in servlet configuration. This is " + "configuration. This is required to allow the message manager to load " +
"required to allow the message manager to load " +
"site-specific translation resources."); "site-specific translation resources.");
} }
} }
@@ -144,18 +131,17 @@ public class Application
} }
/** /**
* Called prior to initializing Velocity to allow the application to * Called prior to initializing Velocity to allow the application to specify custom
* specify custom configuration properties. * configuration properties.
*/ */
protected void configureVelocity (ServletConfig config, Properties props) protected void configureVelocity (ServletConfig config, Properties props)
{ {
} }
/** /**
* Looks up an initialization parameter for this application. The * Looks up an initialization parameter for this application. The default implementation
* default implementation retrieves the value from the servlet config, * retrieves the value from the servlet config, but derived classes may wish to get certain
* but derived classes may wish to get certain parameters from some * parameters from some other configuration source.
* other configuration source.
*/ */
protected String getInitParameter (ServletConfig config, String key) protected String getInitParameter (ServletConfig config, String key)
{ {
@@ -163,38 +149,42 @@ public class Application
} }
/** /**
* This should be overridden by the application implementation to * Creates the message manager to be used for this application.
* invoke any necessary pre-initialization code. They should be sure */
* to call <code>super.willInit()</code>. protected MessageManager createMessageManager (String bundlePath)
{
return new MessageManager(bundlePath, null, _siteIdent);
}
/**
* This should be overridden by the application implementation to invoke any necessary
* pre-initialization code. They should be sure to call <code>super.willInit()</code>.
*/ */
protected void willInit (ServletConfig config) protected void willInit (ServletConfig config)
{ {
} }
/** /**
* This should be overridden by the application implementation to * This should be overridden by the application implementation to invoke any necessary
* invoke any necessary post-initialization code. They should be sure * post-initialization code. They should be sure to call <code>super.didInit()</code>.
* to call <code>super.didInit()</code>.
*/ */
protected void didInit (ServletConfig config) protected void didInit (ServletConfig config)
{ {
} }
/** /**
* Allows derived aplication classes to prepare an invocation context * Allows derived aplication classes to prepare an invocation context prior to the logic class
* prior to the logic class being invoked. They may wish to add * being invoked. They may wish to add standard tools to the context or do any other
* standard tools to the context or do any other request-invariant * request-invariant preparation.
* preparation.
*/ */
protected void prepareContext (InvocationContext ctx) protected void prepareContext (InvocationContext ctx)
{ {
} }
/** /**
* Allows derived application classes to check access in a single location * Allows derived application classes to check access in a single location prior to resolving
* prior to resolving and dispatching a logic class, if they desire access * and dispatching a logic class, if they desire access control at this level. Alternatively,
* control at this level. Alternatively, access control can be performed by * access control can be performed by the logic instance.
* the logic instance.
*/ */
protected void checkAccess (InvocationContext ctx) protected void checkAccess (InvocationContext ctx)
throws RedirectException, HttpErrorException throws RedirectException, HttpErrorException
@@ -202,10 +192,9 @@ public class Application
} }
/** /**
* If an exception propagates up from {@link Logic#invoke}, the application * If an exception propagates up from {@link Logic#invoke}, the application is given the chance
* is given the chance to convert a low-level exception into a {@link * to convert a low-level exception into a {@link FriendlyException} or a {@link
* FriendlyException} or a {@link RedirectException} which will be handled * RedirectException} which will be handled in the normal way.
* in the normal way.
*/ */
protected Exception translateException (Exception error) protected Exception translateException (Exception error)
{ {
@@ -213,18 +202,15 @@ public class Application
} }
/** /**
* If a generic exception propagates up from {@link Logic#invoke} and is * If a generic exception propagates up from {@link Logic#invoke} and is not otherwise
* not otherwise converted into a friendly or redirect exception, the * converted into a friendly or redirect exception, the application will be required to provide
* application will be required to provide a generic error message to be * a generic error message to be inserted into the context and should take this opportunity to
* inserted into the context and should take this opportunity to log the * log the exception.
* exception.
* *
* <p><em>Note:</em> the string returned by this method will be translated * <p><em>Note:</em> the string returned by this method will be translated using the
* using the application's message manager before being inserted into the * application's message manager before being inserted into the Velocity context.
* Velocity context.
*/ */
protected String handleException ( protected String handleException (HttpServletRequest req, Logic logic, Exception error)
HttpServletRequest req, Logic logic, Exception error)
{ {
Log.warning(logic + " failed on: " + RequestUtils.reconstructURL(req)); Log.warning(logic + " failed on: " + RequestUtils.reconstructURL(req));
Log.logStackTrace(error); Log.logStackTrace(error);
@@ -232,16 +218,15 @@ public class Application
} }
/** /**
* This should be overridden by the application implementation to * This should be overridden by the application implementation to perform any necessary
* perform any necessary cleanup. * cleanup.
*/ */
public void shutdown () public void shutdown ()
{ {
} }
/** /**
* Returns a reference to the servlet context in which this * Returns a reference to the servlet context in which this application is operating.
* application is operating.
*/ */
public ServletContext getServletContext () public ServletContext getServletContext ()
{ {
@@ -249,8 +234,7 @@ public class Application
} }
/** /**
* Returns the message manager in effect for this application, if one * Returns the message manager in effect for this application, if one is in effect.
* is in effect.
*/ */
public MessageManager getMessageManager () public MessageManager getMessageManager ()
{ {
@@ -258,8 +242,8 @@ public class Application
} }
/** /**
* Returns the site identifier in effect for figuring out which site * Returns the site identifier in effect for figuring out which site through which a user is
* through which a user is making a request. * making a request.
*/ */
public SiteIdentifier getSiteIdentifier () public SiteIdentifier getSiteIdentifier ()
{ {
@@ -267,9 +251,8 @@ public class Application
} }
/** /**
* Returns a reference to the loader used to obtain site-specific * Returns a reference to the loader used to obtain site-specific resources. This is only valid
* resources. This is only valid if the user specified the * if the user specified the site-specific jar file path in the servlet configuration.
* site-specific jar file path in the servlet configuration.
* *
* @see #SITE_JAR_PATH_KEY * @see #SITE_JAR_PATH_KEY
*/ */
@@ -279,12 +262,10 @@ public class Application
} }
/** /**
* Called to instantiate the site identifier that we'd like to use in * Called to instantiate the site identifier that we'd like to use in this application. This
* this application. This will be an instance of {@link * will be an instance of {@link IndiscriminateSiteIdentifier} unless the derived application
* IndiscriminateSiteIdentifier} unless the derived application class * class overrides this method and creates something more to its liking. This will be called
* overrides this method and creates something more to its liking. * after the application's {@link #init} method has been called.
* This will be called after the application's {@link #init} method
* has been called.
*/ */
protected SiteIdentifier createSiteIdentifier (ServletContext ctx) protected SiteIdentifier createSiteIdentifier (ServletContext ctx)
{ {
@@ -302,46 +283,14 @@ public class Application
/** /**
* A convenience function for translating messages. * A convenience function for translating messages.
*/ */
public final String translate (InvocationContext ctx, String msg, public final String translate (InvocationContext ctx, String msg, Object... args)
Object arg)
{
return _msgmgr.getMessage(ctx.getRequest(), msg,
new Object[]{ arg });
}
/**
* A convenience function for translating messages.
*/
public final String translate (InvocationContext ctx, String msg,
Object arg1, Object arg2)
{
return _msgmgr.getMessage(ctx.getRequest(), msg,
new Object[]{ arg1, arg2 });
}
/**
* A convenience function for translating messages.
*/
public final String translate (InvocationContext ctx, String msg,
Object arg1, Object arg2, Object arg3)
{
return _msgmgr.getMessage(ctx.getRequest(), msg,
new Object[]{ arg1, arg2, arg3 });
}
/**
* A convenience function for translating messages.
*/
public final String translate (InvocationContext ctx, String msg,
Object[] args)
{ {
return _msgmgr.getMessage(ctx.getRequest(), msg, args); return _msgmgr.getMessage(ctx.getRequest(), msg, args);
} }
/** /**
* Given the servlet path (the part of the URI after the context path) * Given the servlet path (the part of the URI after the context path) this generates the
* this generates the classname of the logic class that should handle * classname of the logic class that should handle the request.
* the request.
*/ */
protected String generateClass (String path) protected String generateClass (String path)
{ {
@@ -356,12 +305,10 @@ public class Application
return _logicPkg + path; return _logicPkg + path;
} }
/** A reference to the servlet context in which this application is /** A reference to the servlet context in which this application is operating. */
* operating. */
protected ServletContext _context; protected ServletContext _context;
/** The prefix that we use to generate fully qualified logic class /** The prefix that we use to generate fully qualified logic class names. */
* names. */
protected String _logicPkg; protected String _logicPkg;
/** A reference to our message manager or null if we have none. */ /** A reference to our message manager or null if we have none. */
@@ -373,16 +320,14 @@ public class Application
/** Provides access to site-specific resources. */ /** Provides access to site-specific resources. */
protected SiteResourceLoader _siteLoader; protected SiteResourceLoader _siteLoader;
/** The servlet parameter key specifying the path to the application's /** The servlet parameter key specifying the path to the application's translated message
* translated message resources. */ * resources. */
protected static final String MESSAGE_BUNDLE_PATH_KEY = "messages_path"; protected static final String MESSAGE_BUNDLE_PATH_KEY = "messages_path";
/** The servlet parameter key specifying the path to the site-specific /** The servlet parameter key specifying the path to the site-specific jar files. */
* jar files. */
protected static final String SITE_JAR_PATH_KEY = "site_jar_path"; protected static final String SITE_JAR_PATH_KEY = "site_jar_path";
/** The servlet parameter key specifying the path to the site-specific /** The servlet parameter key specifying the path to the site-specific translated message
* translated message resources. */ * resources. */
protected static final String SITE_MESSAGE_BUNDLE_PATH_KEY = protected static final String SITE_MESSAGE_BUNDLE_PATH_KEY = "site_messages_path";
"site_messages_path";
} }