/*  Copyright (c) 2001 by Oracle Corporation. All Rights Reserved. */

package oracle.portal.provider.v2;

import java.util.*;
import oracle.portal.provider.v2.Validateable;
import oracle.portal.provider.v2.utils.ValidationError;

/**
 * A ParameterDefinition is the definition of a parameter used either as an
 * input parameter to the portlet's renderer, or as a parameter passed out
 * of the portlet when an event is raised.
 *
 * As with Portlets, parameters have string elements which should be stored in
 * a resource bundle so that they are translated.  The following attributes can
 * be retrieved from a resource bundle: displayName and description If using a
 * resource bundle, be sure to set the key for lookup using setDisplayNameKey
 * and setDescriptionKey respectively.
 */
public class ParameterDefinition implements Validateable
{
    /**
     * mName stores the name for this parameter.
     */
    private String mName;

    /**
     * mDisplayName stores the display name for this parameter.
     */
    private String mDisplayName;

    /**
     * mDisplayNameKey stores the string value for the key used to look
     * up the parameter's display name in a resource bundle.
     */
    private String mDisplayNameKey;

    /**
     * mDescription stores the description for this parameter.
     */
    private String mDescription;

    /**
     * mDescriptionKey stores the string value for the key used to look
     * up the parameter's description in a resource bundle.
     */
    private String mDescriptionKey;

    /**
     * mResource stores a string of the resource location for this parameter.
     */
    private String mResource;

    /**
     * mBundle stores a cached ResourceBundle for this parameter.
     */
    private ResourceBundle mBundle;

    /**
     * mBundleLocale stores a cached Locale for mBundle
     */
    private Locale mBundleLocale;


    /**
     * Default constructor.
     */
    public ParameterDefinition()
    {
    }

    /**
     * Gets the resource bundle for this Portlet in the given Locale.
     *
     * @param l the Locale of the resource bundle being requested.
     * @return the resource bundle for this parameter.  <b>null</b> if
     * there isn't one.
     */
    public ResourceBundle getResourceBundle(Locale l)
    {
        if (mResource == null) return null;

        if (l == null)
        {
            l = Locale.getDefault();
        }

        if (mBundle == null || mBundleLocale == null || !l.equals(mBundleLocale))
        {
            // We have to use the the current thread's 'context class loader'
            // (i.e. the web app's class loader) to load the resource, so that
            // it can be picked up from within the web app
            mBundle = ResourceBundle.getBundle(mResource, l,
                                               Thread.currentThread().getContextClassLoader());
            mBundleLocale = l;
        }

        return mBundle;
    }

    /**
     * Sets the name of the default resource bundle class for this parameter
     *
     * @param resourceClassName full name of class extending {@link
     * java.util.ResourceBundle}.
     */
    public void setResource(String resourceClassName)
    {
        mResource = resourceClassName;
    }

    /**
     * @return String this parameter's name.
     */
    public String getName()
    {
        return mName;
    }

    /**
     * Sets the parameter's name.
     *
     * This name should be unique from any other parameters under the parent.
     * This name must also be a legal string that can be passed as 
     * a URL parameter to the portlet's renderer.
     *
     * @param name the parameter's name.
     */
    public void setName(String name)
    {
        mName = name;
    }

    /**
     * @return String this parameter's display name.
     */
    public String getDisplayName(Locale l)
    {
        if (mDisplayName != null)
        {
            return mDisplayName;
        }
        else
        {
            ResourceBundle b = getResourceBundle(l);
            if (b != null)
            {
                String key = getDisplayNameKey();

                if (key != null)
                {
                    // get string from bundle.
                    // If none present, null is returned.
                    try
                    {
                        return b.getString(key);
                    }
                    catch (MissingResourceException mre)
                    {
                    }
                }
            }
        }
        return null;
    }

    /**
     * Sets the parameter's display name.
     *
     * This is a short name used in the Portal UI.
     *
     * @param displayName a friendly name to be used in the Portal UI.
     */
    public void setDisplayName(String displayName)
    {
        mDisplayName = displayName;
    }

    /**
     * @return the key used to look up this parameter's display name from a
     * resource bundle.
     */
    public String getDisplayNameKey()
    {
        return mDisplayNameKey;
    }

    /**
     * Sets the parameter's display name key.
     *
     * @param displayNameKey the string value for the key used to look up 
     * the parameter's display name in a resource bundle.
     */
    public void setDisplayNameKey(String displayNameKey)
    {
        mDisplayNameKey = displayNameKey;
    }

    /**
     * @return String this parameter's description .
     */
    public String getDescription(Locale l)
    {
        if (mDescription != null)
        {
            return mDescription;
        }
        else
        {
            ResourceBundle b = getResourceBundle(l);
            if (b != null)
            {
                String key = getDescriptionKey();

                if (key != null)
                {
                    // get string from bundle.
                    // If none present, null is returned.
                    try
                    {
                        return b.getString(key);
                    }
                    catch (MissingResourceException mre)
                    {
                    }
                }
            }
        }
        return null;
    }

    /**
     * Sets the parameter's description.
     *
     * This is displayed in the Portal UI to give the page designer 
     * a better idea of what it will be used for.
     *
     * @param description a short description of what this parameter is.
     */
    public void setDescription(String description)
    {
        mDescription = description;
    }

    /**
     * @return the key used to look up this parameter's description from a
     * resource bundle.
     */
    public String getDescriptionKey()
    {
        return mDescriptionKey;
    }

    /**
     * Sets the parameter's description key.
     *
     * @param descriptionKey the string value for the key used to look up 
     * the parameter's description in a resource bundle.
     */
    public void setDescriptionKey(String descriptionKey)
    {
        mDescriptionKey = descriptionKey;
    }

    /**
     * Validates the internal state of this <code>ParameterDefinition</code>
     * instance. Errors found are reported using the supplied {@link
     * oracle.portal.provider.v2.utils.ValidationError} instance.
     *
     * @param context The context of the calling instance.
     * @param errors The current list of errors.
     */
    public void validate(String context, ValidationError errors)
    {
        String ctx = ValidationError.newContext(context, "ParameterDefinition",
                                                mName);
        // Check the validity of the member variables
        if( mName == null || mName.length() == 0 )
        {
            errors.addError(ctx, "name must not be null", null);
        }
    }
}
