001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements. See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership. The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the  "License");
007     * you may not use this file except in compliance with the License.
008     * You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing, software
013     * distributed under the License is distributed on an "AS IS" BASIS,
014     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     */
018    /*
019     * $Id: XMLMessages.java 468653 2006-10-28 07:07:05Z minchau $
020     */
021    package org.apache.xml.res;
022    
023    import java.util.ListResourceBundle;
024    import java.util.Locale;
025    import java.util.MissingResourceException;
026    import java.util.ResourceBundle;
027    
028    /**
029     * A utility class for issuing XML error messages.
030     * @xsl.usage internal
031     */
032    public class XMLMessages
033    {
034    
035      /** The local object to use.  */
036      protected Locale fLocale = Locale.getDefault();
037    
038      /** The language specific resource object for XML messages.  */
039      private static ListResourceBundle XMLBundle = null;
040    
041      /** The class name of the XML error message string table.    */
042      private static final String XML_ERROR_RESOURCES =
043        "org.apache.xml.res.XMLErrorResources";
044    
045      /** String to use if a bad message code is used. */
046      protected static final String BAD_CODE = "BAD_CODE";
047    
048      /** String to use if the message format operation failed.  */
049      protected static final String FORMAT_FAILED = "FORMAT_FAILED";
050        
051      /**
052       * Set the Locale object to use.
053       * 
054       * @param locale non-null reference to Locale object.
055       */
056       public void setLocale(Locale locale)
057      {
058        fLocale = locale;
059      }
060    
061      /**
062       * Get the Locale object that is being used.
063       * 
064       * @return non-null reference to Locale object.
065       */
066      public Locale getLocale()
067      {
068        return fLocale;
069      }
070        
071      /**
072       * Creates a message from the specified key and replacement
073       * arguments, localized to the given locale.
074       *
075       * @param msgKey    The key for the message text.
076       * @param args      The arguments to be used as replacement text
077       *                  in the message created.
078       *
079       * @return The formatted message string.
080       */
081      public static final String createXMLMessage(String msgKey, Object args[])
082      {
083        if (XMLBundle == null)
084          XMLBundle = loadResourceBundle(XML_ERROR_RESOURCES);
085        
086        if (XMLBundle != null)
087        {
088          return createMsg(XMLBundle, msgKey, args);
089        }
090        else
091          return "Could not load any resource bundles.";
092      }
093    
094      /**
095       * Creates a message from the specified key and replacement
096       * arguments, localized to the given locale.
097       *
098       * @param fResourceBundle The resource bundle to use.
099       * @param msgKey  The message key to use.
100       * @param args      The arguments to be used as replacement text
101       *                  in the message created.
102       *
103       * @return The formatted message string.
104       */
105      public static final String createMsg(ListResourceBundle fResourceBundle,
106            String msgKey, Object args[])  //throws Exception
107      {
108    
109        String fmsg = null;
110        boolean throwex = false;
111        String msg = null;
112    
113        if (msgKey != null)
114          msg = fResourceBundle.getString(msgKey);
115    
116        if (msg == null)
117        {
118          msg = fResourceBundle.getString(BAD_CODE);
119          throwex = true;
120        }
121    
122        if (args != null)
123        {
124          try
125          {
126    
127            // Do this to keep format from crying.
128            // This is better than making a bunch of conditional
129            // code all over the place.
130            int n = args.length;
131    
132            for (int i = 0; i < n; i++)
133            {
134              if (null == args[i])
135                args[i] = "";
136            }
137    
138            fmsg = java.text.MessageFormat.format(msg, args);
139          }
140          catch (Exception e)
141          {
142            fmsg = fResourceBundle.getString(FORMAT_FAILED);
143            fmsg += " " + msg;
144          }
145        }
146        else
147          fmsg = msg;
148    
149        if (throwex)
150        {
151          throw new RuntimeException(fmsg);
152        }
153    
154        return fmsg;
155      }
156    
157      /**
158       * Return a named ResourceBundle for a particular locale.  This method mimics the behavior
159       * of ResourceBundle.getBundle().
160       *
161       * @param className The class name of the resource bundle.
162       * @return the ResourceBundle
163       * @throws MissingResourceException
164       */
165      public static ListResourceBundle loadResourceBundle(String className)
166              throws MissingResourceException
167      {    
168        Locale locale = Locale.getDefault();
169    
170        try
171        {
172          return (ListResourceBundle)ResourceBundle.getBundle(className, locale);
173        }
174        catch (MissingResourceException e)
175        {
176          try  // try to fall back to en_US if we can't load
177          {
178    
179            // Since we can't find the localized property file,
180            // fall back to en_US.
181            return (ListResourceBundle)ResourceBundle.getBundle(
182              className, new Locale("en", "US"));
183          }
184          catch (MissingResourceException e2)
185          {
186    
187            // Now we are really in trouble.
188            // very bad, definitely very bad...not going to get very far
189            throw new MissingResourceException(
190              "Could not load any resource bundles." + className, className, "");
191          }
192        }
193      }
194    
195      /**
196       * Return the resource file suffic for the indicated locale
197       * For most locales, this will be based the language code.  However
198       * for Chinese, we do distinguish between Taiwan and PRC
199       *
200       * @param locale the locale
201       * @return an String suffix which can be appended to a resource name
202       */
203      protected static String getResourceSuffix(Locale locale)
204      {
205    
206        String suffix = "_" + locale.getLanguage();
207        String country = locale.getCountry();
208    
209        if (country.equals("TW"))
210          suffix += "_" + country;
211    
212        return suffix;
213      }
214    }