< prev index next >

src/share/classes/sun/tools/jconsole/Resources.java

Print this page
rev 1501 : 7017818: NLS: JConsoleResources.java cannot be handled by translation team
Reviewed-by: mchung, mfang


   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.tools.jconsole;
  27 



  28 import java.text.MessageFormat;



  29 import java.util.MissingResourceException;
  30 import java.util.ResourceBundle;
  31 
  32 import sun.tools.jconsole.resources.JConsoleResources;
  33 
  34 /**
  35  * Provides resource support for jconsole.
  36  */
  37 public final class Resources {






  38 
  39     private static final Object lock = new Object();
  40     private static JConsoleResources resources = null;
  41     static {
































  42         try {
  43             resources =
  44                 (JConsoleResources)ResourceBundle.getBundle("sun.tools.jconsole.resources.JConsoleResources");
  45         } catch (MissingResourceException e) {
  46             // gracefully handle this later










  47         }
  48     }
  49 
  50     private Resources() { throw new AssertionError(); }




  51 
  52     /**
  53      * Returns the text of the jconsole resource for the specified key
  54      * formatted with the specified arguments.
  55      *




  56      */
  57     public static String getText(String key, Object... args) {
  58         String format = getString(key);
  59         if (format == null) {
  60             format = "missing resource key: key = \"" + key + "\", " +
  61                 "arguments = \"{0}\", \"{1}\", \"{2}\"";















  62         }
  63         return formatMessage(format, args);










  64     }
  65 
  66     static String formatMessage(String format, Object... args) {
  67         String ss = null;
  68         synchronized (lock) {
  69             /*
  70              * External synchronization required for safe use of
  71              * java.text.MessageFormat:

  72              */
  73             ss = MessageFormat.format(format, args);







  74         }
  75         return ss;
  76     }
  77 
  78     /**
  79      * Returns the mnemonic keycode int of the jconsole resource for the specified key.



  80      *


  81      */
  82     public static int getMnemonicInt(String key) {
  83         int mnemonic = 0;
  84         if (resources != null) {
  85             Object obj = resources.getObject(key+".mnemonic");
  86             if (obj instanceof Character) {
  87                 mnemonic = (int)(Character)obj;
  88                 if (mnemonic >= 'a' && mnemonic <='z') {
  89                     mnemonic -= ('a' - 'A');
  90                 }
  91             } else if (obj instanceof Integer) {
  92                 mnemonic = (Integer)obj;
  93             }
  94         }
  95         return mnemonic;
  96     }
  97 
  98     /**
  99      * Returns the jconsole resource string for the specified key.
 100      *




 101      */
 102     private static String getString(String key) {
 103         if (resources != null) {
 104             try {
 105                 return resources.getString(key);
 106             } catch (MissingResourceException e) {
 107                 return null;
 108             }










 109         }
 110         return "missing resource bundle: key = \"" + key + "\", " +
 111             "arguments = \"{0}\", \"{1}\", \"{2}\"";
 112     }
 113 }


   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.tools.jconsole;
  27 
  28 import java.awt.event.KeyEvent;
  29 import java.lang.reflect.Field;
  30 import java.lang.reflect.Modifier;
  31 import java.text.MessageFormat;
  32 import java.util.Collections;
  33 import java.util.HashMap;
  34 import java.util.Map;
  35 import java.util.MissingResourceException;
  36 import java.util.ResourceBundle;
  37 


  38 /**
  39  * Toolkit that provides resource support for JConsole.
  40  */
  41 public final class Resources {
  42     private static Map<String, Integer> MNEMONIC_LOOKUP = Collections
  43             .synchronizedMap(new HashMap<String, Integer>());
  44 
  45     private Resources() {
  46         throw new AssertionError();
  47     }
  48 
  49     /**
  50      * Convenience method for {@link MessageFormat#format(String, Object...)}.
  51      *
  52      * @param pattern the pattern
  53      * @param objects the arguments for the pattern
  54      *
  55      * @return a formatted string
  56      */
  57     public static String format(String pattern, Object... arguments) {
  58             return MessageFormat.format(pattern, arguments);
  59     }
  60 
  61     /**
  62      * Returns the mnemonic for a message.
  63      *
  64      * @param message the message
  65      *
  66      * @return the mnemonic <code>int</code>
  67      */
  68     public static int getMnemonicInt(String message) {
  69         Integer integer = MNEMONIC_LOOKUP.get(message);
  70         if (integer != null) {
  71             return integer.intValue();
  72         }
  73         return 0;
  74     }
  75 
  76     /**
  77      * Initializes all non-final public static fields in the given class with
  78      * messages from a {@link ResourceBundle}.
  79      *
  80      * @param clazz the class containing the fields
  81      */
  82     public static void initializeMessages(Class<?> clazz, String rbName) {
  83         ResourceBundle rb = null;
  84         try {
  85             rb = ResourceBundle.getBundle(rbName);
  86         } catch (MissingResourceException mre) {
  87             // fall through, handled later
  88         }
  89         for (Field field : clazz.getFields()) {
  90             if (isWritableField(field)) {
  91                 String key = field.getName();
  92                 String message = getMessage(rb, key);
  93                 int mnemonicInt = findMnemonicInt(message);
  94                 message = removeMnemonicAmpersand(message);
  95                 message = replaceWithPlatformLineFeed(message);
  96                 setFieldValue(field, message);
  97                 MNEMONIC_LOOKUP.put(message, mnemonicInt);
  98             }
  99         }
 100     }
 101 
 102     private static boolean isWritableField(Field field) {
 103         int modifiers = field.getModifiers();
 104         return Modifier.isPublic(modifiers) && Modifier.isStatic(modifiers)
 105                 && !Modifier.isFinal(modifiers);
 106     }
 107 
 108     /**
 109      * Returns the message corresponding to the key in the bundle or a text
 110      * describing it's missing.
 111      *
 112      * @param rb the resource bundle
 113      * @param key the key
 114      *
 115      * @return the message
 116      */
 117     private static String getMessage(ResourceBundle rb, String key) {
 118         if (rb == null) {
 119             return "missing resource bundle";
 120         }
 121         try {
 122             return rb.getString(key);
 123         } catch (MissingResourceException mre) {
 124             return "missing message for key = \"" + key
 125                     + "\" in resource bundle ";
 126         }
 127     }
 128 
 129     private static void setFieldValue(Field field, String value) {
 130         try {
 131             field.set(null, value);
 132         } catch (IllegalArgumentException e) {
 133             throw new Error("Unable to access or set message for field " + field.getName());
 134         } catch (IllegalAccessException e) {
 135             throw new Error("Unable to access or set message for field " + field.getName());
 136         }
 137     }
 138 
 139     /**
 140      * Returns a {@link String} where all <code>\n</code> in the <text> have
 141      * been replaced with the line separator for the platform.
 142      *
 143      * @param text the to be replaced
 144      *
 145      * @return the replaced text
 146      */
 147     private static String replaceWithPlatformLineFeed(String text) {
 148         return text.replace("\n", System.getProperty("line.separator"));
 149     }
 150 
 151     /**
 152      * Removes the mnemonic identifier (<code>&</code>) from a string unless
 153      * it's escaped by <code>&&</code> or placed at the end.
 154      *
 155      * @param message the message
 156      *
 157      * @return a message with the mnemonic identifier removed
 158      */
 159     private static String removeMnemonicAmpersand(String message) {
 160         StringBuilder s = new StringBuilder();
 161         for (int i = 0; i < message.length(); i++) {
 162             char current = message.charAt(i);
 163             if (current != '&' || i == message.length() - 1
 164                     || message.charAt(i + 1) == '&') {
 165                 s.append(current);
 166             }
 167         }
 168         return s.toString();
 169     }
 170 
 171     /**
 172      * Finds the mnemonic character in a message.
 173      *
 174      * The mnemonic character is the first character followed by the first
 175      * <code>&</code> that is not followed by another <code>&</code>.
 176      *
 177      * @return the mnemonic as an <code>int</code>, or <code>0</code> if it
 178      *         can't be found.
 179      */
 180     private static int findMnemonicInt(String s) {
 181         for (int i = 0; i < s.length() - 1; i++) {
 182             if (s.charAt(i) == '&') {
 183                 if (s.charAt(i + 1) != '&') {
 184                     return lookupMnemonicInt(s.substring(i + 1, i + 2));
 185                 } else {
 186                     i++;

 187                 }


 188             }
 189         }
 190         return 0;
 191     }
 192 
 193     /**
 194      * Lookups the mnemonic for a key in the {@link KeyEvent} class.
 195      *
 196      * @param c the character to lookup
 197      *
 198      * @return the mnemonic as an <code>int</code>, or <code>0</code> if it
 199      *         can't be found.
 200      */
 201     private static int lookupMnemonicInt(String c) {

 202         try {
 203             return KeyEvent.class.getDeclaredField("VK_" + c.toUpperCase())
 204                     .getInt(null);
 205         } catch (IllegalArgumentException e) {
 206             // Missing VK is okay
 207             return 0;
 208         } catch (IllegalAccessException e) {
 209             // Missing VK is okay
 210             return 0;
 211         } catch (NoSuchFieldException e) {
 212             // Missing VK is okay
 213             return 0;
 214         } catch (SecurityException e) {
 215             // Missing VK is okay
 216             return 0;
 217         }


 218     }
 219 }
< prev index next >