org.xwiki.localization.jar.internal.RootClassLoaderTranslationBundle.java Source code

Java tutorial

Introduction

Here is the source code for org.xwiki.localization.jar.internal.RootClassLoaderTranslationBundle.java

Source

/*
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.xwiki.localization.jar.internal;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Enumeration;
import java.util.List;
import java.util.ListIterator;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;

import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;

import org.apache.commons.collections.EnumerationUtils;
import org.xwiki.component.annotation.Component;
import org.xwiki.localization.TranslationBundleContext;
import org.xwiki.localization.internal.AbstractCachedTranslationBundle;
import org.xwiki.localization.internal.DefaultLocalizedTranslationBundle;
import org.xwiki.localization.internal.DefaultTranslation;
import org.xwiki.localization.internal.LocalizedTranslationBundle;
import org.xwiki.localization.message.TranslationMessage;
import org.xwiki.localization.message.TranslationMessageParser;

/**
 * Provide translations coming from the root {@link ClassLoader}.
 * 
 * @version $Id: ceecec30802ef07676521733b4576d26d9836d95 $
 * @since 4.5M1
 */
@Component
@Named("rootclassloader")
@Singleton
public class RootClassLoaderTranslationBundle extends AbstractCachedTranslationBundle {
    /**
     * The parser to use for each message.
     */
    @Inject
    @Named("messagetool/1.0")
    private TranslationMessageParser parser;

    /**
     * Used to access the current bundles.
     */
    @Inject
    private TranslationBundleContext bundleContext;

    @Override
    protected LocalizedTranslationBundle createBundle(Locale locale) {
        Properties properties = getResourceProperties(locale);

        if (properties == null) {
            return LocalizedTranslationBundle.EMPTY;
        }

        // Convert to LocalBundle
        DefaultLocalizedTranslationBundle localeBundle = new DefaultLocalizedTranslationBundle(this, locale);

        for (Map.Entry<Object, Object> entry : properties.entrySet()) {
            if (entry.getKey() instanceof String && entry.getValue() instanceof String) {
                String key = (String) entry.getKey();
                String message = (String) entry.getValue();

                TranslationMessage translationMessage = this.parser.parse(message);

                localeBundle.addTranslation(
                        new DefaultTranslation(this.bundleContext, localeBundle, key, translationMessage));
            }
        }

        return localeBundle;
    }

    /**
     * @param locale the locale to search for
     * @return the content of all the resources files associated to the provided locale
     */
    private Properties getResourceProperties(Locale locale) {
        String resourceName = "ApplicationResources";
        if (!locale.equals(Locale.ROOT)) {
            resourceName += "_" + locale;
        }
        resourceName += ".properties";

        Enumeration<URL> urls;
        try {
            urls = getClass().getClassLoader().getResources(resourceName);
        } catch (IOException e) {
            this.logger.error("Failed to get resource URLs from class loader for name [{}]", resourceName, e);

            return null;
        }

        if (!urls.hasMoreElements()) {
            return null;
        }

        List<URL> urlList = EnumerationUtils.toList(urls);

        Properties properties = new Properties();

        // Load resources in reverse order to give priority to first found resources (follow ClassLoader#getResource
        // behavior)
        for (ListIterator<URL> it = urlList.listIterator(urlList.size()); it.hasPrevious();) {
            URL url = it.previous();

            try {
                InputStream componentListStream = url.openStream();

                try {
                    properties.load(componentListStream);
                } finally {
                    componentListStream.close();
                }
            } catch (IOException e) {
                this.logger.error("Failed to parse resource [{}] as translation budle", url, e);
            }
        }

        return properties;
    }
}