Hello All
I have coded up an ErrorResources Bundle. Sorry for the delay. I have been
busy with customers and making a living :)... Well I hope that this is a
more elegant solution than my inline error messages were.

I have created an ErrorResources.java file which is inherited from a new
file called ResourceBundle.java. ResourceBundle.java was basically derived
from TurbineResources.java. I took the non-static methods and moved them
into ResourceBundle.java. ErrorResources and TurbineResources inherit from
ResourceBundle.

I basically created a default error message bundle which is populated from
the static{} method of the ErrorResources class. I will continue to add
error messages as time permits.

It is possible to use property files to configure the error messages.
I am strongly -1 on this however, because it is another configuration
problem that can occur. In the case where multiple configuration problems
are encountered and Error Resource property file is not configured.
Debugging could be a nightmare. Just imagine untarring Turbine and getting
zero error messages.

I believe even if we do not go with property file error messages that the
isolation of error messages to one file is a great thing. I would prefer a
system where we just add error messages to the default Error Resource
Bundle in the static method. I know that this requires a recompile to
change error messages, but it only requires one file to be recompiled and
the isolation of error messages makes the code more readable and
manageable.

Questions Comments Discussion
I hope these solutions are better!!!!


Jeff

--------------------DIFFS--------------------------------------------
? turbine/bin
? turbine/build/jeffsbuild.sh
? turbine/src/java/org/apache/util
? turbine/src/java/org/apache/turbine/opl/database/DbBroker.class
? turbine/src/java/org/apache/turbine/opl/database/DbBrokerManager.class
? turbine/src/java/org/apache/turbine/services/schedule/JobEntry.class
? turbine/src/java/org/apache/turbine/services/schedule/TurbineScheduler.class
? turbine/src/java/org/apache/turbine/services/schedule/JobEntryPeer.class
? turbine/src/java/org/apache/turbine/util/ErrorResources.java
? turbine/src/java/org/apache/turbine/util/ResourceBundle.java
Index: turbine/src/java/Turbine.java
===================================================================
RCS file: /products/cvs/turbine/turbine/src/java/Turbine.java,v
retrieving revision 1.28
diff -r1.28 Turbine.java
78a79
> import org.apache.ecs.html.*;
103c104
<     private boolean init = false;
---
>     private String initFailureMessage = null;
113c114,115
<         if ( props == null || props.length() == 0 || ! new File(props).exists() )
---
> 
>         if ( props == null)
115,116c117,121
<             log ( "Properties file not found: " + props );
<             return;
---
>             String params[] = {"properties"};
>             initFailureMessage = ErrorResources.getInstance().getMessage(
>                    ErrorResources.PROPERTIES_INIT_PARAMETER_NOT_FOUND, params);
>             log(initFailureMessage);
>             throw new ServletException(initFailureMessage);       
118c123,148
< 
---
>         else if(props.length() == 0)
>         {
>             String params[] = {"properties"};
>             initFailureMessage = ErrorResources.getInstance().getMessage(
>                    ErrorResources.PROPERTIES_INIT_PARAMETER_ZERO_LENGTH_STRING,
>                    params);
>             log(initFailureMessage);
>             throw new ServletException(initFailureMessage);       
>         }
>         else if(!(new File(props).exists()))
>         {
>             String params[] = {props, "properties"};
>             initFailureMessage = ErrorResources.getInstance().getMessage(
>                    ErrorResources.TURBINE_RESOURCE_FILE_DOES_NOT_EXIST, params);
>             log(initFailureMessage);
>             throw new ServletException(initFailureMessage);
>         }
>         else if(!(new File(props).canRead()))
>         {
>             String params[] = {props, System.getProperty("user.name")};
>             initFailureMessage = ErrorResources.getInstance().getMessage(
>                    ErrorResources.TURBINE_RESOURCE_FILE_NOT_READABLE, params);
>             log(initFailureMessage);
>             throw new ServletException(initFailureMessage);
>         }           
>         
146d175
<         init = true;
147a177
> 
167c197
<         if ( ! init )
---
>         if (initFailureMessage != null)
169c199,210
<             res.getOutputStream().println ("Turbine: could not find properties 
file!");
---
>             res.setContentType("text/html");
>             Document initErrorPage = new Document();
>             Head initErrorPageHeader = new Head();
>             Title initErrorPageTitle = new Title(
>                    "Turbine Initialization Error");
>             Body initErrorPageBody = new Body();
>             StringElement message = new StringElement(initFailureMessage);
>             initErrorPageBody.addElement((Element) message);
>             initErrorPage.setBody(initErrorPageBody);
>             initErrorPageHeader.addElement((Element) initErrorPageTitle);
>             initErrorPage.setHead(initErrorPageHeader);
>             initErrorPage.output(res.getOutputStream());
375c416
< }
\ No newline at end of file
---
> }
Index: turbine/src/java/org/apache/turbine/services/schedule/TurbineScheduler.java
===================================================================
RCS file: 
/products/cvs/turbine/turbine/src/java/org/apache/turbine/services/schedule/TurbineScheduler.java,v
retrieving revision 1.2
diff -r1.2 TurbineScheduler.java
77,78c77,78
< public class TurbineScheduler implements Runnable, Comparable {
<     
---
> public class TurbineScheduler implements Runnable, 
>        org.apache.turbine.util.Comparable {
317c317
<     
\ No newline at end of file
---
>     
Index: turbine/src/java/org/apache/turbine/util/TurbineResources.java
===================================================================
RCS file: 
/products/cvs/turbine/turbine/src/java/org/apache/turbine/util/TurbineResources.java,v
retrieving revision 1.11
diff -r1.11 TurbineResources.java
69c69
< public class TurbineResources
---
> public class TurbineResources extends ResourceBundle
102,104d101
<     /** The configurations that this class holds. */
<     private Configurations confs = null;
< 
110c107
<         confs = new Configurations(new ExtendedProperties(fileName));
---
>         super(new Configurations(new ExtendedProperties(fileName)));
145,204d141
<     }
< 
<     public boolean getBoolean(String name) {
<         return confs.getBoolean(name);
<     }
< 
<     public boolean getBoolean(String name, boolean def) {
<         return confs.getBoolean(name, def);
<     }
< 
<     public double getDouble(String name) {
<         return confs.getDouble(name);
<     }
< 
<     public double getDouble(String name, double def) {
<         return confs.getDouble(name, def);
<     }
< 
<     public float getFloat(String name) {
<         return confs.getFloat(name);
<     }
< 
<     public float getFloat(String name, float def) {
<         return confs.getFloat(name, def);
<     }
< 
<     public int getInt(String name) {
<         return confs.getInteger(name);
<     }
< 
<     public int getInt(String name, int def) {
<         return confs.getInteger(name, def);
<     }
< 
<     public Enumeration getKeys() {
<         return confs.getKeys();
<     }
< 
<     public Enumeration getKeys(String prefix) {
<         return confs.getKeys(prefix);
<     }
< 
<     public long getLong(String name) {
<         return confs.getLong(name);
<     }
< 
<     public long getLong(String name, long def) {
<         return confs.getLong(name, def);
<     }
< 
<     public String getString(String name) {
<         return confs.getString(name);
<     }
< 
<     public String getString(String name, String def) {
<         return confs.getString(name, def);
<     }
< 
<     public Vector getVector(String name) {
<         return confs.getVector(name);

--------------------------------------ResourceBundle.java------------------
/*
 * Copyright (c) 1997-1999 The Java Apache Project.  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. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the Java Apache
 *    Project for use in the Apache JServ servlet engine project
 *    <http://java.apache.org/>."
 *
 * 4. The names "Apache JServ", "Apache JServ Servlet Engine", "Turbine",
 *    "Apache Turbine", "Turbine Project", "Apache Turbine Project" and
 *    "Java Apache Project" must not be used to endorse or promote products
 *    derived from this software without prior written permission.
 *
 * 5. Products derived from this software may not be called "Apache JServ"
 *    nor may "Apache" nor "Apache JServ" appear in their names without
 *    prior written permission of the Java Apache Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the Java Apache
 *    Project for use in the Apache JServ servlet engine project
 *    <http://java.apache.org/>."
 *
 * THIS SOFTWARE IS PROVIDED BY THE JAVA APACHE PROJECT "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 JAVA APACHE PROJECT 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 Java Apache Group. For more information
 * on the Java Apache Project and the Apache JServ Servlet Engine project,
 * please see <http://java.apache.org/>.
 *
 */

package org.apache.turbine.util;
import java.util.*;

import org.apache.java.util.*;

/**
 * This class encapsulates the functionality of a generic turbine resource
 * bundle. This code was derived from the TurbineResources.java file.
 * It basically consists of a group of accessors for configuration information.
 * @author Jeff Prickett [EMAIL PROTECTED]
 */

public class ResourceBundle extends Object
{
    /** The configurations that this class holds. */
    private Configurations confs = null;

    /**
     * The constructor used by a sub class to create a resource bundle.
     * @param theConf The new configuration for the resource bundles
     */
    protected ResourceBundle(Configurations theConf)
    {
        confs = theConf;
    }    

    /**
     * The purpose of this method is to get the configuration resource with
     * the given name as a boolean value.
     * @param name The resource name
     * @return The value of the named resource as a boolean
     */
    public boolean getBoolean(String name) {
        return confs.getBoolean(name);
    }

    /**
     * The purppose of this method is to get the configuration resource with
     * the given name as a boolean value.
     * @param name The resource name
     * @param def The default value of the resource
     * @return The value of the named resource as a boolean
     */
    public boolean getBoolean(String name, boolean def) {
        return confs.getBoolean(name, def);
    }

    /**
     * The purpose of this method is to get the configuration resource with 
     * the given name as a double.
     * @param name The resoource name
     * @return The value of the named resource as double 
     */
    public double getDouble(String name) {
        return confs.getDouble(name);
    }

    /**
     * The purpose of this method is to get the configuration resource with
     * the given name as a double.
     * @param name The resource name
     * @param def The default value of the resource
     * @return The value of the named resource as a double
     */
    public double getDouble(String name, double def) {
        return confs.getDouble(name, def);
    }

    /**
     * The purpose of this method is to get the configuration resource with
     * the given name as a float.
     * @param name The resource name
     * @return The value of the resource as a float
     */
    public float getFloat(String name) {
        return confs.getFloat(name);
    }

    /**
     * The purpose of this method is to get the configuration resource with
     * the given name as a float.
     * @param name The resource name
     * @param def The default value of the resource
     * @return The value of the resource as a float
     */
    public float getFloat(String name, float def) {
        return confs.getFloat(name, def);
    }

    /**
     * The purpose of this method is to get the configuration resource with
     * the given name as an integer.
     * @param name The resource name
     * @return The value of the resource as a float
     */
    public int getInt(String name) {
        return confs.getInteger(name);
    }

    /**
     * The purpose of this method is to get the configuration resource with
     * the given name as an integer.
     * @param name The resource name
     * @param def The default value of the resource
     * @return The value of the resource as an integer
     */
    public int getInt(String name, int def) {
        return confs.getInteger(name, def);
    }

    /**
     * The purpose of this method is to get an Enumeration of all the keys
     * in the resource bundle.
     * @return An enumeration full of all the keys
     */
    public Enumeration getKeys() {
        return confs.getKeys();
    }

    /**
     * The purpose of this method is to get an Enumeration full of all the
     * keys that begin with the given prefix.
     * @param prefix The prefix of the keys to retrieve
     * @return An enumeration full of keys that begin with the given prefix
     */
    public Enumeration getKeys(String prefix) {
        return confs.getKeys(prefix);
    }

    /**
     * The purpose of this method is to get the configuration resource with
     * the given name as a long.
     * @param name The resource name
     * @return The value of the resource as a long
     */
    public long getLong(String name) {
        return confs.getLong(name);
    }

    /**
     * The purpose of this method is to get the configuration resource with
     * the given name as a long.
     * @param name The resource name
     * @param def The default value of the resource
     * @return The value of the resource as a long
     */
    public long getLong(String name, long def) {
        return confs.getLong(name, def);
    }

    /**
     * The purpose of this method is to get the configuration resource with
     * the given name as a string.
     * @param name The resource name
     * @return The value of the resource as a string
     */
    public String getString(String name) {
        return confs.getString(name);
    }

    /**
     * The purpose of this method is to get the configuration resource with
     * the given name as a string.
     * @param name The resource name
     * @param def The default value of the resource
     * @return The value of the resource as a string
     */
    public String getString(String name, String def) {
        return confs.getString(name, def);
    }

    /**
     * The purpose of this method is to get the configuration resource with
     * the given name as a vector.
     * @param name The resource name
     * @return The value of the resource as a vector.
     */
    public Vector getVector(String name) {
        return confs.getVector(name);
    }
}    

-----------------------------------ErrorResources.java------------------------
/*
 * Copyright (c) 1997-1999 The Java Apache Project.  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. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the Java Apache
 *    Project for use in the Apache JServ servlet engine project
 *    <http://java.apache.org/>."
 *
 * 4. The names "Apache JServ", "Apache JServ Servlet Engine", "Turbine",
 *    "Apache Turbine", "Turbine Project", "Apache Turbine Project" and
 *    "Java Apache Project" must not be used to endorse or promote products
 *    derived from this software without prior written permission.
 *
 * 5. Products derived from this software may not be called "Apache JServ"
 *    nor may "Apache" nor "Apache JServ" appear in their names without
 *    prior written permission of the Java Apache Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the Java Apache
 *    Project for use in the Apache JServ servlet engine project
 *    <http://java.apache.org/>."
 *
 * THIS SOFTWARE IS PROVIDED BY THE JAVA APACHE PROJECT "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 JAVA APACHE PROJECT 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 Java Apache Group. For more information
 * on the Java Apache Project and the Apache JServ Servlet Engine project,
 * please see <http://java.apache.org/>.
 *
 */

package org.apache.turbine.util;
import java.io.*;
import java.util.*;

import org.apache.java.util.*;

/**
 * This class is an error resource bundle. It is a collection of error messages
 * that can be used for log files and exception handling to define messages.
 * The main addition to this bundle from a generic 
 * resource bundle is the getMessage(String, String[]) method. This method
 * returns a string to be printed in a log file. The first string is a resource
 * name or key, the array of strings is a parameter array. The getMessage
 * method looks up the message string that corresponds to the key. It then
 * parses the message string, inserting the parameters where they belong. 
 * The parameters are inserted in the string where there is a $[number] 
 * combination. This was modelled after shell scripts which use $1, $2, etc
 * to represent command line arguments. $1 corresponds to params[0],
 * $2 corresponds to params[1]. etc.
 * @author Jeff Prickett [EMAIL PROTECTED]
 */

public class ErrorResources extends ResourceBundle
{

    /** The key that corresponds to the error condition that exists when
     *  a properties parameter is not found. The message for this error
     *  has one parameter argument. It is as follows:
     *       $1 = properties init argument name
     */
    public static final String PROPERTIES_INIT_PARAMETER_NOT_FOUND = 
           "error.org.apache.Turbine.init.1";
    
    /**
     * The key that corresponds to the error condition that exists when a
     * propeties parameter is a zero length string. The message for this error
     * has one parameter argument. It is as follows:
     *        $1 = properties init argument name
     */
    public static final String PROPERTIES_INIT_PARAMETER_ZERO_LENGTH_STRING =
           "error.org.apache.Turbine.init.2";
    
    /**
     * The key that corresponds to the error condition that exists when the
     * turbine resources file does not exist. The message for this error has
     * two parameters.
     *        $1 = Turbine Resources property file name 
     *        $2 = properties init argument name
     */
    public static final String TURBINE_RESOURCE_FILE_DOES_NOT_EXIST =
           "error.org.apache.Turbine.init.3";

    /**
     * The key that corresponds to the error condition that exists when the
     * turbine resources file is not readable. The message for this error
     * has two parameters.
     *       $1 = Turbine Resources property file name
     *       $2 = user who is running JVM process
     */
    public static final String TURBINE_RESOURCE_FILE_NOT_READABLE =
           "error.org.apache.Turbine.init.4";
           
    private static String fileName = null;
    private static ErrorResources instance = null;
    private static ErrorResources defaultErrorResources = null;

    private ErrorResources() throws IOException
    {
        super(new Configurations(new ExtendedProperties(fileName)));
    }

    private ErrorResources(Configurations defaults) throws IOException
    {
        super(defaults);
    }
    
    public static void setPropertiesFileName(String propertiesFileName)
    {
        fileName = propertiesFileName;
    }
    
    public static ErrorResources getInstance()
    {
        if(instance.equals(defaultErrorResources))
        {
            synchronized(ErrorResources.class)
            {
                if((instance.equals(defaultErrorResources)) && 
                       (fileName !=null))
                {
                    try
                    {
                        instance = new ErrorResources();
                        defaultErrorResources = null;
                    }
                    catch(IOException ioe)
                    {
                    }
                }
            }
        }
        return instance;
    }
    
    static
    {
        try
        {
            /*
             * Populate the default error resources with messages.
             */
            ExtendedProperties defaults = new ExtendedProperties();
            defaults.put((Object) PROPERTIES_INIT_PARAMETER_NOT_FOUND,
                   (Object) "Turbine::init(ServletConfig) - '$1' Init Parameter"
                   + " not found. Please specify a value for the '$1' Init " +
                   "Parameter by editing the servlet zone properties " +
                   "file. This is done by adding the following line to the zone"
                   + " properties file: " +
                   "servlet.Turbine.initArgs=$1=" +
                   "/path/to/TurbineResources.properties");
               
            defaults.put((Object) PROPERTIES_INIT_PARAMETER_ZERO_LENGTH_STRING,
                  (Object) "Turbine::init(ServletConfig) - '$1' Init Parameter"
                  + " value is empty. The '$1' Init Parameter exists but it is "
                  + "a zero length string. Please specify a value for the '$1'"
                  + "Init Parameter. This is done by adding the following line" 
                  + "to the zone properties file: " +
                  "servlet.Turbine.initArgs=properties=" +
                  "/path/to/TurbineResources.properties");

            defaults.put((Object) TURBINE_RESOURCE_FILE_DOES_NOT_EXIST,
                   (Object) "Turbine::init(ServletConfig) - The Turbine " +
                   "Resources "
                   + "File - '$1' does not exist. Please create it or change " 
                   + "the"
                   + " '$2' Init Parameter Value to a file name that exists and"
                   + " contains the TurbineResources.");
        
            defaults.put((Object) TURBINE_RESOURCE_FILE_NOT_READABLE,
                   (Object) "Turbine::init(ServletConfig) - The Turbine " +
                   "Resources"
                   + " Property file - '$1' is not readable by user '$2'. "
                   + "Please"
                   + " change permissions on the file. In UNIX this is done by "
                   + "executing the chmod command.");

            defaultErrorResources = new ErrorResources(new Configurations(
                   (ConfigurationsRepository) defaults));     
            instance = defaultErrorResources;
        }
        catch(Exception e)
        {
            System.err.println(e);
            e.printStackTrace();
        }    
    }          

    public String getMessage(String messageName, String[] messageParams)
    {
        String rawMessage = getString(messageName);
        StringBuffer messageOut = new StringBuffer();
        StringTokenizer tokens = new StringTokenizer(rawMessage, "$");
        String nextToken = (String) tokens.nextElement();
        messageOut.append(nextToken);
        for(;tokens.hasMoreTokens();) 
        {
            nextToken = (String) tokens.nextElement();
            int i = 0;
            for(i = 0; Character.isDigit(nextToken.charAt(i)); i++) {}
            int parameterIndex = Integer.valueOf(nextToken.substring(0, i))
                   .intValue() - 1;
            messageOut.append(messageParams[parameterIndex]);
            messageOut.append(nextToken.substring(i, nextToken.length()));
        }
        return messageOut.toString();
    }    
           
}    




------------------------------------------------------------
To subscribe:        [EMAIL PROTECTED]
To unsubscribe:      [EMAIL PROTECTED]
Problems?:           [EMAIL PROTECTED]

Reply via email to