[Jsxe-cvs] SF.net SVN: jsxe: [989] trunk/jsxe
Status: Inactive
Brought to you by:
ian_lewis
From: <ian...@us...> - 2006-07-06 21:27:00
|
Revision: 989 Author: ian_lewis Date: 2006-07-06 14:26:48 -0700 (Thu, 06 Jul 2006) ViewCVS: http://svn.sourceforge.net/jsxe/?rev=989&view=rev Log Message: ----------- rewrote Messages Modified Paths: -------------- trunk/jsxe/Changelog trunk/jsxe/src/net/sourceforge/jsxe/JARClassLoader.java trunk/jsxe/src/net/sourceforge/jsxe/gui/Messages.java trunk/jsxe/src/net/sourceforge/jsxe/jsXe.java trunk/jsxe/src/net/sourceforge/jsxe/util/MiscUtilities.java Modified: trunk/jsxe/Changelog =================================================================== --- trunk/jsxe/Changelog 2006-07-06 16:51:38 UTC (rev 988) +++ trunk/jsxe/Changelog 2006-07-06 21:26:48 UTC (rev 989) @@ -1,3 +1,10 @@ +07/06/2006 Ian Lewis <Ian...@me...> + + * Rewrote the Messages class. Now it loads messages on demand and only + loads the messages that it needs but allows the Locale to be changed at + any time. Though this implementation is inefficient as it checks for + messages files in plugins every time a message is requested. + 06/27/2006 Ian Lewis <Ian...@me...> * Added the GUIUtilities class for handling utility functions in jsXe. Modified: trunk/jsxe/src/net/sourceforge/jsxe/JARClassLoader.java =================================================================== --- trunk/jsxe/src/net/sourceforge/jsxe/JARClassLoader.java 2006-07-06 16:51:38 UTC (rev 988) +++ trunk/jsxe/src/net/sourceforge/jsxe/JARClassLoader.java 2006-07-06 21:26:48 UTC (rev 989) @@ -191,7 +191,31 @@ return null; }//}}} - + + //{{{ getPluginResources() + /** + * Finds all resources matching the name in the jar files specified in the + * search path. The search path is specified by the + * {@link addJarFile(String)}, {@link addJarFile(File)}, and + * {@link addDirectory(String)} methods. + * @param name the name of the resources to find + */ + public Enumeration getPluginResources(String name) throws IOException { + return findResources(name); + }//}}} + + //{{{ getPluginResource() + /** + * Finds the first resource matching the name in the jar files specified + * in the search path. The search path is specified by the + * {@link addJarFile(String)}, {@link addJarFile(File)}, and + * {@link addDirectory(String)} methods. + * @param name the name of the resources to find + */ + public URL getPluginResource(String name) { + return findResource(name); + }//}}} + //}}} //{{{ addJarFile() @@ -703,22 +727,22 @@ checkDependencies(jarfile); //load the plugin's localized messages - Log.log(Log.NOTICE, this, "Loading localized messages for plugin: "+pluginName); - Properties pluginMessages = new Properties(); - try { - InputStream stream = jarfile.getInputStream(jarfile.getEntry("messages/messages.en")); - pluginMessages.load(stream); - Messages.loadPluginMessages(pluginMessages); - } catch (IOException e) { - Log.log(Log.WARNING, this, "Plugin "+pluginName+" does not have default messages.en"); - } - try { - InputStream stream = jarfile.getInputStream(jarfile.getEntry("messages/messages."+Messages.getLanguage())); - pluginMessages.load(stream); - Messages.loadPluginMessages(pluginMessages); - } catch (IOException e) { - Log.log(Log.WARNING, this, "Plugin "+pluginName+" does not have localized messages."+Messages.getLanguage()); - } + // Log.log(Log.NOTICE, this, "Loading localized messages for plugin: "+pluginName); + // Properties pluginMessages = new Properties(); + // try { + // InputStream stream = jarfile.getInputStream(jarfile.getEntry("messages/messages.en")); + // pluginMessages.load(stream); + // Messages.loadPluginMessages(pluginMessages); + // } catch (IOException e) { + // Log.log(Log.WARNING, this, "Plugin "+pluginName+" does not have default messages.en"); + // } + // try { + // InputStream stream = jarfile.getInputStream(jarfile.getEntry("messages/messages."+Messages.getLanguage())); + // pluginMessages.load(stream); + // Messages.loadPluginMessages(pluginMessages); + // } catch (IOException e) { + // Log.log(Log.WARNING, this, "Plugin "+pluginName+" does not have localized messages."+Messages.getLanguage()); + // } Class pluginClass = loadClass(mainPluginClass); Modified: trunk/jsxe/src/net/sourceforge/jsxe/gui/Messages.java =================================================================== --- trunk/jsxe/src/net/sourceforge/jsxe/gui/Messages.java 2006-07-06 16:51:38 UTC (rev 988) +++ trunk/jsxe/src/net/sourceforge/jsxe/gui/Messages.java 2006-07-06 21:26:48 UTC (rev 989) @@ -34,16 +34,16 @@ //{{{ Java base classes import java.io.*; -import java.util.Locale; -import java.util.Properties; -import java.util.Enumeration; -import java.util.Iterator; +import java.util.*; import java.text.MessageFormat; +import java.net.URL; //}}} //{{{ jsXe classes import net.sourceforge.jsxe.jsXe; +import net.sourceforge.jsxe.JARClassLoader; import net.sourceforge.jsxe.util.Log; +import net.sourceforge.jsxe.util.MiscUtilities; //}}} //}}} @@ -55,10 +55,17 @@ * {@link #setLanguage(String)} method. * * Messages are automatically loaded from the properties files located in the - * 'messages' directory in the jsXe install. These files are named - * <code>message.<i>language</i></code>. Where language is the ISO-639 language - * code. The default being english. + * 'messages' directory in the jsXe install directory. The messages files are + * names with the format messages.<code>language</code>.<code>country</code>.<code>variant</code>. + * The Messages class searches these files in the following order. * + * <ul> + * <li>messages.<code>language</code>.<code>country</code>.<code>variant</code></li> + * <li>messages.<code>language</code>.<code>country</code></li> + * <li>messages.<code>language</code></li> + * <li>messages</li> + * </ul> + * * @author Trish Hartnett (<a href="mailto:tri...@me...">tri...@me...</a>) * @author Ian Lewis (<a href="mailto:Ian...@me...">Ian...@me...</a>) * @version $Id$ @@ -68,28 +75,154 @@ public class Messages { //{{{ Private static members - private static Properties m_propertiesObject = new Properties(); - private static Properties m_pluginMessages = new Properties(); - private static Properties m_defaultProperties = new Properties(); - private static String m_language; - private static String m_directory = "."; //default to current directory - //}}} + /** + * A Locale to Properties object map which is used when searching + * for a message resource. + */ + private static HashMap m_messagesMap = new HashMap(); + /** + * This is a list of URLs messages files for plugins which have been loaded. + */ + private static ArrayList m_resources = new ArrayList(); + /** + * The default properties file + */ + private static Properties m_default; + private static Locale m_locale = Locale.getDefault(); - //{{{ getLanguage() + //{{{ getMessagesFileName() + private static String getMessagesFileName(Locale locale) { + StringBuffer messagesFile = new StringBuffer("messages"); + + if (locale != null) { + String language = locale.getLanguage(); + if (language != null && !language.equals("")) { + messagesFile.append(".").append(language); + + String country = locale.getCountry(); + if (country != null && !country.equals("")) { + messagesFile.append(".").append(country); + + String variant = locale.getVariant(); + if (variant != null && !variant.equals("")) { + messagesFile.append(".").append(variant); + } + } + } + } + + return messagesFile.toString(); + }//}}} + + //{{{ loadMessages() /** - * @return Returns the ISO-639 language code. + * @param locale the locale to use when searching for the messages file. + * The language, country, and variant must be exact. Null + * loads the default messages file. */ - public static String getLanguage() { - return m_language; + private static Properties loadMessages(Locale locale) { + Properties props = null; + try { + + if (locale != null) { + props = (Properties)m_messagesMap.get(locale); + } else { + props = m_default; + } + + if (props == null) { + //{{{ Load the properties file + + String messagesFile = getMessagesFileName(locale); + + //create input stream from messages file + FileInputStream in = new FileInputStream(jsXe.getInstallDirectory()+ + System.getProperty("file.separator")+ + "messages"+ + System.getProperty("file.separator")+ + messagesFile.toString()); + Log.log(Log.NOTICE, Messages.class, "Loading messages file: "+messagesFile); + props = new Properties(); + props.load(in); + if (locale != null) { + m_messagesMap.put(locale, props); + } else { + m_default = props; + } + //}}} + } + } catch (FileNotFoundException e) { + // just fall through + } catch(IOException e) { + Log.log(Log.ERROR, Messages.class, e); + } + + //{{{ Check for plugin resources + // Log.log(Log.DEBUG, Messages.class, "loading plugin messages"); + try { + JARClassLoader loader = jsXe.getPluginLoader(); + if (loader != null) { + String messagesFile = getMessagesFileName(locale); + //TODO: inefficient + Enumeration pluginMessages = loader.getPluginResources("messages/"+messagesFile); + // Log.log(Log.DEBUG, Messages.class, "looking for: "+"messages/"+messagesFile); + while (pluginMessages.hasMoreElements()) { + URL resource = (URL)pluginMessages.nextElement(); + // Log.log(Log.DEBUG, Messages.class, resource.toString()); + if (!m_resources.contains(resource)) { + Properties resourceProps = new Properties(); + Log.log(Log.NOTICE, Messages.class, "Loading plugin messages file: "+resource.toString()); + resourceProps.load(resource.openStream()); + props = MiscUtilities.mergeProperties(props, resourceProps); + m_resources.add(resource); + if (locale != null) { + m_messagesMap.put(locale, props); + } else { + m_default = props; + } + } + } + } + } catch(IOException e) { + Log.log(Log.ERROR, Messages.class, e); + }//}}} + + return props; }//}}} - //{{{ setLanguage() + //{{{ getMessages() /** - * @param newLanguage The ISO-639 language code + * Searches the available resources for a resource where it can draw + * the messages that are needed for the current locale. */ - public static void setLanguage(String newLanguage) { - initLocale(newLanguage, m_directory); + private static Properties getMessages(Locale locale) { + Properties messages = loadMessages(locale); + if (messages == null) { + messages = loadMessages(new Locale(locale.getLanguage(), locale.getCountry())); + if (messages == null) { + messages = loadMessages(new Locale(locale.getLanguage())); + if (messages == null) { + messages = loadMessages(null); + } + } + } + return messages; }//}}} + + //}}} + + //{{{ getLocale() + public Locale getLocale() { + return m_locale; + }//}}} + + //{{{ setLocale() + /** + * @param locale the new locale The ISO-639 language code + */ + public static void setLocale(Locale locale) { + m_locale = locale; + }//}}} //{{{ getMessage() /** @@ -103,15 +236,11 @@ * @return Returns the value of a property from the propertiesObject. */ public static synchronized String getMessage(String propertyName){ - if (m_language == null) { - //setLanguage("en"); - Locale newLocal = Locale.getDefault(); - String isoLanguage = newLocal.getLanguage(); - setLanguage(isoLanguage); - } + Properties messages = getMessages(m_locale); + //search in order, localized messages->default messages->plugin messages - String message = m_propertiesObject.getProperty(propertyName, m_defaultProperties.getProperty(propertyName, m_pluginMessages.getProperty(propertyName))); + String message = messages.getProperty(propertyName); if (message == null) { Log.log(Log.WARNING, Messages.class, "Unregistered message requested: "+propertyName); } @@ -155,78 +284,4 @@ } }//}}} - //{{{ initLocale() - /** - * Initializes localized messages for jsXe. - * @param language The language for the propertiesObject. - * @param directory The directory where the messages files are located. - */ - public static void initLocale(String language, String directory) { - String isoLanguage = language; - if (isoLanguage == null){ - //setLanguage("en"); - Locale newLocal = Locale.getDefault(); - isoLanguage = newLocal.getLanguage(); - } - - Log.log(Log.MESSAGE, Messages.class, "Loading messages for language: "+isoLanguage); - - File messagesFile = new File(directory+System.getProperty("file.separator")+"messages."+isoLanguage); - if (!messagesFile.exists()) { - Log.log(Log.WARNING, Messages.class, "Default messages file for current language not found"); - } else { - loadMessages(m_propertiesObject, messagesFile); - m_language = isoLanguage; - } - m_directory = directory; - - //load default english - messagesFile = new File(directory+System.getProperty("file.separator")+"messages.en"); - if (!messagesFile.exists()) { - Log.log(Log.ERROR, Messages.class, "Default messages file for English not found"); - } else { - if (m_language == null) { - m_language = "en"; - } - } - loadMessages(m_defaultProperties, messagesFile); - }//}}} - - //{{{ loadPluginMessages() - /** - * Loads the localized messages from installed plugins and merges them into - * the plugin messages. - * This method should only be called on jsXe startup. - */ - public static void loadPluginMessages(Properties pluginMessages) { - Enumeration names = pluginMessages.propertyNames(); - while (names.hasMoreElements()) { - String name = names.nextElement().toString(); - String message = pluginMessages.getProperty(name); - m_pluginMessages.setProperty(name, message); - } - }//}}} - - //{{{ Private Members - - //{{{ loadMessages() - /** - * - * @param propertiesObject The propertiesObject which will store the values from the messages file. - * @param messssagesFile The name of the messages file to be used. - */ - private static void loadMessages(Properties propertiesObject, File messagesFile) { - try { - //create input stream from messages file - FileInputStream in = new FileInputStream(messagesFile); - propertiesObject.load(in); - } catch (FileNotFoundException e) { - Log.log(Log.ERROR, Messages.class, e); - } catch(IOException e) { - Log.log(Log.ERROR, Messages.class, e); - } - }//}}} - - //}}} - } Modified: trunk/jsxe/src/net/sourceforge/jsxe/jsXe.java =================================================================== --- trunk/jsxe/src/net/sourceforge/jsxe/jsXe.java 2006-07-06 16:51:38 UTC (rev 988) +++ trunk/jsxe/src/net/sourceforge/jsxe/jsXe.java 2006-07-06 21:26:48 UTC (rev 989) @@ -123,7 +123,7 @@ if(!_pluginsDirectory.exists()) _pluginsDirectory.mkdirs(); - String jsXeHome = System.getProperty("jsxe.home"); + jsXeHome = System.getProperty("jsxe.home"); if (jsXeHome == null) { String classpath = System.getProperty("java.class.path"); int index = classpath.toLowerCase().indexOf("jsxe.jar"); @@ -143,10 +143,6 @@ //}}} - //{{{ start locale - Messages.initLocale(null, jsXeHome+fileSep+"messages"); - //}}} - //{{{ get and load the configuration files initDefaultProps(); //}}} @@ -458,6 +454,23 @@ return jsXeIcon; }//}}} + //{{{ getHomeDirectory() method + /** + * Returns the path to where jsXe is installed + */ + public static String getInstallDirectory() { + return jsXeHome; + } //}}} + + + //{{{ getHomeDirectory() method + /** + * Returns the path to the user's home directory. + */ + public static String getHomeDirectory() { + return m_homeDirectory; + } //}}} + //{{{ getSettingsDirectory() method /** * Returns the path of the directory where user-specific settings @@ -1336,6 +1349,7 @@ private static TabbedView m_activeView; private static String m_settingsDirectory; private static String m_homeDirectory; + private static String jsXeHome; private static OptionPane jsXeOptions; //}}} Modified: trunk/jsxe/src/net/sourceforge/jsxe/util/MiscUtilities.java =================================================================== --- trunk/jsxe/src/net/sourceforge/jsxe/util/MiscUtilities.java 2006-07-06 16:51:38 UTC (rev 988) +++ trunk/jsxe/src/net/sourceforge/jsxe/util/MiscUtilities.java 2006-07-06 21:26:48 UTC (rev 989) @@ -1307,6 +1307,44 @@ //}}} + //{{{ mergeProperties() + /** + * Merges two Properties sets together into a new Properties object + * giving precidence to the properties in the first argument. If either + * Properties object is null, the other Properties object is returned. + * If both are null then null is returned. + * + * @param props1 the first Properties object whose properties are given + * precidence. + * @param props2 the second Properties object whose properties are merged + * with that of the first. + */ + public static Properties mergeProperties(Properties props1, Properties props2) { + if (props1 == null) { + return props2; + } + + if (props2 == null) { + return props1; + } + + Properties props = new Properties(); + + Enumeration names = props2.propertyNames(); + while (names.hasMoreElements()) { + String name = names.nextElement().toString(); + props.setProperty(name, props2.getProperty(name)); + } + + names = props1.propertyNames(); + while (names.hasMoreElements()) { + String name = names.nextElement().toString(); + props.setProperty(name, props1.getProperty(name)); + } + + return props; + }//}}} + //{{{ isTrue() /** * Returns true if the value of the string is true This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |