package com.atlassian.sal.jira.message;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.apache.log4j.Logger;

import com.atlassian.jira.security.JiraAuthenticationContext;
import com.atlassian.jira.web.bean.I18nBean;
import com.atlassian.plugin.ModuleDescriptor;
import com.atlassian.plugin.Plugin;
import com.atlassian.plugin.PluginAccessor;
import com.atlassian.plugin.elements.ResourceDescriptor;
import com.atlassian.sal.core.message.AbstractI18nResolver;

/**
 * A JIRA I18nResolver.  Uses the user's locale if a user is logged in or the default
 * locale if none can be found.
 */
public class JiraI18nResolver extends AbstractI18nResolver
{
	private static final Logger log = Logger.getLogger(JiraI18nResolver.class);
    private final JiraAuthenticationContext jiraAuthenticationContext;
    private final PluginAccessor pluginAccessor;
    private final List<String> pluginResources;

    public JiraI18nResolver(JiraAuthenticationContext jiraAuthenticationContext, PluginAccessor pluginAccessor)
    {
        this.jiraAuthenticationContext = jiraAuthenticationContext;
        this.pluginAccessor = pluginAccessor;
        this.pluginResources =  initPluginI18NResources();
    }

    private I18nBean getI18nBean()
    {
        return new I18nBean(jiraAuthenticationContext.getUser())
        {
            public List getI18nLocations()
            {
                return pluginResources;
            }
        };
    }

    public String resolveText(String key, Serializable[] arguments)
    {
        return getI18nBean().getText(key, arguments);
    }

    // Stolen from Confluence :)
    // load all i18n resources declared inside plugin descriptor files (that is, atlassian-plugin.xml)
    private List<String> initPluginI18NResources()
    {
		//lazy load this, as the list will never change.
    	List<String> list = new ArrayList<String>();
    	list.addAll(new I18nBean().getI18nLocations());
		// find all i18n resource descriptors
		Set<String> i18nResourceDescriptors = new HashSet<String>();
		for (Iterator i = pluginAccessor.getEnabledPlugins().iterator(); i.hasNext();)
		{
			Plugin plugin = (Plugin) i.next();
			try
			{
				// first locate i18n resources declared in the plugin scope
				for (Iterator j = plugin.getResourceDescriptors("i18n").iterator(); j.hasNext();)
				{
					ResourceDescriptor resourceDescriptor = (ResourceDescriptor) j.next();
					i18nResourceDescriptors.add(resourceDescriptor.getLocation());
				}

				// then locate i18n resources declared within plugin modules
				for (Iterator iterator = plugin.getModuleDescriptors().iterator(); iterator.hasNext();)
				{
					ModuleDescriptor moduleDescriptor = (ModuleDescriptor) iterator.next();
					for (Iterator iterator1 = moduleDescriptor.getResourceDescriptors("i18n").iterator(); iterator1
							.hasNext();)
					{
						ResourceDescriptor resourceDescriptor = (ResourceDescriptor) iterator1.next();
						i18nResourceDescriptors.add(resourceDescriptor.getLocation());
					}
				}
			} catch (Exception e)
			{
				log.error("Unable to load i18n resources for: " + plugin.getName() + "(" + plugin.getKey()
						+ ") " + e.toString(), e);
			}
		}

		list.addAll(i18nResourceDescriptors);
		return list;
    }
}

@@ -38,197 +38,8 @@
 e;%0A%0A
-import java.io.Serializable;%0Aimport java.util.ArrayList;%0Aimport java.util.HashSet;%0Aimport java.util.Iterator;%0Aimport java.util.List;%0Aimport java.util.Set;%0A%0Aimport org.apache.log4j.Logger;%0A%0A
 impo
@@ -169,30 +169,28 @@
 .plugin.
-ModuleDescript
+PluginAccess
 or;%0Aimpo
@@ -210,182 +210,107 @@
 ian.
-plugin.Plugin;%0Aimport com.atlassian.plugin.PluginAccessor;%0Aimport com.atlassian.plugin.elements.ResourceDescripto
+sal.core.message.AbstractI18nResolver;%0Aimport org.apache.log4j.Logge
 r;%0A
+%0A
 import 
-com.atlassian.sal.core.message.AbstractI18nResolver
+java.io.Serializable
 ;%0A%0A/
@@ -695,56 +695,8 @@
 sor;
-%0A    private final List%3CString%3E pluginResources;
 %0A%0A  
@@ -929,67 +929,8 @@
 or;%0A
-        this.pluginResources =  initPluginI18NResources();%0A
     
@@ -1064,36 +1064,72 @@
     
-public List getI18nLocations
+@Override%0A            protected PluginAccessor getPluginAccessor
 ()%0A 
@@ -1170,25 +1170,24 @@
 n plugin
-Resources
+Accessor
 ;%0A      
@@ -1298,1709 +1298,226 @@
     
-return getI18nBean().getText(key, arguments);%0A    %7D%0A%0A    // Stolen from Confluence :)%0A    // load all i18n resources declared inside plugin descriptor files (that is, atlassian-plugin.xml)%0A    private List%3CString%3E initPluginI18NResources()%0A    %7B%0A%09%09//lazy load this, as the list will never change.%0A    %09List%3CString%3E list = new ArrayList%3CString%3E();%0A    %09list.addAll(new I18nBean().getI18nLocations());%0A%09%09// find all i18n resource descriptors%0A%09%09Set%3CString%3E i18nResourceDescriptors = new HashSet%3CString%3E();%0A%09%09for (Iterator i = pluginAccessor.getEnabledPlugins().iterator(); i.hasNext();)%0A%09%09%7B%0A%09%09%09Plugin plugin = (Plugin) i.next();%0A%09%09%09try%0A%09%09%09%7B%0A%09%09%09%09// first locate i18n resources declared in the plugin scope%0A%09%09%09%09for (Iterator j = plugin.getResourceDescriptors(%22i18n%22).iterator(); j.hasNext();)%0A%09%09%09%09%7B%0A%09%09%09%09%09ResourceDescriptor resourceDescriptor = (ResourceDescriptor) j.next();%0A%09%09%09%09%09i18nResourceDescriptors.add(resourceDescriptor.getLocation());%0A%09%09%09%09%7D%0A%0A%09%09%09%09// then locate i18n resources declared within plugin modules%0A%09%09%09%09for (Iterator iterator = plugin.getModuleDescriptors().iterator(); iterator.hasNext();)%0A%09%09%09%09%7B%0A%09%09%09%09%09ModuleDescriptor moduleDescriptor = (ModuleDescriptor) iterator.next();%0A%09%09%09%09%09for (Iterator iterator1 = moduleDescriptor.getResourceDescriptors(%22i18n%22).iterator(); iterator1%0A%09%09%09%09%09%09%09.hasNext();)%0A%09%09%09%09%09%7B%0A%09%09%09%09%09%09ResourceDescriptor resourceDescriptor = (ResourceDescriptor) iterator1.next();%0A%09%09%09%09%09%09i18nResourceDescriptors.add(resourceDescriptor.getLocation());%0A%09%09%09%09%09%7D%0A%09%09%09%09%7D%0A%09%09%09%7D catch (Exception e)%0A%09%09%09%7B%0A%09%09%09%09log.error(%22Unable to load i18n resources for: %22 + plugin.getName() + %22(%22 + plugin.getKey()%0A%09%09%09%09%09%09+ %22) %22 + e.toString(), e);%0A%09%09%09%7D%0A%09%09%7D%0A%0A%09%09list.addAll(i18nResourceDescriptors);%0A%09%09return list
+// TODO: this is creating a new i18n bean for each call. this is suboptimal. need to do some kind of %0A        // profiling/benchmarking to see if this is acceptable.%0A        return getI18nBean().getText(key, arguments)
 ;%0A  

update to using new JIRA I18n bean