You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by Nacho <na...@siapi.es> on 2000/12/15 06:12:47 UTC
RE: cvs commit: jakarta-struts/src/share/org/apache/struts/util M
essageResourcesFactory.java PropertyMessageResources.java PropertyMessage
ResourcesFactory.java ServletContextWriter.java MessageResources.java
Thanks!!
Is good to see the King.... eres el mejor :-) que no el mas rapido :-(
I understand why you didnt commit my poor code :-)
Saludos ,
Ignacio J. Ortega
> -----Mensaje original-----
> De: craigmcc@locus.apache.org [mailto:craigmcc@locus.apache.org]
> Enviado el: viernes 15 de diciembre de 2000 4:08
> Para: jakarta-struts-cvs@apache.org
> Asunto: cvs commit: jakarta-struts/src/share/org/apache/struts/util
> MessageResourcesFactory.java PropertyMessageResources.java
> PropertyMessageResourcesFactory.java ServletContextWriter.java
> MessageResources.java
>
>
> craigmcc 00/12/14 19:08:12
>
> Modified: src/share/org/apache/struts/action ActionServlet.java
> src/share/org/apache/struts/util MessageResources.java
> Added: src/share/org/apache/struts/util
> MessageResourcesFactory.java
> PropertyMessageResources.java
> PropertyMessageResourcesFactory.java
> ServletContextWriter.java
> Log:
> Replace the previous implementation of MessageResources
> with a set of
> classes offering the following features:
>
> - The MessageResources instance is now Serializable, to make it work
> in application servers that require this even for
> application scope
> beans
>
> - The MessageResources implementation class (and the
> implementation class
> for the corresponding MessageResourcesFactory) are
> pluggable at run time
> so that you can provide your own MessageResources implementations.
>
> - The Struts controller servlet accepts a new "factory"
> initialization
> parameter to set the name of the MessageResourcesFactory
> class to use.
>
> - The default implementation reads resource property files from the
> web app class path, just as the previous version did.
>
> - No changes in existing classes are required if you always want the
> currently registered default implementation class.
>
> Revision Changes Path
> 1.42 +29 -6
> jakarta-struts/src/share/org/apache/struts/action/ActionServlet.java
>
> Index: ActionServlet.java
> ===================================================================
> RCS file:
> /home/cvs/jakarta-struts/src/share/org/apache/struts/action/Ac
> tionServlet.java,v
> retrieving revision 1.41
> retrieving revision 1.42
> diff -u -r1.41 -r1.42
> --- ActionServlet.java 2000/12/06 19:15:58 1.41
> +++ ActionServlet.java 2000/12/15 03:08:09 1.42
> @@ -1,7 +1,7 @@
> /*
> - * $Header:
> /home/cvs/jakarta-struts/src/share/org/apache/struts/action/Ac
> tionServlet.java,v 1.41 2000/12/06 19:15:58 craigmcc Exp $
> - * $Revision: 1.41 $
> - * $Date: 2000/12/06 19:15:58 $
> + * $Header:
> /home/cvs/jakarta-struts/src/share/org/apache/struts/action/Ac
> tionServlet.java,v 1.42 2000/12/15 03:08:09 craigmcc Exp $
> + * $Revision: 1.42 $
> + * $Date: 2000/12/15 03:08:09 $
> *
> *
> ====================================================================
> *
> @@ -85,6 +85,8 @@
> import org.apache.struts.util.BeanUtils;
> import org.apache.struts.util.GenericDataSource;
> import org.apache.struts.util.MessageResources;
> +import org.apache.struts.util.MessageResourcesFactory;
> +import org.apache.struts.util.ServletContextWriter;
> import org.xml.sax.SAXException;
>
>
> @@ -161,6 +163,9 @@
> * <li><strong>detail</strong> - The debugging detail
> level for the Digester
> * we utilize in <code>initMapping()</code>, which
> logs to System.out
> * instead of the servlet log. [0]</li>
> + * <li><strong>factory</strong> - The Java class name of the
> + * <code>MessageResourcesFactory</code> used to create
> the application
> + * <code>MessageResources</code> object.</li>
> * <li><strong>forward</strong> - The Java class name of
> the ActionForward
> * implementation to use
> [org.apache.struts.action.ActionForward].
> * Two convenient classes you may wish to use are:
> @@ -203,7 +208,7 @@
> * </ul>
> *
> * @author Craig R. McClanahan
> - * @version $Revision: 1.41 $ $Date: 2000/12/06 19:15:58 $
> + * @version $Revision: 1.42 $ $Date: 2000/12/15 03:08:09 $
> */
>
> public class ActionServlet
> @@ -259,6 +264,13 @@
>
>
> /**
> + * The Java class name of the
> <code>MessageResourcesFactory</code>
> + * class for the application message resources bundle.
> + */
> + protected String factoryClass = null;
> +
> +
> + /**
> * The Java class name of the ActionFormBean
> implementation class to use.
> */
> protected String formBeanClass =
> @@ -887,10 +899,21 @@
> String value =
> getServletConfig().getInitParameter("application");
> if (value == null)
> return;
> + String factory =
> + getServletConfig().getInitParameter("factory");
> if (debug >= 1)
> log(internal.getMessage("applicationLoading", value));
> try {
> - application = MessageResources.getMessageResources(value);
> + MessageResourcesFactory.setDefaultWriter
> + (new ServletContextWriter(getServletContext()));
> + String oldFactory =
> + MessageResourcesFactory.getFactoryClass();
> + if (factory != null)
> + MessageResourcesFactory.setFactoryClass(factory);
> + MessageResourcesFactory factoryObject =
> + MessageResourcesFactory.createFactory();
> + application = factoryObject.createResources(value);
> + MessageResourcesFactory.setFactoryClass(oldFactory);
> value = getServletConfig().getInitParameter("null");
> if (value == null)
> value = "true";
> @@ -899,7 +922,7 @@
> application.setReturnNull(true);
> else
> application.setReturnNull(false);
> - } catch (MissingResourceException e) {
> + } catch (Throwable e) {
> log(internal.getMessage("applicationResources", value), e);
> throw new UnavailableException
> (internal.getMessage("applicationResources", value));
>
>
>
> 1.5 +164 -213
> jakarta-struts/src/share/org/apache/struts/util/MessageResources.java
>
> Index: MessageResources.java
> ===================================================================
> RCS file:
> /home/cvs/jakarta-struts/src/share/org/apache/struts/util/Mess
> ageResources.java,v
> retrieving revision 1.4
> retrieving revision 1.5
> diff -u -r1.4 -r1.5
> --- MessageResources.java 2000/08/01 20:04:02 1.4
> +++ MessageResources.java 2000/12/15 03:08:10 1.5
> @@ -1,7 +1,7 @@
> /*
> - * $Header:
> /home/cvs/jakarta-struts/src/share/org/apache/struts/util/Mess
> ageResources.java,v 1.4 2000/08/01 20:04:02 craigmcc Exp $
> - * $Revision: 1.4 $
> - * $Date: 2000/08/01 20:04:02 $
> + * $Header:
> /home/cvs/jakarta-struts/src/share/org/apache/struts/util/Mess
> ageResources.java,v 1.5 2000/12/15 03:08:10 craigmcc Exp $
> + * $Revision: 1.5 $
> + * $Date: 2000/12/15 03:08:10 $
> *
> *
> ====================================================================
> *
> @@ -63,169 +63,130 @@
> package org.apache.struts.util;
>
>
> +import java.io.PrintWriter;
> +import java.io.Serializable;
> import java.text.MessageFormat;
> -import java.util.Enumeration;
> -import java.util.Hashtable;
> +import java.util.HashMap;
> import java.util.Locale;
> -import java.util.MissingResourceException;
> -import java.util.ResourceBundle;
>
>
> /**
> - * General purpose utility module that wraps the named
> resource bundle
> - * passed to our constructor and produces messages from
> it, with parametric
> - * replacement of MessageFormat parameters. Convenience
> methods allow
> - * retrieval of messages for either the default Locale or
> a specified Locale.
> + * General purpose abstract class that describes an API
> for retrieving
> + * Locale-sensitive messages from underlying resource
> locations of an
> + * unspecified design, and optionally utilizing the
> <code>MessageFormat</code>
> + * class to produce internationalized messages with
> parametric replacement.
> + * <p>
> + * Calls to <code>getMessage()</code> variants without a
> <code>Locale</code>
> + * argument are presumed to be requesting a message string
> in the default
> + * <code>Locale</code> for this JVM.
> + * <p>
> + * Calls to <code>getMessage()</code> with an unknown key,
> or an unknown
> + * <code>Locale</code> will return <code>null</code> if the
> + * <code>returnNull</code> property is set to
> <code>true</code>. Otherwise,
> + * a suitable error message will be returned instead.
> + * <p>
> + * <strong>IMPLEMENTATION NOTE</strong> - Classes that
> extend this class
> + * must be Serializable so that instances may be used in
> distributable
> + * application server environments.
> *
> * @author Craig R. McClanahan
> - * @version $Revision: 1.4 $ $Date: 2000/08/01 20:04:02 $
> + * @version $Revision: 1.5 $ $Date: 2000/12/15 03:08:10 $
> */
>
> -public final class MessageResources {
> +public abstract class MessageResources implements Serializable {
>
>
> - //
> -----------------------------------------------------------
> Constructors
> + //
> -------------------------------------------------------------
> Properties
>
>
> /**
> - * Construct a new resources object that wraps the
> named ResourceBundles.
> - *
> - * @param base Base name of the ResourceBundles to be wrapped
> - *
> - * @exception MissingResourceException if the
> specified bundle cannot
> - * be loaded
> + * The configuration parameter used to initialize this
> MessageResources.
> */
> - public MessageResources(String base) throws
> MissingResourceException {
> -
> - super();
> - this.base = base;
> - this.bundle = ResourceBundle.getBundle(base);
> + protected String config = null;
>
> + public String getConfig() {
> + return (this.config);
> }
>
>
> - //
> -----------------------------------------------------
> Instance Variables
> -
> -
> - /**
> - * The base name of resource bundles used for
> resolving requests for
> - * messages.
> - */
> - private String base = null;
> -
> -
> /**
> - * The resource bundle to be used for resolving
> requests for messages
> - * when no Locale is specified (i.e. the bundle that
> will be used for
> - * the default Locale).
> + * The default Locale for our environment.
> */
> - private ResourceBundle bundle = null;
> + protected Locale defaultLocale = Locale.getDefault();
>
>
> /**
> - * The set of resource bundles from which we access
> resources, keyed by
> - * the key computed in <code>getLocaleKey()</code>.
> + * The <code>MessageResourcesFactory</code> that
> created this instance.
> */
> - private Hashtable bundles = new Hashtable();
> + protected MessageResourcesFactory factory = null;
>
> -
> - /**
> - * The default Locale for our installation.
> - */
> - private static final Locale defaultLocale =
> Locale.getDefault();
> + public MessageResourcesFactory getFactory() {
> + return (this.factory);
> + }
>
>
> /**
> - * The set of previously created message format
> objects, keyed by
> - * the key computed in <code>getResourceKey()</code>.
> + * The set of previously created MessageFormat
> objects, keyed by the
> + * key computed in <code>messageKey()</code>.
> */
> - private Hashtable formats = new Hashtable();
> + private HashMap formats = new HashMap();
>
>
> /**
> - * Should we return <code>null</code> for message keys
> that are not
> - * found (instead of an error code that includes the
> offending key)?
> + * Should we return <code>null</code> instead of an
> error message string
> + * if an unknown Locale or key is requested?
> */
> - private boolean returnNull = true;
> -
> + protected boolean returnNull = false;
>
> - //
> -------------------------------------------------------------
> Properties
> -
> -
> - /**
> - * Return the "return null" property.
> - */
> public boolean getReturnNull() {
> -
> - return (this.returnNull);
> -
> + return (this.returnNull);
> }
>
> -
> - /**
> - * Set the "return null" property.
> - *
> - * @param returnNull The new "return null" property
> - */
> public void setReturnNull(boolean returnNull) {
> -
> - this.returnNull = returnNull;
> -
> + this.returnNull = returnNull;
> }
>
> -
> - //
> ---------------------------------------------------------
> Public Methods
>
> + //
> -----------------------------------------------------------
> Constructors
>
>
> /**
> - * Return the resource bundle that will be used to
> resolve message
> - * requests for the default Locale.
> + * Construct a new MessageResources according to the
> specified parameters.
> *
> - * @exception MissingResourceException if a suitable
> bundle cannot
> - * be located
> + * @param factory The MessageResourcesFactory that created us
> + * @param config The configuration parameter for this
> MessageResources
> */
> - public ResourceBundle getBundle() throws
> MissingResourceException {
> + public MessageResources(MessageResourcesFactory
> factory, String config) {
>
> - return (getBundle(null));
> + this(factory, config, false);
>
> }
>
>
> /**
> - * Return the resource bundle that will be used to
> resolve message
> - * requests for the specified Locale, if there is one.
> Otherwise,
> - * return <code>null</code>
> - *
> - * @param locale The locale used to select a resource bundle
> + * Construct a new MessageResources according to the
> specified parameters.
> *
> - * @exception MissingResourceException if a suitable
> bundle cannot
> - * be located
> + * @param factory The MessageResourcesFactory that created us
> + * @param config The configuration parameter for this
> MessageResources
> + * @param returnNull The returnNull property we should
> initialize with
> */
> - public ResourceBundle getBundle(Locale locale)
> - throws MissingResourceException {
> -
> - if (locale == null)
> - return (bundle);
> - String localeKey = getLocaleKey(locale);
> + public MessageResources(MessageResourcesFactory
> factory, String config,
> + boolean returnNull) {
>
> - ResourceBundle bundle = null;
> - synchronized (bundles) {
> - bundle = (ResourceBundle) bundles.get(localeKey);
> - if (bundle == null) {
> - bundle = ResourceBundle.getBundle(base, locale);
> - bundles.put(localeKey, bundle);
> - }
> - }
> - return (bundle);
> + super();
> + this.factory = factory;
> + this.config = config;
> + this.returnNull = returnNull;
>
> }
>
>
> + //
> ---------------------------------------------------------
> Public Methods
> +
> +
> +
> /**
> * Returns a text message for the specified key, for
> the default Locale.
> - * A null string result will be returned by this
> method if no relevant
> - * message resource is found.
> *
> * @param key The message key to look up
> */
> @@ -238,8 +199,7 @@
>
> /**
> * Returns a text message after parametric replacement
> of the specified
> - * parameter placeholders. A null string result will
> be returned by
> - * this method if no resource bundle has been configured.
> + * parameter placeholders.
> *
> * @param key The message key to look up
> * @param args An array of replacement parameters for
> placeholders
> @@ -253,13 +213,12 @@
>
> /**
> * Returns a text message after parametric replacement
> of the specified
> - * parameter placeholders. A null string result will
> never be returned
> - * by this method.
> + * parameter placeholders.
> *
> * @param key The message key to look up
> * @param arg0 The replacement for placeholder {0} in
> the message
> */
> - public String getMessage(String key, String arg0) {
> + public String getMessage(String key, Object arg0) {
>
> return (getMessage((Locale) null, key, arg0));
>
> @@ -268,14 +227,13 @@
>
> /**
> * Returns a text message after parametric replacement
> of the specified
> - * parameter placeholders. A null string result will
> never be returned
> - * by this method.
> + * parameter placeholders.
> *
> * @param key The message key to look up
> * @param arg0 The replacement for placeholder {0} in
> the message
> * @param arg1 The replacement for placeholder {1} in
> the message
> */
> - public String getMessage(String key, String arg0,
> String arg1) {
> + public String getMessage(String key, Object arg0,
> Object arg1) {
>
> return (getMessage((Locale) null, key, arg0, arg1));
>
> @@ -284,16 +242,15 @@
>
> /**
> * Returns a text message after parametric replacement
> of the specified
> - * parameter placeholders. A null string result will
> never be returned
> - * by this method.
> + * parameter placeholders.
> *
> * @param key The message key to look up
> * @param arg0 The replacement for placeholder {0} in
> the message
> * @param arg1 The replacement for placeholder {1} in
> the message
> * @param arg2 The replacement for placeholder {2} in
> the message
> */
> - public String getMessage(String key, String arg0, String arg1,
> - String arg2) {
> + public String getMessage(String key, Object arg0, Object arg1,
> + Object arg2) {
>
> return (getMessage((Locale) null, key, arg0, arg1, arg2));
>
> @@ -302,8 +259,7 @@
>
> /**
> * Returns a text message after parametric replacement
> of the specified
> - * parameter placeholders. A null string result will
> never be returned
> - * by this method.
> + * parameter placeholders.
> *
> * @param key The message key to look up
> * @param arg0 The replacement for placeholder {0} in
> the message
> @@ -311,8 +267,8 @@
> * @param arg2 The replacement for placeholder {2} in
> the message
> * @param arg3 The replacement for placeholder {3} in
> the message
> */
> - public String getMessage(String key, String arg0, String arg1,
> - String arg2, String arg3) {
> + public String getMessage(String key, Object arg0, Object arg1,
> + Object arg2, Object arg3) {
>
> return (getMessage((Locale) null, key, arg0, arg1, arg2, arg3));
>
> @@ -322,20 +278,19 @@
> /**
> * Returns a text message for the specified key, for
> the default Locale.
> * A null string result will be returned by this
> method if no relevant
> - * message resource is found.
> + * message resource is found for this key or Locale, if the
> + * <code>returnNull</code> property is set.
> Otherwise, an appropriate
> + * error message will be returned.
> + * <p>
> + * This method must be implemented by a concrete subclass.
> *
> * @param locale The requested message Locale, or
> <code>null</code>
> * for the system default Locale
> * @param key The message key to look up
> */
> - public String getMessage(Locale locale, String key) {
> + public abstract String getMessage(Locale locale, String key);
>
> - Object args[] = new Object[0];
> - return (getMessage(locale, key, args));
>
> - }
> -
> -
> /**
> * Returns a text message after parametric replacement
> of the specified
> * parameter placeholders. A null string result will
> be returned by
> @@ -349,20 +304,22 @@
> public String getMessage(Locale locale, String key,
> Object args[]) {
>
> // Cache MessageFormat instances as they are accessed
> + if (locale == null)
> + locale = defaultLocale;
> MessageFormat format = null;
> - String messageKey = getResourceKey(locale, key);
> + String formatKey = messageKey(locale, key);
> synchronized (formats) {
> - format = (MessageFormat) formats.get(messageKey);
> + format = (MessageFormat) formats.get(formatKey);
> if (format == null) {
> - String formatString = (String) getResource(locale, key);
> + String formatString = getMessage(locale, key);
> if (formatString == null) {
> if (returnNull)
> return (null);
> else
> - return ("???" + key + "???");
> + return ("???" + formatKey + "???");
> }
> format = new MessageFormat(formatString);
> - formats.put(messageKey, format);
> + formats.put(formatKey, format);
> }
>
> }
> @@ -381,7 +338,7 @@
> * @param key The message key to look up
> * @param arg0 The replacement for placeholder {0} in
> the message
> */
> - public String getMessage(Locale locale, String key,
> String arg0) {
> + public String getMessage(Locale locale, String key,
> Object arg0) {
>
> Object args[] = new Object[1];
> args[0] = arg0;
> @@ -402,7 +359,7 @@
> * @param arg1 The replacement for placeholder {1} in
> the message
> */
> public String getMessage(Locale locale,
> - String key, String arg0, String arg1) {
> + String key, Object arg0, Object arg1) {
>
> Object args[] = new Object[2];
> args[0] = arg0;
> @@ -425,8 +382,8 @@
> * @param arg2 The replacement for placeholder {2} in
> the message
> */
> public String getMessage(Locale locale,
> - String key, String arg0, String arg1,
> - String arg2) {
> + String key, Object arg0, Object arg1,
> + Object arg2) {
>
> Object args[] = new Object[3];
> args[0] = arg0;
> @@ -451,8 +408,8 @@
> * @param arg3 The replacement for placeholder {3} in
> the message
> */
> public String getMessage(Locale locale,
> - String key, String arg0, String arg1,
> - String arg2, String arg3) {
> + String key, Object arg0, Object arg1,
> + Object arg2, Object arg3) {
>
> Object args[] = new Object[4];
> args[0] = arg0;
> @@ -464,121 +421,115 @@
> }
>
>
> + //
> ------------------------------------------------------
> Protected Methods
> +
> +
> /**
> - * Returns a resource for the specified message key,
> or <code>null</code>
> - * if no corresponding resource can be found, for the
> default Locale.
> + * Compute and return a key to be used in caching
> information by a Locale.
> + * <strong>NOTE</strong> - The locale key for the
> default Locale in our
> + * environment is a zero length String.
> *
> - * @param key The resource key to look up
> + * @param locale The locale for which a key is desired
> */
> - public Object getResource(String key) {
> + protected String localeKey(Locale locale) {
>
> - return (getResource((Locale) null, key));
> + if (locale == null)
> + return ("");
> + else if (locale.equals(defaultLocale))
> + return ("");
> + else
> + return (locale.toString());
>
> }
>
>
> /**
> - * Returns a resource for the specified message key,
> or <code>null</code>
> - * if no corresponding resource can be found, for the
> specified Locale.
> + * Compute and return a key to be used in caching information
> + * by Locale and message key.
> *
> - * @param locale The requested message Locale, or
> <code>null</code>
> - * for the system default Locale
> - * @param key The resource key to look up
> + * @param locale The Locale for which this format key
> is calculated
> + * @param key The message key for which this format
> key is calculated
> */
> - public Object getResource(Locale locale, String key) {
> + protected String messageKey(Locale locale, String key) {
>
> - // Look up the resource bundle we will use
> - ResourceBundle bundle = null;
> - try {
> - bundle = getBundle(locale);
> - } catch (Exception e) {
> - return (null);
> - }
> -
> - // Look up the resource itself in this resource bundle
> - Object result = null;
> - try {
> - result = bundle.getString(key);
> - } catch (MissingResourceException e) {
> - return (null);
> - }
> - return (result);
> + return (localeKey(locale) + "." + key);
>
> }
>
>
> - //
> --------------------------------------------------------
> Private Methods
> -
> -
> /**
> - * Returns the key under which resources for a
> particular Locale may be
> - * uniquely accessed.
> + * Compute and return a key to be used in caching information
> + * by locale key and message key.
> *
> - * @param locale The locale for which a key is to be
> computed, or
> - * <code>null</code> for the system default Locale
> + * @param localeKey The locale key for which this
> cache key is calculated
> + * @param key The message key for which this cache key
> is calculated
> */
> - private String getLocaleKey(Locale locale) {
> + protected String messageKey(String localeKey, String key) {
>
> - if (locale == null)
> - locale = defaultLocale;
> - StringBuffer sb = new StringBuffer();
> - sb.append(locale.getCountry());
> - sb.append(".");
> - sb.append(locale.getLanguage());
> - sb.append(".");
> - String variant = locale.getVariant();
> - if (variant != null) {
> - sb.append(variant);
> - sb.append(".");
> - }
> - return (sb.toString());
> + return (localeKey + "." + key);
>
> }
>
>
> + //
> ---------------------------------------------------------
> Static Methods
> +
> +
> /**
> - * Returns the key under which a message format for a
> particular message,
> - * from the resource bundle for a particular locale,
> may be uniquely
> - * accessed.
> - *
> - * @param locale Locale for which this message key is computed
> - * @param id Message identifier for which this message
> key is computed
> + * The default MessageResourcesFactory used to create
> MessageResources
> + * instances.
> */
> - private String getResourceKey(Locale locale, String id) {
> + protected static MessageResourcesFactory defaultFactory = null;
>
> - return (getLocaleKey(locale) + "." + id);
>
> - }
> + /**
> + * Create and return an instance of
> <code>MessageResources</code> for the
> + * created by the default <code>MessageResourcesFactory</code>.
> + *
> + * @param config Configuration parameter for this
> message bundle.
> + */
> + public synchronized static MessageResources
> + getMessageResources(String config) {
>
> + if (defaultFactory == null)
> + defaultFactory =
> MessageResourcesFactory.createFactory();
> + return defaultFactory.createResources(config);
>
> - //
> ---------------------------------------------------------
> Static Methods
> + }
>
>
> /**
> - * The MessageResources instances that have been
> created so far,
> - * keyed by base name.
> + * Log a message to the Writer that has been
> configured for our use.
> + *
> + * @param message The message to be logged
> */
> - private static Hashtable cache = new Hashtable();
> + public void log(String message) {
>
> + PrintWriter writer = factory.getWriter();
> + if (writer != null) {
> + writer.print("MessageResources: ");
> + writer.println(message);
> + writer.flush();
> + }
>
> + }
> +
> +
> /**
> - * Return an instance of MessageResources for the
> specified base name.
> + * Log a message and exception to the Writer that has
> been configured
> + * for our use.
> *
> - * @param base Base name of the ResourceBundles to be wrapped
> - *
> - * @exception MissingResourcesException if no default resources
> - * can be loaded
> + * @param message The message to be logged
> + * @param throwable The exception to be logged
> */
> - public synchronized static MessageResources
> - getMessageResources(String base) throws
> MissingResourceException {
> + public void log(String message, Throwable throwable) {
>
> - MessageResources messageResources =
> - (MessageResources) cache.get(base);
> - if (messageResources != null)
> - return (messageResources);
> - messageResources = new MessageResources(base);
> - cache.put(base, messageResources);
> - return (messageResources);
> + PrintWriter writer = factory.getWriter();
> + if (writer != null) {
> + writer.print("MessageResources: ");
> + writer.println(message);
> + throwable.printStackTrace(writer);
> + writer.flush();
> + }
>
> }
>
>
>
>
> 1.1
> jakarta-struts/src/share/org/apache/struts/util/MessageResourc
> esFactory.java
>
> Index: MessageResourcesFactory.java
> ===================================================================
> /*
> * $Header:
> /home/cvs/jakarta-struts/src/share/org/apache/struts/util/Mess
> ageResourcesFactory.java,v 1.1 2000/12/15 03:08:11 craigmcc Exp $
> * $Revision: 1.1 $
> * $Date: 2000/12/15 03:08:11 $
> *
> *
> ====================================================================
> *
> * The Apache Software License, Version 1.1
> *
> * Copyright (c) 1999 The Apache Software Foundation. All rights
> * reserved.
> *
> * Redistribution and use in source and binary forms, with
> or without
> * modification, are permitted provided that the following
> conditions
> * are met:
> *
> * 1. Redistributions of source code must retain the above copyright
> * notice, this list of conditions and the following disclaimer.
> *
> * 2. Redistributions in binary form must reproduce the
> above copyright
> * notice, this list of conditions and the following
> disclaimer in
> * the documentation and/or other materials provided with the
> * distribution.
> *
> * 3. The end-user documentation included with the
> redistribution, if
> * any, must include the following acknowlegement:
> * "This product includes software developed by the
> * Apache Software Foundation (http://www.apache.org/)."
> * Alternately, this acknowlegement may appear in the
> software itself,
> * if and wherever such third-party acknowlegements
> normally appear.
> *
> * 4. The names "The Jakarta Project", "Tomcat", and
> "Apache Software
> * Foundation" must not be used to endorse or promote
> products derived
> * from this software without prior written permission.
> For written
> * permission, please contact apache@apache.org.
> *
> * 5. Products derived from this software may not be called "Apache"
> * nor may "Apache" appear in their names without prior written
> * permission of the Apache Group.
> *
> * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
> * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
> * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
> * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
> * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
> CAUSED AND
> * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
> LIABILITY,
> * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
> ANY WAY OUT
> * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
> POSSIBILITY OF
> * SUCH DAMAGE.
> *
> ====================================================================
> *
> * This software consists of voluntary contributions made by many
> * individuals on behalf of the Apache Software Foundation.
> For more
> * information on the Apache Software Foundation, please see
> * <http://www.apache.org/>.
> *
> */
>
>
> package org.apache.struts.util;
>
>
> import java.io.PrintWriter;
>
>
> /**
> * Factory for <code>MessageResources</code> instances.
> The general usage
> * pattern for this class is:
> * <ul>
> * <li>Call
> <code>MessageResourcesFactory().createFactory()</code> to retrieve
> * a <code>MessageResourcesFactory</code> instance.</li>
> * <li>Set properties as required to configure this factory
> instance to create
> * <code>MessageResources</code> instances with desired
> * characteristics.</li>
> * <li>Call the <code>createResources()</code> method of
> the factory to
> * retrieve a newly instantiated <code>MessageResources</code>
> * instance.</li>
> * </ul>
> *
> * @author Craig R. McClanahan
> * @version $Revision: 1.1 $ $Date: 2000/12/15 03:08:11 $
> */
>
> public abstract class MessageResourcesFactory {
>
>
> // ----------------------------------------------------
> Instance Properties
>
>
> /**
> * The "return null" property value to which newly created
> * MessageResourcess should be initialized.
> */
> protected boolean returnNull = true;
>
> public boolean getReturnNull() {
> return (this.returnNull);
> }
>
> public void setReturnNull(boolean returnNull) {
> this.returnNull = returnNull;
> }
>
>
> /**
> * The PrintWriter to which we can log debugging and
> error information,
> * if any.
> */
> protected PrintWriter writer = null;
>
> public PrintWriter getWriter() {
> return (this.writer);
> }
>
> public void setWriter(PrintWriter writer) {
> this.writer = writer;
> }
>
>
> //
> ---------------------------------------------------------
> Public Methods
>
>
> /**
> * Create and return a newly instansiated
> <code>MessageResources</code>.
> * This method must be implemented by concrete subclasses.
> *
> * @param config Configuration parameter(s) for the
> requested bundle
> */
> public abstract MessageResources createResources(String config);
>
>
> //
> ------------------------------------------------------ Static
> Properties
>
>
> /**
> * The Java class to be used for
> * <code>MessageResourcesFactory</code> instances.
> */
> protected static Class clazz = null;
>
>
> /**
> * The fully qualified class name to be used for
> * <code>MessageResourcesFactory</code> instances.
> */
> protected static String factoryClass =
> "org.apache.struts.util.PropertyMessageResourcesFactory";
>
> public static String getFactoryClass() {
> return (MessageResourcesFactory.factoryClass);
> }
>
> public static void setFactoryClass(String factoryClass) {
> MessageResourcesFactory.factoryClass = factoryClass;
> MessageResourcesFactory.clazz = null;
> }
>
>
> /**
> * The PrintWriter to which we can log error and
> debugging information,
> * if any.
> */
> protected static PrintWriter defaultWriter = null;
>
> public static PrintWriter getDefaultWriter() {
> return (MessageResourcesFactory.defaultWriter);
> }
>
> public static void setDefaultWriter(PrintWriter writer) {
> MessageResourcesFactory.defaultWriter = writer;
> }
>
>
> //
> ---------------------------------------------------------
> Static Methods
>
>
> /**
> * Create and return a
> <code>MessageResourcesFactory</code> instance of the
> * appropriate class, which can be used to create customized
> * <code>MessageResources</code> instances. If no such
> factory can be
> * created, return <code>null</code> instead.
> */
> public static MessageResourcesFactory createFactory() {
>
> // Construct a new instance of the specified factory class
> try {
> if (clazz == null)
> clazz = Class.forName(factoryClass);
> MessageResourcesFactory factory =
> (MessageResourcesFactory) clazz.newInstance();
> factory.setWriter(defaultWriter);
> return (factory);
> } catch (Throwable t) {
> if (defaultWriter != null) {
>
> defaultWriter.println("MessageResourcesFactory.createFactory");
> t.printStackTrace(defaultWriter);
> defaultWriter.flush();
> }
> return (null);
> }
>
> }
>
>
> }
>
>
>
> 1.1
> jakarta-struts/src/share/org/apache/struts/util/PropertyMessag
> eResources.java
>
> Index: PropertyMessageResources.java
> ===================================================================
> /*
> * $Header:
> /home/cvs/jakarta-struts/src/share/org/apache/struts/util/Prop
> ertyMessageResources.java,v 1.1 2000/12/15 03:08:11 craigmcc Exp $
> * $Revision: 1.1 $
> * $Date: 2000/12/15 03:08:11 $
> *
> *
> ====================================================================
> *
> * The Apache Software License, Version 1.1
> *
> * Copyright (c) 1999 The Apache Software Foundation. All rights
> * reserved.
> *
> * Redistribution and use in source and binary forms, with
> or without
> * modification, are permitted provided that the following
> conditions
> * are met:
> *
> * 1. Redistributions of source code must retain the above copyright
> * notice, this list of conditions and the following disclaimer.
> *
> * 2. Redistributions in binary form must reproduce the
> above copyright
> * notice, this list of conditions and the following
> disclaimer in
> * the documentation and/or other materials provided with the
> * distribution.
> *
> * 3. The end-user documentation included with the
> redistribution, if
> * any, must include the following acknowlegement:
> * "This product includes software developed by the
> * Apache Software Foundation (http://www.apache.org/)."
> * Alternately, this acknowlegement may appear in the
> software itself,
> * if and wherever such third-party acknowlegements
> normally appear.
> *
> * 4. The names "The Jakarta Project", "Tomcat", and
> "Apache Software
> * Foundation" must not be used to endorse or promote
> products derived
> * from this software without prior written permission.
> For written
> * permission, please contact apache@apache.org.
> *
> * 5. Products derived from this software may not be called "Apache"
> * nor may "Apache" appear in their names without prior written
> * permission of the Apache Group.
> *
> * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
> * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
> * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
> * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
> * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
> CAUSED AND
> * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
> LIABILITY,
> * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
> ANY WAY OUT
> * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
> POSSIBILITY OF
> * SUCH DAMAGE.
> *
> ====================================================================
> *
> * This software consists of voluntary contributions made by many
> * individuals on behalf of the Apache Software Foundation.
> For more
> * information on the Apache Software Foundation, please see
> * <http://www.apache.org/>.
> *
> */
>
>
> package org.apache.struts.util;
>
>
> import java.io.InputStream;
> import java.util.Enumeration;
> import java.util.HashMap;
> import java.util.Locale;
> import java.util.Properties;
>
>
> /**
> * Concrete subclass of <code>MessageResources</code> that
> reads message keys
> * and corresponding strings from named property resources
> in the same manner
> * that <code>java.util.PropertyResourceBundle</code> does. The
> * <code>base</code> property defines the base property
> resource name, and
> * must be specified.
> * <p>
> * <strong>IMPLEMENTATION NOTE</strong> - This class trades
> memory for
> * speed by caching all messages located via generalizing
> the Locale under
> * the original locale as well.
> * This results in specific messages being stored in the
> message cache
> * more than once, but improves response time on subsequent
> requests for
> * the same locale + key combination.
> *
> * @author Craig R. McClanahan
> * @version $Revision: 1.1 $ $Date: 2000/12/15 03:08:11 $
> */
>
> public class PropertyMessageResources extends MessageResources {
>
>
> //
> -----------------------------------------------------------
> Constructors
>
>
> /**
> * Construct a new PropertyMessageResources according to the
> * specified parameters.
> *
> * @param factory The MessageResourcesFactory that created us
> * @param config The configuration parameter for this
> MessageResources
> */
> public PropertyMessageResources(MessageResourcesFactory factory,
> String config) {
>
> super(factory, config);
>
> }
>
>
> /**
> * Construct a new PropertyMessageResources according to the
> * specified parameters.
> *
> * @param factory The MessageResourcesFactory that created us
> * @param config The configuration parameter for this
> MessageResources
> * @param returnNull The returnNull property we should
> initialize with
> */
> public PropertyMessageResources(MessageResourcesFactory factory,
> String config, boolean
> returnNull) {
>
> super(factory, config, returnNull);
>
> }
>
>
> //
> -------------------------------------------------------------
> Properties
>
>
> /**
> * The set of locale keys for which we have already
> loaded messages, keyed
> * by the value calculated in <code>localeKey()</code>.
> */
> protected HashMap locales = new HashMap();
>
>
> /**
> * The cache of messages we have accumulated over time,
> keyed by the
> * value calculated in <code>messageKey()</code>.
> */
> protected HashMap messages = new HashMap();
>
>
> //
> ---------------------------------------------------------
> Public Methods
>
>
> /**
> * Returns a text message for the specified key, for
> the default Locale.
> * A null string result will be returned by this method
> if no relevant
> * message resource is found for this key or Locale, if the
> * <code>returnNull</code> property is set. Otherwise,
> an appropriate
> * error message will be returned.
> * <p>
> * This method must be implemented by a concrete subclass.
> *
> * @param locale The requested message Locale, or
> <code>null</code>
> * for the system default Locale
> * @param key The message key to look up
> */
> public String getMessage(Locale locale, String key) {
>
> // Initialize variables we will require
> String localeKey = localeKey(locale);
> String originalKey = messageKey(localeKey, key);
> String messageKey = null;
> String message = null;
> int underscore = 0;
> boolean addIt = false; // Add if not found under
> the original key
>
> // Loop from specific to general Locales looking
> for this message
> while (true) {
>
> // Load this Locale's messages if we have not
> done so yet
> loadLocale(localeKey);
>
> // Check if we have this key for the current locale key
> messageKey = messageKey(localeKey, key);
> synchronized (messages) {
> message = (String) messages.get(messageKey);
> if (message != null) {
> if (addIt)
> messages.put(originalKey, message);
> return (message);
> }
> }
>
> // Strip trailing modifiers to try a more
> general locale key
> addIt = true;
> underscore = localeKey.lastIndexOf("_");
> if (underscore < 0)
> break;
> localeKey = localeKey.substring(0, underscore);
>
> }
>
> // As a last resort, try the default Locale
> localeKey = localeKey(defaultLocale);
> messageKey = messageKey(localeKey, key);
> loadLocale(localeKey);
> synchronized (messages) {
> message = (String) messages.get(messageKey);
> if (message != null) {
> if (addIt)
> messages.put(originalKey, message);
> return (message);
> }
> }
>
> // Return an appropriate error indication
> if (returnNull)
> return (null);
> else
> return ("???" + messageKey(locale, key) + "???");
>
> }
>
>
> //
> ------------------------------------------------------
> Protected Methods
>
>
> /**
> * Load the messages associated with the specified
> Locale key. For this
> * implementation, the <code>config</code> property
> should contain a fully
> * qualified package and resource name, separated by
> periods, of a series
> * of property resources to be loaded from the class
> loader that created
> * this PropertyMessageResources instance. This is
> exactly the same name
> * format you would use when utilizing the
> * <code>java.util.PropertyResourceBundle</code> class.
> *
> * @param localeKey Locale key for the messages to be retrieved
> */
> protected void loadLocale(String localeKey) {
>
> // Have we already attempted to load messages for
> this locale?
> synchronized (locales) {
> if (locales.get(localeKey) != null)
> return;
> locales.put(localeKey, localeKey);
> }
>
> // Set up to load the property resource for this
> locale key, if we can
> String name = config.replace('.', '/');
> if (localeKey.length() > 0)
> name += "_" + localeKey;
> name += ".properties";
> InputStream is = null;
> Properties props = new Properties();
>
> // Load the specified property resource
> try {
> is =
> this.getClass().getClassLoader().getResourceAsStream(name);
> if (is != null) {
> props.load(is);
> is.close();
> }
> } catch (Throwable t) {
> if (is != null) {
> try {
> is.close();
> } catch (Throwable u) {
> ;
> }
> }
> }
>
> // Copy the corresponding values into our cache
> if (props.size() < 1)
> return;
> synchronized (messages) {
> Enumeration names = props.keys();
> while (names.hasMoreElements()) {
> String key = (String) names.nextElement();
> messages.put(messageKey(localeKey, key),
> props.getProperty(key));
> }
> }
>
> }
>
>
> }
>
>
>
> 1.1
> jakarta-struts/src/share/org/apache/struts/util/PropertyMessag
> eResourcesFactory.java
>
> Index: PropertyMessageResourcesFactory.java
> ===================================================================
> /*
> * $Header:
> /home/cvs/jakarta-struts/src/share/org/apache/struts/util/Prop
> ertyMessageResourcesFactory.java,v 1.1 2000/12/15 03:08:11
> craigmcc Exp $
> * $Revision: 1.1 $
> * $Date: 2000/12/15 03:08:11 $
> *
> *
> ====================================================================
> *
> * The Apache Software License, Version 1.1
> *
> * Copyright (c) 1999 The Apache Software Foundation. All rights
> * reserved.
> *
> * Redistribution and use in source and binary forms, with
> or without
> * modification, are permitted provided that the following
> conditions
> * are met:
> *
> * 1. Redistributions of source code must retain the above copyright
> * notice, this list of conditions and the following disclaimer.
> *
> * 2. Redistributions in binary form must reproduce the
> above copyright
> * notice, this list of conditions and the following
> disclaimer in
> * the documentation and/or other materials provided with the
> * distribution.
> *
> * 3. The end-user documentation included with the
> redistribution, if
> * any, must include the following acknowlegement:
> * "This product includes software developed by the
> * Apache Software Foundation (http://www.apache.org/)."
> * Alternately, this acknowlegement may appear in the
> software itself,
> * if and wherever such third-party acknowlegements
> normally appear.
> *
> * 4. The names "The Jakarta Project", "Tomcat", and
> "Apache Software
> * Foundation" must not be used to endorse or promote
> products derived
> * from this software without prior written permission.
> For written
> * permission, please contact apache@apache.org.
> *
> * 5. Products derived from this software may not be called "Apache"
> * nor may "Apache" appear in their names without prior written
> * permission of the Apache Group.
> *
> * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
> * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
> * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
> * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
> * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
> CAUSED AND
> * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
> LIABILITY,
> * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
> ANY WAY OUT
> * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
> POSSIBILITY OF
> * SUCH DAMAGE.
> *
> ====================================================================
> *
> * This software consists of voluntary contributions made by many
> * individuals on behalf of the Apache Software Foundation.
> For more
> * information on the Apache Software Foundation, please see
> * <http://www.apache.org/>.
> *
> */
>
>
> package org.apache.struts.util;
>
>
> /**
> * Factory for <code>PropertyMessageResources</code> instances. The
> * configuration paramter for such instances is the base
> Java package
> * name of the resources entries from which our keys and
> values will be
> * loaded.
> *
> * @author Craig R. McClanahan
> * @version $Revision: 1.1 $ $Date: 2000/12/15 03:08:11 $
> */
>
> public class PropertyMessageResourcesFactory extends
> MessageResourcesFactory {
>
>
> //
> ---------------------------------------------------------
> Public Methods
>
>
> /**
> * Create and return a newly instansiated
> <code>MessageResources</code>.
> * This method must be implemented by concrete subclasses.
> *
> * @param config Configuration parameter(s) for the
> requested bundle
> */
> public MessageResources createResources(String config) {
>
> return new PropertyMessageResources(this, config,
> this.returnNull);
>
> }
>
>
> }
>
>
>
> 1.1
> jakarta-struts/src/share/org/apache/struts/util/ServletContext
> Writer.java
>
> Index: ServletContextWriter.java
> ===================================================================
> /*
> * $Header:
> /home/cvs/jakarta-struts/src/share/org/apache/struts/util/Serv
> letContextWriter.java,v 1.1 2000/12/15 03:08:11 craigmcc Exp $
> * $Revision: 1.1 $
> * $Date: 2000/12/15 03:08:11 $
> *
> *
> ====================================================================
> *
> * The Apache Software License, Version 1.1
> *
> * Copyright (c) 1999 The Apache Software Foundation. All rights
> * reserved.
> *
> * Redistribution and use in source and binary forms, with
> or without
> * modification, are permitted provided that the following
> conditions
> * are met:
> *
> * 1. Redistributions of source code must retain the above copyright
> * notice, this list of conditions and the following disclaimer.
> *
> * 2. Redistributions in binary form must reproduce the
> above copyright
> * notice, this list of conditions and the following
> disclaimer in
> * the documentation and/or other materials provided with the
> * distribution.
> *
> * 3. The end-user documentation included with the
> redistribution, if
> * any, must include the following acknowlegement:
> * "This product includes software developed by the
> * Apache Software Foundation (http://www.apache.org/)."
> * Alternately, this acknowlegement may appear in the
> software itself,
> * if and wherever such third-party acknowlegements
> normally appear.
> *
> * 4. The names "The Jakarta Project", "Tomcat", and
> "Apache Software
> * Foundation" must not be used to endorse or promote
> products derived
> * from this software without prior written permission.
> For written
> * permission, please contact apache@apache.org.
> *
> * 5. Products derived from this software may not be called "Apache"
> * nor may "Apache" appear in their names without prior written
> * permission of the Apache Group.
> *
> * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
> * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
> * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
> * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
> * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
> CAUSED AND
> * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
> LIABILITY,
> * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
> ANY WAY OUT
> * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
> POSSIBILITY OF
> * SUCH DAMAGE.
> *
> ====================================================================
> *
> * This software consists of voluntary contributions made by many
> * individuals on behalf of the Apache Software Foundation.
> For more
> * information on the Apache Software Foundation, please see
> * <http://www.apache.org/>.
> *
> */
>
>
> package org.apache.struts.util;
>
>
> import java.io.PrintWriter;
> import java.io.StringWriter;
> import javax.servlet.ServletContext;
>
>
> /**
> * A PrintWriter implementation that uses the logging
> facilities of a
> * <code>javax.servlet.ServletContext</code> to output its
> results. Output
> * will be buffered until a newline character is output,
> <code>flush()</code>
> * is called, or until one of the <code>println()</code>
> methods is called.
> * Along the way, carriage return characters are skipped.
> *
> * @author Craig R. McClanahan
> * @version $Revision: 1.1 $ $Date: 2000/12/15 03:08:11 $
> */
>
> public class ServletContextWriter extends PrintWriter {
>
>
> //
> -----------------------------------------------------------
> Constructors
>
>
> /**
> * Construct a ServletContextWriter associated with the
> specified
> * ServletContext instance.
> *
> * @param context The associated servlet context
> */
> public ServletContextWriter(ServletContext context) {
>
> super(new StringWriter());
> this.context = context;
>
> }
>
>
> //
> -------------------------------------------------------------
> Properties
>
>
> /**
> * The buffer into which we accumulate lines to be logged.
> */
> protected StringBuffer buffer = new StringBuffer();
>
>
> /**
> * The servlet context with which we are associated.
> */
> protected ServletContext context = null;
>
>
> /**
> * The error state for this stream.
> */
> protected boolean error = false;
>
>
> //
> ---------------------------------------------------------
> Public Methods
>
>
> /**
> * Flush the stream and check for its error state.
> <strong>IMPLEMENTATION
> * NOTE</strong> - our associated servlet context gives
> no indication of
> * problems with logging, so the only way this method
> will return
> * <code>true</code> is if <code>setError()</code> is called.
> */
> public boolean checkError() {
>
> flush();
> return (error);
>
> }
>
>
> /**
> * Close the stream.
> */
> public void close() {
>
> flush();
>
> }
>
>
> /**
> * Flush the stream.
> */
> public void flush() {
>
> if (buffer.length() > 0) {
> context.log(buffer.toString());
> buffer.setLength(0);
> }
>
> }
>
>
> /**
> * Print a boolean value.
> *
> * @param b The value to be printed
> */
> public void print(boolean b) {
>
> write(String.valueOf(b));
>
> }
>
>
> /**
> * Print a character value.
> *
> * @param c The value to be printed
> */
> public void print(char c) {
>
> write(c);
>
> }
>
>
> /**
> * Print a character array.
> *
> * @param c The character array to be printed
> */
> public void print(char c[]) {
>
> for (int i = 0; i < c.length; i++)
> write(c[i]);
>
> }
>
>
> /**
> * Print a double value.
> *
> * @param d The value to be printed
> */
> public void print(double d) {
>
> write(String.valueOf(d));
>
> }
>
>
> /**
> * Print a float value.
> *
> * @param f The value to be printed
> */
> public void print(float f) {
>
> write(String.valueOf(f));
>
> }
>
>
> /**
> * Print an integer value.
> *
> * @param i The value to be printed
> */
> public void print(int i) {
>
> write(String.valueOf(i));
>
> }
>
>
> /**
> * Print a long value.
> *
> * @param l The value to be printed
> */
> public void print(long l) {
>
> write(String.valueOf(l));
>
> }
>
>
> /**
> * Print an object.
> *
> * @param o The value to be printed
> */
> public void print(Object o) {
>
> write(o.toString());
>
> }
>
>
> /**
> * Print a String value.
> *
> * @param s The value to be printed
> */
> public void print(String s) {
>
> int len = s.length();
> for (int i = 0; i < len; i++)
> write(s.charAt(i));
>
> }
>
>
> /**
> * Terminate the current line and flush the buffer.
> */
> public void println() {
>
> flush();
>
> }
>
>
> /**
> * Print a boolean value and terminate the line.
> *
> * @param b The value to be printed
> */
> public void println(boolean b) {
>
> println(String.valueOf(b));
>
> }
>
>
> /**
> * Print a character value and terminate the line.
> *
> * @param c The value to be printed
> */
> public void println(char c) {
>
> write(c);
> println();
>
> }
>
>
> /**
> * Print a character array and terminate the line.
> *
> * @param c The character array to be printed
> */
> public void println(char c[]) {
>
> for (int i = 0; i < c.length; i++)
> print(c[i]);
> println();
>
> }
>
>
> /**
> * Print a double value and terminate the line.
> *
> * @param d The value to be printed
> */
> public void println(double d) {
>
> println(String.valueOf(d));
>
> }
>
>
> /**
> * Print a float value and terminate the line.
> *
> * @param f The value to be printed
> */
> public void println(float f) {
>
> println(String.valueOf(f));
>
> }
>
>
> /**
> * Print an integer value and terminate the line.
> *
> * @param i The value to be printed
> */
> public void println(int i) {
>
> println(String.valueOf(i));
>
> }
>
>
> /**
> * Print a long value and terminate the line.
> *
> * @param l The value to be printed
> */
> public void println(long l) {
>
> println(String.valueOf(l));
>
> }
>
>
> /**
> * Print an object and terminate the line.
> *
> * @param o The value to be printed
> */
> public void println(Object o) {
>
> println(o.toString());
>
> }
>
>
> /**
> * Print a String value and terminate the line.
> *
> * @param s The value to be printed
> */
> public void println(String s) {
>
> int len = s.length();
> for (int i = 0; i < len; i++)
> print(s.charAt(i));
> println();
>
> }
>
>
> /**
> * Set the error state for this stream.
> */
> public void setError() {
>
> this.error = true;
>
> }
>
>
> /**
> * Write a single character to this stream.
> *
> * @param c The character to be written
> */
> public void write(char c) {
>
> if (c == '\n')
> flush();
> else if (c != '\r')
> buffer.append(c);
>
> }
>
>
> /**
> * Write a single character to this stream.
> *
> * @param c The character to be written
> */
> public void write(int c) {
>
> write((char) c);
>
> }
>
>
> /**
> * Write an array of charaters to this stream.
> *
> * @param buf The character array to be written
> */
> public void write(char buf[]) {
>
> for (int i = 0; i < buf.length; i++)
> write(buf[i]);
>
> }
>
>
> /**
> * Write the specified subset of an array of characters
> to this stream.
> *
> * @param buf The character array from which to write
> * @param off The zero-relative starting offset to write
> * @param len The number of characters to write
> */
> public void write(char buf[], int off, int len) {
>
> for (int i = off; i < len; i++)
> write(buf[i]);
>
> }
>
>
> /**
> * Write a String to this stream.
> *
> * @param s The string to be written
> */
> public void write(String s) {
>
> int len = s.length();
> for (int i = 0; i < len; i++)
> write(s.charAt(i));
>
> }
>
>
> /**
> * Write the specified portion of a String to this stream.
> *
> * @param s The String from which to write
> * @param off The zero-relative starting offset to write
> * @param len The number of characters to write
> */
> public void write(String s, int off, int len) {
>
> for (int i = off; i < len; i++)
> write(s.charAt(i));
>
> }
>
>
> }
>
>
>
>