/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.el.util;

import java.text.Format;
import java.text.MessageFormat;
import java.text.NumberFormat;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

/**
 * Factory for creating localized EL messages.
 */
public final class MessageFactory {

    private static final ResourceBundle DEFAULT_BUNDLE = ResourceBundle.getBundle("org.apache.el.LocalStrings");

    private static final MessageFactory DEFAULT_MESSAGE_FACTORY = new MessageFactory(DEFAULT_BUNDLE);

    /**
     * Get a localized message.
     * @param key the message key
     * @return the message
     */
    public static String get(final String key) {
        return DEFAULT_MESSAGE_FACTORY.getInternal(key);
    }

    /**
     * Get a localized message with arguments.
     * @param key the message key
     * @param args the arguments
     * @return the message
     */
    public static String get(final String key, final Object... args) {
        return DEFAULT_MESSAGE_FACTORY.getInternal(key, args);
    }

    private final ResourceBundle bundle;

    /**
     * Constructor.
     * @param bundle the resource bundle
     */
    public MessageFactory(ResourceBundle bundle) {
        this.bundle = bundle;
    }

    /**
     * Get a message from the bundle.
     * @param key the message key
     * @return the message
     */
    protected String getInternal(final String key) {
        try {
            return bundle.getString(key);
        } catch (MissingResourceException e) {
            return key;
        }
    }

    /**
     * Get a message from the bundle with arguments.
     * @param key the message key
     * @param args the arguments
     * @return the message
     */
    protected String getInternal(final String key, final Object... args) {
        String value = getInternal(key);

        MessageFormat mf = new MessageFormat(value);
        Format[] formats = null;

        // Unless an argument has been explicitly configured to use a number
        // format, convert all Number arguments to String else MessageFormat may
        // try to format them in unexpected ways.
        if (args != null) {
            for (int i = 0; i < args.length; i++) {
                if (args[i] instanceof Number) {
                    if (formats == null) {
                        formats = mf.getFormatsByArgumentIndex();
                    }
                    if (i < formats.length && !(formats[i] instanceof NumberFormat)) {
                        args[i] = args[i].toString();
                    }
                }
            }
        }

        return mf.format(args, new StringBuffer(), null).toString();
    }
}
