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 }