1 /*
   2  * $Id$
   3  *
   4  * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
   5  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   6  *
   7  * This code is free software; you can redistribute it and/or modify it
   8  * under the terms of the GNU General Public License version 2 only, as
   9  * published by the Free Software Foundation.  Oracle designates this
  10  * particular file as subject to the "Classpath" exception as provided
  11  * by Oracle in the LICENSE file that accompanied this code.
  12  *
  13  * This code is distributed in the hope that it will be useful, but WITHOUT
  14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  15  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  16  * version 2 for more details (a copy is included in the LICENSE file that
  17  * accompanied this code).
  18  *
  19  * You should have received a copy of the GNU General Public License version
  20  * 2 along with this work; if not, write to the Free Software Foundation,
  21  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  22  *
  23  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  24  * or visit www.oracle.com if you need additional information or have any
  25  * questions.
  26  */
  27 package com.sun.interview.wizard;
  28 
  29 import java.awt.Color;
  30 import java.text.MessageFormat;
  31 import java.util.Enumeration;
  32 import java.util.Locale;
  33 import java.util.ResourceBundle;
  34 import java.util.MissingResourceException;
  35 
  36 /**
  37  * A class that lazily opens a package-specific resource bundle
  38  * containing localization data for a class.
  39  */
  40 class I18NResourceBundle extends ResourceBundle
  41 {
  42     static I18NResourceBundle getDefaultBundle() {
  43         if (defaultBundle == null)
  44             defaultBundle = getBundleForClass(I18NResourceBundle.class);
  45 
  46         return defaultBundle;
  47     }
  48 
  49     private static I18NResourceBundle defaultBundle;
  50 
  51     /**
  52      * Get a package-specific resource bundle for a class containing localization data.
  53      * The bundle is named i18n.properties in the same
  54      * package as the given class.
  55      * @param c the class for which to obtain the resource bundle
  56      * @return the appropriate resource bundle for the class
  57      */
  58     public static I18NResourceBundle getBundleForClass(Class c) {
  59         String cn = c.getName();
  60         int dot = cn.lastIndexOf('.');
  61         String rn = (dot == -1 ? "i18n" : cn.substring(0, dot) + ".i18n");
  62         boolean logging = (logClassPrefix == null ? false : cn.startsWith(logClassPrefix));
  63         return new I18NResourceBundle(rn, logging, c.getClassLoader());
  64     }
  65 
  66     /**
  67      * Get an entry from the resource bundle.
  68      * If the resource cannot be found, a message is printed to the console
  69      * and the result will be a string containing the method parameters.
  70      * @param key the name of the entry to be returned
  71      * @param arg an argument to be formatted into the result using
  72      * {@link java.text.MessageFormat#format}
  73      * @return the formatted string
  74      */
  75     public String getString(String key, Object arg) {
  76         return getString(key, new Object[] {arg});
  77     }
  78 
  79     /**
  80      * Get an entry from the resource bundle.
  81      * If the resource cannot be found, a message is printed to the console
  82      * and the result will be a string containing the method parameters.
  83      * @param key the name of the entry to be returned
  84      * @param args an array of arguments to be formatted into the result using
  85      * {@link java.text.MessageFormat#format}
  86      * @return the formatted string
  87      */
  88     public String getString(String key, Object[] args) {
  89         try {
  90             return MessageFormat.format(getString(key), args);
  91         }
  92         catch (MissingResourceException e) {
  93             showError(key, name);
  94             return key;
  95         }
  96     }
  97 
  98     /**
  99      * Get a color defined in the resource bundle.
 100      * If the resource cannot be found, a message is printed to the console
 101      * and the result will be a specified default.
 102      * @param key The base key for the resource. The actual key is this
 103      * value with ".clr" appended.
 104      * @param dflt an integer value used to construct the default result
 105      * if the specified resource cannot be found. The value is normally
 106      * most conveniently specified in hex, in the standard 0xRRGGBB format.
 107      * @return the color defined in the resource bundle, or a default
 108      * if the resource cannot be found
 109      */
 110     public Color getColor(String key, int dflt) {
 111         String value = getString(key + ".clr");
 112         try {
 113             if (value != null)
 114                 return Color.decode(value);
 115         }
 116         catch (Exception e) {
 117             // ignore
 118         }
 119         return new Color(dflt);
 120     }
 121 
 122     /**
 123      * Get a color suitable for displaying short error messages.
 124      * The color is defined by the i18n.error.clr resource.
 125      * @return a color suitable for displaying short error messages
 126      */
 127     public Color getErrorColor() {
 128         return getColor("i18n.error", 0xff0000);
 129     }
 130 
 131 
 132     /**
 133      * Create a resource bundle for the given name.
 134      * The actual resource bundle will not be loaded until it is needed.
 135      * @arg name The name of the actual resource bundle to use.
 136      */
 137     private I18NResourceBundle(String name, boolean logging, ClassLoader cl) {
 138         this.name = name;
 139         this.logging = logging;
 140         this.classLoader = cl;
 141     }
 142 
 143     /**
 144      * A required internal method for ResourceBundle.
 145      * Load the actual resource bundle, if it has not yet been loaded,
 146      * then hand the request off to that bundle.
 147      * If the resource cannot be found, a message is printed to the console
 148      * and the result will be the original key.
 149      */
 150     protected Object handleGetObject(String key) throws MissingResourceException {
 151         if (logging)
 152             System.out.println("i18n: " + key);
 153         try {
 154             if (delegate == null)
 155                 delegate = ResourceBundle.getBundle(name, Locale.getDefault(), classLoader);
 156             return delegate.getObject(key);
 157         }
 158         catch (MissingResourceException e) {
 159             showError(key, name);
 160             return key;
 161         }
 162     }
 163 
 164     /**
 165      * A required internal method for ResourceBundle.
 166      * Load the actual resource bundle, if it has not yet been loaded,
 167      * then hand the request off to that bundle.
 168      */
 169     public Enumeration<String> getKeys() {
 170         if (delegate == null)
 171             delegate = ResourceBundle.getBundle(name, Locale.getDefault(), classLoader);
 172         return delegate.getKeys();
 173     }
 174 
 175     private void showError(String key, String name) {
 176         System.err.println("WARNING: missing resource: " + key + " for " + name);
 177     }
 178 
 179     private String name;
 180     private ResourceBundle delegate;
 181     private ClassLoader classLoader;
 182     private boolean logging;
 183 
 184     private static String logClassPrefix = System.getProperty("i18n.log");
 185 }