Subversion Repositories bacoAlunos

Rev

Rev 1814 | Blame | Compare with Previous | Last modification | View Log | RSS feed

package pt.estgp.estgweb.domain.utils;

import org.apache.log4j.Logger;
import org.apache.struts.util.PropertyMessageResources;
import pt.estgp.estgweb.web.filters.UserRoleProxy;

import java.io.File;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.Locale;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Automatisch neu ladbare MessageResources.
 *
 * @author boeckmic
 * @since Mar 26, 2008
 */

public class ReloadablePropertyMessageResources extends PropertyMessageResources {

    private static final long serialVersionUID = 4344652868862075298L;

    private final 1.5.0/docs/api/java/util/logging/Logger.html">Logger logger = 1.5.0/docs/api/java/util/logging/Logger.html">Logger.getLogger(ReloadablePropertyMessageResources.class);

    /** The last time the file was checked for changes. */
    protected long lastChecked;

    /** The minimum delay in milliseconds between checks. */
    protected long refreshDelay = DEFAULT_REFRESH_DELAY;

    /** Constant for the default refresh delay. */
    private static final int DEFAULT_REFRESH_DELAY = 5000;

    private final ConcurrentHashMap<String, File> fileMap = new ConcurrentHashMap<String, File>();

    private final ConcurrentHashMap<File, Long> timestampMap = new ConcurrentHashMap<File, Long>();

    /**
     * Konstruktor aus Superklasse.
     *
     * @param factory Factory
     * @param config Name der Konfigurationsdatei
     */

    public ReloadablePropertyMessageResources(
            final ReloadablePropertyMessageResourcesFactory factory, final 1.5.0/docs/api/java/lang/String.html">String config) {
        super(factory, config);
    }

    /**
     * Konstruktor aus Superklasse.
     *
     * @param factory Factory
     * @param config Name der Konfigurationsdatei
     * @param returnNull Fehler werfen bei nicht vorhandenem Key?
     */

    public ReloadablePropertyMessageResources(
            final ReloadablePropertyMessageResourcesFactory factory, final 1.5.0/docs/api/java/lang/String.html">String config,
            final boolean returnNull) {
        super(factory, config, returnNull);
    }

    /**
     * Pr�ft ob ein Reload der Properties notwendig ist.
     *
     * {@inheritDoc}
     *
     * @see org.apache.struts.util.PropertyMessageResources#getMessage(java.util.Locale,
     *      java.lang.String)
     */

    @1.5.0/docs/api/java/lang/Override.html">Override
    public 1.5.0/docs/api/java/lang/String.html">String getMessage(final 1.5.0/docs/api/java/util/Locale.html">Locale locale, final 1.5.0/docs/api/java/lang/String.html">String key) {
        reload(locale);
        if(key == null || key.length() == 0)
        {
            return "CHAVE MSG EM FALTA";
        }
        else if(key.startsWith("user.role."))
        {
            logger.debug("BACO ROLES:Getting role from UserRoleProxy" + key);
            1.5.0/docs/api/java/lang/String.html">String msg = UserRoleProxy.getMessage(key.substring("user.role.".length()),locale);
            if(msg == null)
                return key;
            return msg;
        }

        return super.getMessage(locale, key);
    }

    /**
     * Pr�ft ob ein Reload der Properties notwendig ist.
     *
     * {@inheritDoc}
     *
     * @see org.apache.struts.util.MessageResources#getMessage(java.util.Locale, java.lang.String,
     *      java.lang.Object[])
     */

    @1.5.0/docs/api/java/lang/Override.html">Override
    public 1.5.0/docs/api/java/lang/String.html">String getMessage(final 1.5.0/docs/api/java/util/Locale.html">Locale locale, final 1.5.0/docs/api/java/lang/String.html">String key, final 5+0%2Fdocs%2Fapi+Object">Object[] args) {
        reload(locale);

        if(key == null || key.length() == 0)
        {
            return "CHAVE MSG EM FALTA";
        }
        else if(key.startsWith("user.role."))
        {
            logger.debug("BACO ROLES:Getting role from UserRoleProxy" + key);
            1.5.0/docs/api/java/lang/String.html">String msg = UserRoleProxy.getMessage(key.substring("user.role.".length()),locale);
            if(msg == null)
                return key;
            return msg;
        }
        return super.getMessage(locale, key, args);
    }

    /**
     * Das Resetten der Maps f�hrt zum reload der Properties.
     *
     * @param locale Locale
     */

    public synchronized void reload(final 1.5.0/docs/api/java/util/Locale.html">Locale locale) {
        if (reloadingRequired(locale)) {
            logger.info("Reloading resources " + getFilename(locale));

            locales.clear();
            messages.clear();
            formats.clear();
        }
    }

    /**
     * Pr�ft ob es notwendig ist die Properties neu zu laden. Pr�ft nur nach Ablauf des
     * {@link #refreshDelay}, um eine �berm��ige Beanspruchung des Dateisystems zu vermeiden.
     *
     * @param locale Locale
     * @return <code>true</code> falls neu geladen werden muss
     */

    public boolean reloadingRequired(final 1.5.0/docs/api/java/util/Locale.html">Locale locale) {
        boolean reloading = false;

        long now = 1.5.0/docs/api/java/lang/System.html">System.currentTimeMillis();

        if (now > lastChecked + refreshDelay) {
            lastChecked = now;
            if (hasChanged(locale)) {
                reloading = true;
            }
        }

        return reloading;
    }

    /**
     * Pr�ft ob sich die Konfiguration seit dem letzten Aufruf ge�ndert hat.
     *
     * @param locale Locale
     * @return <code>true</code> falls sich die Datei ge�ndert hat
     */

    protected boolean hasChanged(final 1.5.0/docs/api/java/util/Locale.html">Locale locale) {
        1.5.0/docs/api/java/io/File.html">File file = getFile(locale);

        if (file == null || !file.exists()) {
            return false;
        }

        1.5.0/docs/api/java/lang/Long.html">Long timestamp = timestampMap.get(file);
        if (timestamp == null) {
            timestampMap.putIfAbsent(file, 1.5.0/docs/api/java/lang/Long.html">Long.valueOf(file.lastModified()));
            return false;
        }

        if (file.lastModified() > timestamp.longValue()) {
            timestampMap.put(file, 1.5.0/docs/api/java/lang/Long.html">Long.valueOf(file.lastModified()));
            return true;
        }

        return false;
    }

    /**
     * Gibt die Datei zur Locale zur�ck.
     *
     * @param locale Locale
     * @return (gecachte) File
     */

    private 1.5.0/docs/api/java/io/File.html">File getFile(final 1.5.0/docs/api/java/util/Locale.html">Locale locale) {

        1.5.0/docs/api/java/lang/String.html">String filename = getFilename(locale);

        1.5.0/docs/api/java/io/File.html">File f = fileMap.get(filename);
        if (f == null) {
            1.5.0/docs/api/java/lang/ClassLoader.html">ClassLoader classLoader = 1.5.0/docs/api/java/lang/Thread.html">Thread.currentThread().getContextClassLoader();
            if (classLoader == null) {
                classLoader = getClass().getClassLoader();
            }

            1.5.0/docs/api/java/net/URL.html">URL fileUrl = classLoader.getResource(filename);

// no bundle for this locale found, so try default bundle
            if (fileUrl == null) {
                fileUrl = classLoader.getResource(getFilename(null));
            }

            try {
                try {
                    f = new 1.5.0/docs/api/java/io/File.html">File(fileUrl.toURI());
                } catch (1.5.0/docs/api/java/net/URISyntaxException.html">URISyntaxException ex) {
                    logger.error(ex,ex);
                } catch (1.5.0/docs/api/java/lang/IllegalArgumentException.html">IllegalArgumentException ex) {


                    try {
                        1.5.0/docs/api/java/lang/System.html">System.out.println("Decoding from fileUrl.getFile");
                        f = new 1.5.0/docs/api/java/io/File.html">File(1.5.0/docs/api/java/net/URLDecoder.html">URLDecoder.decode(fileUrl.getFile(), "UTF-8"));
                        1.5.0/docs/api/java/lang/System.html">System.out.println(f.getAbsolutePath());
                    } catch (1.5.0/docs/api/java/lang/Exception.html">Exception ex2) {
                        logger.error(ex2,ex2);
                    }
                }
            }catch (1.5.0/docs/api/java/lang/Throwable.html">Throwable e) {
                    throw new 1.5.0/docs/api/java/lang/IllegalArgumentException.html">IllegalArgumentException("The properties file "
                            + fileUrl.toExternalForm() + " could not be loaded.", e);
            }
            fileMap.putIfAbsent(filename, f);
        }

        return f;
    }

    /**
     * Berechnet den Dateinamen f�r die Locale.
     *
     * @param locale Locale
     * @return Dateinamen
     */

    private 1.5.0/docs/api/java/lang/String.html">String getFilename(final 1.5.0/docs/api/java/util/Locale.html">Locale locale) {
        1.5.0/docs/api/java/lang/String.html">String name = config.replace('.', '/');
        1.5.0/docs/api/java/lang/String.html">String localeKey = "";

        if (locale != null) {
            localeKey = locale.toString();
            int underscore = localeKey.lastIndexOf("_");
            if (underscore > 0) {
                localeKey = localeKey.substring(0, underscore);
            }
        }

        if (localeKey.length() > 0) {
            name = name + "_" + localeKey;
        }

        return name + ".properties";
    }

}