All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.nuiton.i18n.I18nUtil Maven / Gradle / Ivy

There is a newer version: 4.2
Show newest version
/*
 * #%L
 * I18n :: Api
 * 
 * $Id$
 * $HeadURL$
 * %%
 * Copyright (C) 2004 - 2010 CodeLutin
 * %%
 * This program 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 3 of the 
 * License, or (at your option) any later version.
 * 
 * This program 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 General Lesser Public License for more details.
 * 
 * You should have received a copy of the GNU General Lesser Public 
 * License along with this program.  If not, see
 * .
 * #L%
 */

package org.nuiton.i18n;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuiton.converter.LocaleConverter;
import org.nuiton.i18n.format.I18nMessageFormatter;
import org.nuiton.i18n.format.StringFormatI18nMessageFormatter;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Stack;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import java.util.zip.ZipFile;

/** @author Tony Chemit - [email protected] */
public class I18nUtil {

    /** Logger. */
    private static final Log log = LogFactory.getLog(I18nUtil.class);

    public static final String ISO_8859_1_ENCONDING = "ISO-8859-1";

    public static final String UTF_8_ENCONDING = "UTF-8";

    public static final String DEFAULT_ENCODING = UTF_8_ENCONDING;

    public static final Charset DEFAULT_CHARSET =
            Charset.forName(DEFAULT_ENCODING);

    public static final I18nMessageFormatter DEFAULT_MESSAGE_FORMATTER =
            new StringFormatI18nMessageFormatter();

    public static final Locale DEFAULT_LOCALE = Locale.UK;

    public static final String[] EMPTY_STRING_ARRAY = new String[0];
    public static final LocaleConverter LOCALE_CONVERTER = new LocaleConverter();

    /**
     * Parse a list of {@link Locale} seperated by comma.
     *
     * Example : fr_FR,en_GB
     *
     * @param str the string representation of locale separated by comma
     * @return list of available locales
     * @throws IllegalArgumentException ia a locale is not valid
     */
    public static Locale[] parseLocales(String str) throws IllegalArgumentException {
        List result = new ArrayList();
        String[] bundlesToUse = str.split(",");
        for (int i = 0, j = bundlesToUse.length; i < j; i++) {
            String s = bundlesToUse[i].trim();
            // on devrait verifier que le bundle existe
            try {
                Locale l = LOCALE_CONVERTER.valueOf(s);
                result.add(l);
            } catch (Exception e) {
                throw new IllegalArgumentException("bundle " + s +
                                                   " is not a valid locale", e);
            }
        }
        return result.toArray(new Locale[result.size()]);
    }

    public static Locale newLocale(String str) {
        if (str == null) {

            // get user locale
            return newLocale(null, null);
        }
        try {
            return LOCALE_CONVERTER.valueOf(str);
        } catch (Exception e) {
            if (log.isWarnEnabled()) {
                log.warn("could not load locale '" + str +
                         " for reason : " + e.getMessage());
            }

            // use default locale
            return DEFAULT_LOCALE;
        }
    }

    public static Locale newLocale(String language, String country) {
        if (language == null) {

            // get user locale
            language = System.getProperty("user.language",
                                          DEFAULT_LOCALE.getLanguage());
            country = System.getProperty("user.country",
                                         DEFAULT_LOCALE.getCountry());
        }
        return newLocale(language + (country == null ? "" : '_' + country));
    }

    /**
     * Test if an url contains the given directory with no recurse seeking.
     *
     * @param url       the url to seek
     * @param directory the directory to find
     * @return {@code true} if directory was found, {@code false} otherwise.
     * @throws IOException if any io pb
     */
    public static boolean containsDirectDirectory(URL url, String directory)
            throws IOException {
        String fileName = url.getFile();
        // TODO deal with encoding in windows, this is very durty,
        // TODO but it works...
        File file = new File(fileName.replaceAll("%20", " "));
        if (!file.exists()) {
            return false;
        }
        if (isJar(fileName) || isZip(fileName)) {
            // cas ou le fichier du classLoader est un fichier jar ou zip
            if (log.isTraceEnabled()) {
                log.trace("zip to search " + file);
            }
            return new ZipFile(file).getEntry(directory + "/") != null;
        }
        if (file.isDirectory()) {
            // cas ou le ichier du classLoader est un repertoire
            if (log.isTraceEnabled()) {
                log.trace("directory to search " + file);
            }
            return new File(file, directory).exists();
        }

        if (log.isWarnEnabled()) {
            log.warn("unknown resource type " + url);
        }
        return false;
    }

    /**
     * Verifie si le fichier est un fichier jar.
     *
     * @param name nom du fichier a tester
     * @return vrai si le fichier se termine par .jar faux sinon
     */
    static public boolean isJar(String name) {
        if (name != null && name.length() > 4) {
            String ext = name.substring(name.length() - 4, name.length());
            return ".jar".equalsIgnoreCase(ext);
        }
        return false;
    }

    /**
     * Verifie si le fichier est un fichier zip
     *
     * @param name nom du fichier a tester
     * @return vrai si le fichier se termine par .zip faux sinon
     */
    static public boolean isZip(String name) {
        if (name != null && name.length() > 4) {
            String ext = name.substring(name.length() - 4, name.length());
            return ".zip".equalsIgnoreCase(ext);
        }
        return false;
    }

    /**
     * Retourne la liste des fichiers correspondant au pattern donne, aucun
     * ordre ne doit être supposé sur les fichiers.
     *
     * @param repository repertoire dans lequel on recherche les fichiers
     * @param pattern    le nom du fichier a extraire du fichier du repertoire
     *                   doit correspondre au pattern (repertoire + nom
     *                   compris). si le pattern est null, tous les fichiers
     *                   trouvé sont retourné.
     * @return la liste des urls correspondant au pattern
     */
    static public List getURLsFromDirectory(File repository,
                                                 String pattern) {
        try {
            if (log.isTraceEnabled()) {
                log.trace("search '" + pattern + "' in " + repository);
            }

            List urlList = new ArrayList();
            File[] filesList = repository.listFiles();

            if (filesList != null) {

                for (File file : filesList) {

                    String name = file.getAbsolutePath();

                    if (log.isTraceEnabled()) {
                        log.trace("directory: " + repository + " name: " +
                                  name);
                    }

                    // cas de recursivite : repertoire dans un repertoire
                    if (file.exists() && file.isDirectory()) {
                        urlList.addAll(getURLsFromDirectory(file,
                                                            pattern));
                        // si le fichier du repertoire n'est pas un repertoire
                        // on verifie s'il correspond au pattern
                    } else if (pattern == null || name.matches(pattern)) {
                        URL url = file.toURI().toURL();
                        if (log.isTraceEnabled()) {
                            log.trace("directory: " + repository + " url: " +
                                      url);
                        }
                        urlList.add(url);
                    }
                }
            }
            if (log.isTraceEnabled()) {
                log.trace("found with pattern '" + pattern + "' : " + urlList);
            }
            return urlList;
        } catch (MalformedURLException eee) {
            throw new IllegalArgumentException(
                    "Erreur lors de la conversion de l'url " + repository +
                    " (pattern " + pattern + ") " + eee.getMessage(), eee);
            //throw new ResourceException("Le fichier n'a pu être converti en URL", eee);
        }
    }

    /**
     * Returns the all urls to be used in a {@link URLClassLoader}.
     *
     * If classloader  has only one url and the url is a jar, try to load in
     * manifest class-path.
     *
     * @param loader the classloader (if null will use system one)
     * @return all the url found in the classloader
     */
    static public URL[] getDeepURLs(URLClassLoader loader) {
        Stack urlToTreate = new Stack();
        List urlTreated = new ArrayList();

        // first get the urls from classloader
        URL[] result = getURLs(loader);

        urlToTreate.addAll(Arrays.asList(result));
        while (!urlToTreate.isEmpty()) {
            URL currentUrl = urlToTreate.pop();
            // save the url
            urlTreated.add(currentUrl);
            if (isJar(currentUrl.toString())) {
                // jar invocation
                try {
                    URL[] newArrayURLs =
                            getClassPathURLsFromJarManifest(
                                    currentUrl);
                    if (newArrayURLs == null) {
                        continue;
                    }
                    List newURLs = Arrays.asList(newArrayURLs);
                    for (URL newURL : newURLs) {
                        if (!urlTreated.contains(newURL) &&
                            !urlToTreate.contains(newURL)) {
                            urlToTreate.add(newURL);
                        }
                    }
                } catch (Exception e) {
                    if (log.isDebugEnabled()) {
                        // this is not a such error, but some jar can not be
                        log.debug("error with url" + currentUrl +
                                  " for reason : " + e.getMessage());
                    }
                }
            }
        }
        return urlTreated.toArray(new URL[urlToTreate.size()]);
    }

    /**
     * Recupere la liste des urls d'un {@link URLClassLoader}.
     *
     * Note : Un cas particulier est positionné pour JBoss qui utilise la method
     * getAllURLs.
     *
     * @param classLoader le class loader a scanner
     * @return les urls du classloade.
     */
    static public URL[] getURLs(URLClassLoader classLoader) {
        if (classLoader == null) {
            classLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
        }
        Method m;
        try {
            // Essai de récupération de la méthode getAllURLs() de
            // RepositoryClassLoader (JBoss)
            m = classLoader.getClass().getMethod("getAllURLs");
        } catch (Exception e) {
            m = null;
        }
        URL[] result;
        if (m == null) {
            result = classLoader.getURLs();
        } else {
            try {
                result = (URL[]) m.invoke(classLoader);
            } catch (Exception e) {
                throw new IllegalStateException(e);
            }
        }
        return result;
    }

    static public URL[] getClassPathURLsFromJarManifest(URL jarURL)
            throws IOException, URISyntaxException {
        JarFile jar = null;
        URL[] result;
        try {
            String jarPath = jarURL.toURI().getPath();
            File jarFile = new File(jarPath);
            if (log.isDebugEnabled()) {
                log.debug("class-path jar to scan " + jarPath);
            }
            jar = new JarFile(jarFile);
            File container = jarFile.getParentFile();
            Manifest mf = jar.getManifest();
            String classPath = null;
            if (mf != null && mf.getMainAttributes() != null) {
                classPath = mf.getMainAttributes().getValue(Attributes.Name.CLASS_PATH);
            }
            String[] paths;
            if (classPath != null) {
                paths = classPath.split(" ");
            } else {
                paths = EMPTY_STRING_ARRAY;
            }
            result = new URL[paths.length + 1];
            result[0] = jarURL;
            File path;
            for (int i = 0; i < paths.length; i++) {
                String s = paths[i];
                // test de l'existence d'un protocole dans le path (genre file:...)
                if (s.indexOf(':') != -1) {
                    result[i + 1] = new URL(s);
                    continue;
                }

                if (s.startsWith(".") || !s.startsWith("/")) {
                    // relative url
                    path = new File(container, s);
                } else {
                    path = new File(s);
                }
                if (log.isDebugEnabled()) {
                    log.debug(path);
                }
                result[i + 1] = path.toURI().toURL();
            }
            jar.close();
        } finally {
            if (jar != null) {
                jar.close();
            }
        }
        return result;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy