/* ====================================================================
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2000-2001 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 acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Apache" and "Apache Software Foundation" and
 *     "Apache Jetspeed" 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" or
 *    "Apache Jetspeed", nor may "Apache" appear in their name, without
 *    prior written permission of the Apache Software Foundation.
 *
 * 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.jetspeed.services.resources;

// Turbine stuff
import org.apache.turbine.util.Log;
import org.apache.turbine.services.resources.TurbineResourceService;
import org.apache.turbine.services.resources.ResourceService;

import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.PropertiesConfiguration;

/**
 * <p>This service subclasses <code>TurbineResourceService</code> and
 * provides functionality for overriding properties in default resource
 * files. This override behavior is extended to non-string properties</p>
 * 
 * <P>To override properties:
 * <ul>
 * <li>Define your own property file containing properties you want to override (for example, my.properties)</li>
 * <li>Add the following property in my.properties file:
 * <code>services.ResourceService.classname = org.apache.jetspeed.services.resources.JetspeedResourceService</code></li>
 * <li>Include TurbineResources.properties at the end of my.properties file</li>
 * <li>Set <code>properties</code> init parameter in web.xml to <code>my.properties</code></li>
 * <li>Set <code>resources</code> init parameter in web.xml to
 * <code>org.apache.jetspeed.services.resources.JetspeedResourceService</code></li>
 * </ul>
 * 
 * <P><B>Important note on overriding services.</B>Order of initializing services may be important.
 * Overriding a service may change this order. It is important that services attempt to initialize
 * dependent services in their early init methods. For example, to make sure that ServletService is
 * running, invoke the following code:
 * <PRE>
 * TurbineServices.getInstance().initService(ServletService.SERVICE_NAME, conf);
 * </PRE>
 * </P>
 * 
 * <P>Also, ${variable} substitution is extended to non-string properties. For example, the following
 * property references are valid:
 * <PRE>
 * confRoot=/WEB-INF/conf
 * 
 * psmlMapFile=${confRoot}/psml-mapping.xml
 * registryMapFile=${confRoot}/registry-mapping.xml
 * 
 * defaultRefresh=60
 * 
 * registryRefresh=${defaultRefresh}
 * psmlRefresh=${defaultRefresh}
 * </PRE>
 * </P>
 * 
 * @author <a href="mailto:morciuch@apache.org">Mark Orciuch</a>
 * @version $Id: JetspeedResourceService.java,v 1.2 2002/10/15 17:35:33 taylor Exp $
 */
public class JetspeedResourceService
extends TurbineResourceService
{
    /**
     * 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 new Boolean(interpolate(getConfiguration().getString(name))).booleanValue();
    }

    /**
     * The purppose of this method is to get the configuration
     * resource with the given name as a boolean value, or a default
     * 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)
    {

        String temp = interpolate(getConfiguration().getString(name));
        return temp != null ? new Boolean(temp).booleanValue() : 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 new Double(interpolate(getConfiguration().getString(name))).doubleValue();
    }

    /**
     * The purpose of this method is to get the configuration resource
     * with the given name as a double, or a default value.
     *
     * @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)
    {

        String temp = interpolate(getConfiguration().getString(name));
        return temp != null ? new Double(temp).doubleValue() : 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 new Float(interpolate(getConfiguration().getString(name))).floatValue();
    }

    /**
     * The purpose of this method is to get the configuration resource
     * with the given name as a float, or a default value.
     *
     * @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)
    {

        String temp = interpolate(getConfiguration().getString(name));
        return temp != null ? new Float(temp).floatValue() : 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 an integer.
     */
    public int getInt(String name)
    {

        return new Integer(interpolate(getConfiguration().getString(name))).intValue();
    }

    /**
     * The purpose of this method is to get the configuration resource
     * with the given name as an integer, or a default value.
     *
     * @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)
    {

        String temp = interpolate(getConfiguration().getString(name));
        return temp != null ? new Integer(temp).intValue() : def;
    }

    /**
     * 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 new Long(interpolate(getConfiguration().getString(name))).longValue();
    }

    /**
     * The purpose of this method is to get the configuration resource
     * with the given name as a long, or a default value.
     *
     * @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)
    {

        String temp = interpolate(getConfiguration().getString(name));
        return temp != null ? new Long(temp).longValue() : def;
    }

    /**
     * The purpose of this method is to extract a subset of configuraton
     * resources sharing a common name prefix. The prefix is stripped
     * from the names of the resulting resources.
     *
     * @param prefix the common name prefix
     * @return A ResourceService providing the subset of configuration.
     */
    public ResourceService getResources(String prefix)
    {
        Configuration config = getConfiguration().subset(prefix);

        if (config == null)
        {
            return null;
        }

        JetspeedResourceService res = new JetspeedResourceService();
        try 
        {
            res.init(config);
        }
        catch (Exception e)
        {
            Log.error(e);
        }

        return (ResourceService) res;
    }

}
