org.apache.manifoldcf.core.i18n.Messages.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.manifoldcf.core.i18n.Messages.java

Source

/* $Id: Messages.java 1001023 2011-12-12 18:41:28Z hozawa $ */

/**
* 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.manifoldcf.core.i18n;

import java.text.MessageFormat;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.HashSet;
import java.util.Vector;

import java.io.InputStream;

import org.apache.manifoldcf.core.system.Logging;
import org.apache.manifoldcf.core.interfaces.ManifoldCFException;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.runtime.RuntimeConstants;

public class Messages {
    // Keep track of messages and bundles we've already complained about.

    protected static Set<BundleKey> bundleSet = new HashSet<BundleKey>();
    protected static Set<MessageKey> messageSet = new HashSet<MessageKey>();
    protected static Set<ResourceKey> resourceSet = new HashSet<ResourceKey>();

    /** Constructor - do no instantiate
    */
    protected Messages() {
    }

    /** Create and initialize a velocity engine instance, given a class.
    */
    public static VelocityEngine createVelocityEngine(Class classInstance) throws ManifoldCFException {
        VelocityEngine engine = new VelocityEngine();
        // Now configure it
        org.apache.commons.collections.ExtendedProperties configuration = new org.apache.commons.collections.ExtendedProperties();
        // This is the property that describes the id's of the resource loaders.
        configuration.setProperty(VelocityEngine.RESOURCE_LOADER, "mcf");
        // This is the property which describes the resource loader itself
        configuration.setProperty("mcf." + VelocityEngine.RESOURCE_LOADER + ".instance",
                new MCFVelocityResourceLoader(classInstance));
        engine.setExtendedProperties(configuration);
        engine.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS,
                "org.apache.velocity.runtime.log.Log4JLogChute");
        engine.setProperty("runtime.log.logsystem.log4j.logger", "velocity");
        return engine;
    }

    /** Read a resource as an input stream, given a class, path, locale, and resource key.
    */
    public static InputStream getResourceAsStream(Class classInstance, String pathName, Locale originalLocale,
            String resourceKey) throws ManifoldCFException {
        Locale locale = originalLocale;
        InputStream is = classInstance.getResourceAsStream(localizeResourceName(pathName, resourceKey, locale));
        if (is == null) {
            complainMissingResource(
                    "No resource in path '" + pathName + "' named '" + resourceKey + "' found for locale '"
                            + locale.toString() + "'",
                    new Exception("Resource not found"), pathName, locale, resourceKey);
            locale = new Locale(locale.getLanguage());
            is = classInstance.getResourceAsStream(localizeResourceName(pathName, resourceKey, locale));
            if (is == null) {
                complainMissingResource(
                        "No resource in path '" + pathName + "' named '" + resourceKey + "' found for locale '"
                                + locale.toString() + "'",
                        new Exception("Resource not found"), pathName, locale, resourceKey);
                locale = Locale.US;
                is = classInstance.getResourceAsStream(localizeResourceName(pathName, resourceKey, locale));
                if (is == null) {
                    complainMissingResource(
                            "No resource in path '" + pathName + "' named '" + resourceKey + "' found for locale '"
                                    + locale.toString() + "'",
                            new Exception("Resource not found"), pathName, locale, resourceKey);
                    locale = new Locale(locale.getLanguage());
                    is = classInstance.getResourceAsStream(localizeResourceName(pathName, resourceKey, locale));
                    if (is == null) {
                        complainMissingResource(
                                "No resource in path '" + pathName + "' named '" + resourceKey
                                        + "' found for locale '" + locale.toString() + "'",
                                new Exception("Resource not found"), pathName, locale, resourceKey);
                        is = classInstance.getResourceAsStream(localizeResourceName(pathName, resourceKey, null));
                        if (is == null)
                            throw new ManifoldCFException(
                                    "No matching language resource in path '" + pathName + "' named '" + resourceKey
                                            + "' found for locale '" + originalLocale.toString() + "'");
                    }
                }
            }
        }
        return is;
    }

    private static String localizeResourceName(String pathName, String resourceName, Locale locale) {
        // Path names temporarily disabled, since they don't work.
        // MHL
        if (locale == null)
            return /*pathName + "." + */resourceName;
        int dotIndex = resourceName.lastIndexOf(".");
        if (dotIndex == -1)
            return /*pathName + "." + */resourceName + "_" + locale.toString();
        return /*pathName + "." + */resourceName.substring(0, dotIndex) + "_" + locale.toString()
                + resourceName.substring(dotIndex);
    }

    /** Obtain a resource bundle given a class, bundle name, and locale.
    *@return null if the resource bundle could not be found.
    */
    public static ResourceBundle getResourceBundle(Class clazz, String bundleName, Locale locale) {
        ResourceBundle resources;
        ClassLoader classLoader = clazz.getClassLoader();
        try {
            resources = ResourceBundle.getBundle(bundleName, locale, classLoader);
        } catch (MissingResourceException e) {
            complainMissingBundle("Missing resource bundle '" + bundleName + "' for locale '" + locale.toString()
                    + "': " + e.getMessage() + "; trying " + locale.getLanguage(), e, bundleName, locale);
            // Try plain language next
            locale = new Locale(locale.getLanguage());
            try {
                resources = ResourceBundle.getBundle(bundleName, locale, classLoader);
            } catch (MissingResourceException e2) {
                // Use English if we don't have a bundle for the current locale
                complainMissingBundle("Missing resource bundle '" + bundleName + "' for locale '"
                        + locale.toString() + "': " + e2.getMessage() + "; trying en_US", e2, bundleName, locale);
                locale = Locale.US;
                try {
                    resources = ResourceBundle.getBundle(bundleName, locale, classLoader);
                } catch (MissingResourceException e3) {
                    complainMissingBundle("No backup en_US bundle found! " + e3.getMessage(), e3, bundleName,
                            locale);
                    locale = new Locale(locale.getLanguage());
                    try {
                        resources = ResourceBundle.getBundle(bundleName, locale, classLoader);
                    } catch (MissingResourceException e4) {
                        complainMissingBundle("No backup en bundle found! " + e4.getMessage(), e4, bundleName,
                                locale);
                        return null;
                    }
                }
            }
        }
        return resources;
    }

    /** Obtain a message given a resource bundle and message key.
    *@return null if the message could not be found.
    */
    public static String getMessage(Class clazz, String bundleName, Locale locale, String messageKey) {
        ResourceBundle resources = getResourceBundle(clazz, bundleName, locale);
        if (resources == null)
            return null;

        return getMessage(resources, bundleName, locale, messageKey);
    }

    /** Obtain a message given a resource bundle and message key.
    *@return null if the message could not be found.
    */
    public static String getMessage(ResourceBundle resources, String bundleName, Locale locale, String messageKey) {
        String message;
        try {
            return resources.getString(messageKey);
        } catch (MissingResourceException e) {
            complainMissingMessage("Missing resource '" + messageKey + "' in bundle '" + bundleName
                    + "' for locale '" + locale.toString() + "'", e, bundleName, locale, messageKey);
            return null;
        }
    }

    /** Obtain a string given a resource bundle and message key.
    */
    public static String getString(ResourceBundle resourceBundle, String bundleName, Locale locale,
            String messageKey) {
        return getString(resourceBundle, bundleName, locale, messageKey, null);
    }

    /** Obtain a string given a class, bundle, locale, message key, and arguments.
    */
    public static String getString(Class clazz, String bundleName, Locale locale, String messageKey,
            Object[] args) {
        String message = getMessage(clazz, bundleName, locale, messageKey);
        if (message == null)
            return messageKey;

        // Format the message
        String formatMessage;
        if (args != null) {
            MessageFormat fm = new MessageFormat(message);
            fm.setLocale(locale);
            formatMessage = fm.format(args);
        } else {
            formatMessage = message;
        }
        return formatMessage;
    }

    /** Obtain a string given a resource bundle, message key, and arguments.
    */
    public static String getString(ResourceBundle resourceBundle, String bundleName, Locale locale,
            String messageKey, Object[] args) {
        String message = getMessage(resourceBundle, bundleName, locale, messageKey);
        if (message == null)
            return messageKey;

        // Format the message
        String formatMessage;
        if (args != null) {
            MessageFormat fm = new MessageFormat(message);
            fm.setLocale(locale);
            formatMessage = fm.format(args);
        } else {
            formatMessage = message;
        }
        return formatMessage;

    }

    protected static void complainMissingBundle(String errorMessage, Throwable exception, String bundleName,
            Locale locale) {
        String localeName = locale.toString();
        BundleKey bk = new BundleKey(bundleName, localeName);
        synchronized (bundleSet) {
            if (bundleSet.contains(bk))
                return;
            bundleSet.add(bk);
        }
        logError(errorMessage, exception);
    }

    protected static void complainMissingMessage(String errorMessage, Throwable exception, String bundleName,
            Locale locale, String messageKey) {
        String localeName = locale.toString();
        MessageKey bk = new MessageKey(bundleName, localeName, messageKey);
        synchronized (messageSet) {
            if (messageSet.contains(bk))
                return;
            messageSet.add(bk);
        }
        logError(errorMessage, exception);
    }

    protected static void complainMissingResource(String errorMessage, Throwable exception, String pathName,
            Locale locale, String resourceKey) {
        String localeName = locale.toString();
        ResourceKey bk = new ResourceKey(pathName, localeName, resourceKey);
        synchronized (resourceSet) {
            if (resourceSet.contains(bk))
                return;
            resourceSet.add(bk);
        }
        logError(errorMessage, exception);
    }

    protected static void logError(String errorMessage, Throwable exception) {
        if (Logging.misc == null) {
            System.err.println(errorMessage);
            exception.printStackTrace(System.err);
        } else
            Logging.misc.error(errorMessage, exception);
    }

    /** Class to help keep track of the missing resource bundles we've already complained about,
    * so we don't fill up the standard out log with repetitive stuff. */
    protected static class BundleKey {
        protected String bundleName;
        protected String localeName;

        public BundleKey(String bundleName, String localeName) {
            this.bundleName = bundleName;
            this.localeName = localeName;
        }

        public int hashCode() {
            return bundleName.hashCode() + localeName.hashCode();
        }

        public boolean equals(Object o) {
            if (!(o instanceof BundleKey))
                return false;
            BundleKey b = (BundleKey) o;
            return b.bundleName.equals(bundleName) && b.localeName.equals(localeName);
        }
    }

    /** Class to help keep track of the missing messages we've already complained about,
    * so we don't fill up the standard out log with repetitive stuff. */
    protected static class MessageKey {
        protected String bundleName;
        protected String localeName;
        protected String messageKey;

        public MessageKey(String bundleName, String localeName, String messageKey) {
            this.bundleName = bundleName;
            this.localeName = localeName;
            this.messageKey = messageKey;
        }

        public int hashCode() {
            return bundleName.hashCode() + localeName.hashCode() + messageKey.hashCode();
        }

        public boolean equals(Object o) {
            if (!(o instanceof MessageKey))
                return false;
            MessageKey b = (MessageKey) o;
            return b.bundleName.equals(bundleName) && b.localeName.equals(localeName)
                    && b.messageKey.equals(messageKey);
        }
    }

    /** Class to help keep track of the missing resources we've already complained about,
    * so we don't fill up the standard out log with repetitive stuff. */
    protected static class ResourceKey {
        protected String pathName;
        protected String localeName;
        protected String resourceKey;

        public ResourceKey(String pathName, String localeName, String resourceKey) {
            this.pathName = pathName;
            this.localeName = localeName;
            this.resourceKey = resourceKey;
        }

        public int hashCode() {
            return pathName.hashCode() + localeName.hashCode() + resourceKey.hashCode();
        }

        public boolean equals(Object o) {
            if (!(o instanceof ResourceKey))
                return false;
            ResourceKey b = (ResourceKey) o;
            return b.pathName.equals(pathName) && b.localeName.equals(localeName)
                    && b.resourceKey.equals(resourceKey);
        }
    }

}