001/* 002 * $Id: Chapter.java 3373 2008-05-12 16:21:24Z xlv $ 003 * 004 * This file is part of the iText (R) project. 005 * Copyright (c) 1998-2011 1T3XT BVBA 006 * Authors: Bruno Lowagie, Paulo Soares, et al. 007 * 008 * This program is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU Affero General Public License version 3 010 * as published by the Free Software Foundation with the addition of the 011 * following permission added to Section 15 as permitted in Section 7(a): 012 * FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY 1T3XT, 013 * 1T3XT DISCLAIMS THE WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. 014 * 015 * This program is distributed in the hope that it will be useful, but 016 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 017 * or FITNESS FOR A PARTICULAR PURPOSE. 018 * See the GNU Affero General Public License for more details. 019 * You should have received a copy of the GNU Affero General Public License 020 * along with this program; if not, see http://www.gnu.org/licenses or write to 021 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 022 * Boston, MA, 02110-1301 USA, or download the license from the following URL: 023 * http://itextpdf.com/terms-of-use/ 024 * 025 * The interactive user interfaces in modified source and object code versions 026 * of this program must display Appropriate Legal Notices, as required under 027 * Section 5 of the GNU Affero General Public License. 028 * 029 * In accordance with Section 7(b) of the GNU Affero General Public License, 030 * a covered work must retain the producer line in every PDF that is created 031 * or manipulated using iText. 032 * 033 * You can be released from the requirements of the license by purchasing 034 * a commercial license. Buying such a license is mandatory as soon as you 035 * develop commercial activities involving the iText software without 036 * disclosing the source code of your own applications. 037 * These activities include: offering paid services to customers as an ASP, 038 * serving PDFs on the fly in a web application, shipping iText with a closed 039 * source product. 040 * 041 * For more information, please contact iText Software Corp. at this 042 * address: sales@itextpdf.com 043 */ 044package com.itextpdf.text.error_messages; 045 046import java.io.BufferedReader; 047import java.io.IOException; 048import java.io.InputStream; 049import java.io.InputStreamReader; 050import java.io.Reader; 051import java.util.HashMap; 052 053import com.itextpdf.text.pdf.BaseFont; 054 055/** 056 * Localizes error messages. The messages are located in the package 057 * com.itextpdf.text.error_messages in the form language_country.lng. 058 * The internal file encoding is UTF-8 without any escape chars, it's not a 059 * normal property file. See en.lng for more information on the internal format. 060 * @author Paulo Soares (psoares@glintt.com) 061 */ 062public final class MessageLocalization { 063 private static HashMap<String, String> defaultLanguage = new HashMap<String, String>(); 064 private static HashMap<String, String> currentLanguage; 065 private static final String BASE_PATH = "com/itextpdf/text/l10n/error/"; 066 067 private MessageLocalization() { 068 } 069 070 static { 071 try { 072 defaultLanguage = getLanguageMessages("en", null); 073 } catch (Exception ex) { 074 // do nothing 075 } 076 if (defaultLanguage == null) 077 defaultLanguage = new HashMap<String, String>(); 078 } 079 080 /** 081 * Get a message without parameters. 082 * @param key the key to the message 083 * @return the message 084 */ 085 public static String getMessage(String key) { 086 HashMap<String, String> cl = currentLanguage; 087 String val; 088 if (cl != null) { 089 val = cl.get(key); 090 if (val != null) 091 return val; 092 } 093 cl = defaultLanguage; 094 val = cl.get(key); 095 if (val != null) 096 return val; 097 return "No message found for " + key; 098 } 099 100 101 102 /** 103 * Get a message with one parameter as an primitive int. The parameter will replace the string 104 * "{1}" found in the message. 105 * @param key the key to the message 106 * @param p1 the parameter 107 * @return the message 108 */ 109 public static String getComposedMessage(String key, int p1) { 110 return getComposedMessage(key, String.valueOf(p1), null, null, null); 111 } 112 113 /** 114 * Get a message with param.length parameters or none if param is null. In 115 * the message the "{1}", "{2}" to "{lenght of param array}" are replaced 116 * with the object.toString of the param array. (with param[0] being "{1}") 117 * 118 * @since iText 5.0.6 119 * @param key 120 * the key to the message 121 * @param param array of parameter objects, (toString is used to add it to the message) 122 * @return the message 123 */ 124 public static String getComposedMessage(final String key, final Object... param) { 125 String msg = getMessage(key); 126 if (null != param) { 127 int i = 1; 128 for (Object o : param) { 129 if (null != o) { 130 msg = msg.replace("{" + i + "}", o.toString()); 131 } 132 i++; 133 } 134 } 135 return msg; 136 } 137 138 /** 139 * Sets the language to be used globally for the error messages. The language 140 * is a two letter lowercase country designation like "en" or "pt". The country 141 * is an optional two letter uppercase code like "US" or "PT". 142 * @param language the language 143 * @param country the country 144 * @return true if the language was found, false otherwise 145 * @throws IOException on error 146 */ 147 public static boolean setLanguage(String language, String country) throws IOException { 148 HashMap<String, String> lang = getLanguageMessages(language, country); 149 if (lang == null) 150 return false; 151 currentLanguage = lang; 152 return true; 153 } 154 155 /** 156 * Sets the error messages directly from a Reader. 157 * @param r the Reader 158 * @throws IOException on error 159 */ 160 public static void setMessages(Reader r) throws IOException { 161 currentLanguage = readLanguageStream(r); 162 } 163 164 private static HashMap<String, String> getLanguageMessages(String language, String country) throws IOException { 165 if (language == null) 166 throw new IllegalArgumentException("The language cannot be null."); 167 InputStream is = null; 168 try { 169 String file; 170 if (country != null) 171 file = language + "_" + country + ".lng"; 172 else 173 file = language + ".lng"; 174 is = BaseFont.getResourceStream(BASE_PATH + file, new MessageLocalization().getClass().getClassLoader()); 175 if (is != null) 176 return readLanguageStream(is); 177 if (country == null) 178 return null; 179 file = language + ".lng"; 180 is = BaseFont.getResourceStream(BASE_PATH + file, new MessageLocalization().getClass().getClassLoader()); 181 if (is != null) 182 return readLanguageStream(is); 183 else 184 return null; 185 } 186 finally { 187 try { 188 if (null != is){ 189 is.close(); 190 } 191 } catch (Exception exx) { 192 } 193 // do nothing 194 } 195 } 196 197 private static HashMap<String, String> readLanguageStream(InputStream is) throws IOException { 198 return readLanguageStream(new InputStreamReader(is, "UTF-8")); 199 } 200 201 private static HashMap<String, String> readLanguageStream(Reader r) throws IOException { 202 HashMap<String, String> lang = new HashMap<String, String>(); 203 BufferedReader br = new BufferedReader(r); 204 String line; 205 while ((line = br.readLine()) != null) { 206 int idxeq = line.indexOf('='); 207 if (idxeq < 0) 208 continue; 209 String key = line.substring(0, idxeq).trim(); 210 if (key.startsWith("#")) 211 continue; 212 lang.put(key, line.substring(idxeq + 1)); 213 } 214 return lang; 215 } 216}