/*
 * $Id: VKCActionServlet.java,v 1.2 2004/09/20 10:21:05 koppy Exp $
 *
 * Copyright (c) Siemens AG 2008 
 *           (c) Universität Paderborn 2008 
 * Licensed under EUPL 1.1. 
 * 
 * Created on 02.08.2004
 *
 * $Log: VKCActionServlet.java,v $
 * Revision 1.2  2004/09/20 10:21:05  koppy
 * Setzen von WebShare.resources
 *
 * Revision 1.1  2004/08/30 14:47:31  koppy
 * ActionServlet für Struts, welched Message-ressourcen
 * verschiedener Struts-Module vereint und somit für
 * alle Struts-Module verfügbar macht.
 *
 */
package vkc.servlets;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Vector;

import javax.servlet.ServletException;

import org.apache.struts.action.ActionServlet;
import org.apache.struts.config.MessageResourcesConfig;
import org.apache.struts.config.ModuleConfig;
import org.apache.struts.util.PropertyMessageResources;

import vkc.view.WebShare;

/**
 * This class represents a custom ActionServlet
 * for using with Struts-framework.
 * 
 * @author Andreas Koop
 */
public class VKCActionServlet extends ActionServlet {

    private Map resources = new HashMap();
    private List resourceParameters = new Vector();
    
    /**
     * This method is called on the end of the action-servlets
     * init-routine. 
     * (non-Javadoc)
     * @see org.apache.struts.action.ActionServlet#destroyConfigDigester()
     */
    protected void destroyConfigDigester() {
        super.destroyConfigDigester();
        
        for (Iterator iter = resources.keySet().iterator(); iter.hasNext();) {
            String key = (String) iter.next();
            MessageResourcesConfig mrc = (MessageResourcesConfig)resources.get( key );
            
            VKCMessageResources resources = new VKCMessageResources(resourceParameters);
            resources.setReturnNull(mrc.getNull());
            getServletContext().setAttribute(key, resources);
        }
        
        WebShare.resources = new VKCMessageResources(resourceParameters);
    }
    
    
    /**
     * This method is called for every struts-module.
     * The idea behind this custom method is to enable the user of
     * message-resources across module-boundaries.
     * (non-Javadoc)
     * @see org.apache.struts.action.ActionServlet#initModuleMessageResources(org.apache.struts.config.ModuleConfig)
     */
    protected void initModuleMessageResources(ModuleConfig config)
            throws ServletException {
        
        MessageResourcesConfig mrcs[] = config.findMessageResourcesConfigs();
        for (int i = 0; i < mrcs.length; i++) {
            if (mrcs[i].getParameter() == null) {
                continue;
            }
            resources.put( mrcs[i].getKey() + config.getPrefix(), mrcs[i] );
            resourceParameters.add(mrcs[i].getParameter());
        }

    }
    
    public class VKCMessageResources extends PropertyMessageResources{
        
        private List configs = null;
        
        public VKCMessageResources(List configs ){
            super(null,null);
            this.configs = configs;
        }

        // ------------------------------------------------------ Protected Methods


        /**
         * Load the messages associated with the specified Locale key.  For this
         * implementation, the <code>config</code> property should contain a fully
         * qualified package and resource name, separated by periods, of a series
         * of property resources to be loaded from the class loader that created
         * this PropertyMessageResources instance.  This is exactly the same name
         * format you would use when utilizing the
         * <code>java.util.PropertyResourceBundle</code> class.
         *
         * @param localeKey Locale key for the messages to be retrieved
         */
        protected synchronized void loadLocale(String localeKey) {
            
            if (log.isTraceEnabled()) {
                log.trace("loadLocale(" + localeKey + ")");
            }
            
            // Have we already attempted to load messages for this locale?
            if (locales.get(localeKey) != null) {
                return;
            }
            
            locales.put(localeKey, localeKey);
            
            for (Iterator iter = configs.iterator(); iter.hasNext();) {
                String config = (String) iter.next();

                // Set up to load the property resource for this locale key, if we
                // can
                String name = config.replace('.', '/');
                if (localeKey.length() > 0) {
                    name += "_" + localeKey;
                }
                name += ".properties";
                InputStream is = null;
                Properties props = new Properties();

                // Load the specified property resource
                if (log.isTraceEnabled()) {
                    log.trace("  Loading resource '" + name + "'");
                }

                ClassLoader classLoader = Thread.currentThread()
                        .getContextClassLoader();
                if (classLoader == null) {
                    classLoader = this.getClass().getClassLoader();
                }

                is = classLoader.getResourceAsStream(name);
                if (is != null) {
                    try {
                        props.load(is);

                    } catch (IOException e) {
                        log.error("loadLocale()", e);
                    } finally {
                        try {
                            is.close();
                        } catch (IOException e) {
                            log.error("loadLocale()", e);
                        }
                    }
                }

                if (log.isTraceEnabled()) {
                    log.trace("  Loading resource completed");
                }

                // Copy the corresponding values into our cache
                if (props.size() < 1) {
                    return;
                }

                synchronized (messages) {
                    Iterator names = props.keySet().iterator();
                    while (names.hasNext()) {
                        String key = (String) names.next();
                        if (log.isTraceEnabled()) {
                            log.trace("  Saving message key '"
                                    + messageKey(localeKey, key));
                        }
                        messages.put(messageKey(localeKey, key), props
                                .getProperty(key));
                    }
                }
            }
        }

    }
}
