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 }