1 /* 2 * Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 /* 26 * Licensed Materials - Property of IBM 27 * 5639-D57 (C) COPYRIGHT International Business Machines Corp. 1997,1998 28 * RMI-IIOP v1.0 29 * 30 * Defect History 31 * 32 * #26964 LKR 11/25/96 \u0020 at end-of-message not handled properly by Java. 33 * #31840 LKR 06/05/97 Replace \n in templates with Java's line separator. 34 * 35 */ 36 37 package com.sun.tools.corba.se.idl.som.cff; 38 39 import java.io.IOException; 40 import java.util.Enumeration; 41 import java.util.Properties; 42 import java.lang.String; 43 import java.lang.System; 44 45 /** 46 * This class provides messaging services for accessing, and merging 47 * parameters into, translatable message text. The text is presumed 48 * to reside in a .properties file. A "cff.properties" file that 49 * contains all of the message text needed for the CFF framework itself 50 * is loaded during class initialization. All of the messages in the 51 * cff.properties file that are needed by the CFF framework contain keys 52 * that begin with the string "cff.". 53 * <p> 54 * The static method Messages.msgLoad may be used to merge additional 55 * message text .properties files needed by other frameworks or user 56 * programs. 57 * 58 * @see com.sun.tools.corba.se.idl.som.cff.Messages#msgLoad 59 * 60 * @author Larry K. Raper 61 */ 62 63 public abstract class Messages { 64 65 /* Class variables */ 66 67 68 /* Metasymbol for leading or trailing blank */ 69 private static final String LTB = "%B"; 70 /* Metasymbol for line separator */ 71 private static final char NL = '\n'; 72 73 private static final String lineSeparator = 74 System.getProperty ("line.separator"); 75 76 private static final Properties m = new Properties (); 77 private static boolean loadNeeded = true; 78 79 /* Class methods for message loading and formatting */ 80 81 private static final synchronized void loadDefaultProperties () { 82 83 if (!loadNeeded) 84 return; 85 try { 86 m.load (FileLocator.locateLocaleSpecificFileInClassPath ( 87 "com/sun/tools/corba/se/idl/som/cff/cff.properties")); 88 } catch (IOException ioe) { } 89 fixMessages (m); /* #26964 Replace any metasymbols */ 90 loadNeeded = false; 91 92 } 93 94 /** 95 * This method was introduced to fix defect #26964. For Java 1.0.2 96 * on Win NT, the escape sequence \u0020 was not being handled 97 * correctly by the Java Properties class when it was the final 98 * character of a line. Instead the trailing blank was dropped 99 * and the next line was swallowed as a continuation. To work 100 * around the problem, we introduced our own metasymbol to represent 101 * a trailing blank. Hence: 102 * 103 * Performs substitution for any metasymbols in the message 104 * templates. So far only %B is needed. This was introduced 105 * to make it more convenient for .properties files to 106 * contain message templates with leading or trailing blanks 107 * (although %B may actually occur anywhere in a template). 108 * Subsequently, checking for '\n' has also been added. Now, 109 * wherever '\n' occurs in a message template, it is replaced 110 * with the value of System.getProperty ("line.separator"). 111 */ 112 private static final void fixMessages (Properties p) { 113 114 Enumeration keys = p.keys (); 115 Enumeration elems = p.elements (); 116 while (keys.hasMoreElements ()) { 117 String key = (String) keys.nextElement (); 118 String elem = (String) elems.nextElement (); 119 int i = elem.indexOf (LTB); 120 boolean changed = false; 121 while (i != -1) { 122 if (i == 0) 123 elem = " " + elem.substring (2); 124 else 125 elem = elem.substring (0, i) + " " + elem.substring (i+2); 126 changed = true; 127 i = elem.indexOf (LTB); 128 } 129 int lsIncr = lineSeparator.length () - 1; 130 for (i=0; i<elem.length (); i++) { 131 if (elem.charAt (i) == NL) { 132 elem = elem.substring (0, i) + 133 lineSeparator + elem.substring (i+1); 134 i += lsIncr; 135 changed = true; 136 } 137 } 138 if (changed) 139 p.put (key, elem); 140 } 141 142 } 143 144 /** 145 * Loads additional message keys and text found in the passed 146 * properties file. The specified properties file is assumed to 147 * reside in the CLASSPATH. An IOException is thrown if the loading fails. 148 */ 149 public static final synchronized void msgLoad (String propertyFileName) 150 throws IOException { 151 152 m.load (FileLocator.locateLocaleSpecificFileInClassPath ( 153 propertyFileName)); 154 fixMessages (m); /* #26964 Replace any metasymbols */ 155 loadNeeded = false; 156 157 } 158 159 /** 160 * Returns the message text corresponding to the passed msgkey 161 * string. If the msgkey cannot be found, its value is returned 162 * as the output message text. 163 */ 164 public static final String msg (String msgkey) { 165 166 if (loadNeeded) 167 loadDefaultProperties (); 168 String msgtext = m.getProperty (msgkey, msgkey); 169 return msgtext; 170 171 } 172 173 /** 174 * Returns the message text corresponding to the passed msgkey 175 * string. The message text is assumed to require the insertion 176 * of a single argument, supplied by the "parm" parameter. 177 * If the message text does not contain the meta characters "%1" 178 * that indicate where to place the argument, the passed argument 179 * is appended at the end of the message text. 180 * <p> 181 * If the msgkey cannot be found, its value is used as the 182 * message text. 183 */ 184 public static final String msg (String msgkey, String parm) { 185 186 if (loadNeeded) 187 loadDefaultProperties (); 188 String msgtext = m.getProperty (msgkey, msgkey); 189 int i = msgtext.indexOf ("%1"); 190 if (i >= 0) { 191 String ending = ""; 192 if ((i+2) < msgtext.length ()) 193 ending = msgtext.substring (i+2); 194 return msgtext.substring (0, i) + parm + ending; 195 } else 196 msgtext += " " + parm; 197 return msgtext; 198 199 } 200 201 /** 202 * Returns the message text corresponding to the passed msgkey 203 * string. The message text is assumed to require the insertion 204 * of a single argument, supplied by the "parm" parameter. 205 * If the message text does not contain the meta characters "%1" 206 * that indicate where to place the argument, the passed argument 207 * is appended at the end of the message text. 208 * <p> 209 * If the msgkey cannot be found, its value is used as the 210 * message text. 211 */ 212 public static final String msg (String msgkey, int parm) { 213 214 return msg (msgkey, String.valueOf (parm)); 215 216 } 217 218 /** 219 * Returns the message text corresponding to the passed msgkey 220 * string. The message text is assumed to require the insertion 221 * of two arguments, supplied by the "parm1" and "parm2" parameters. 222 * If the message text does not contain the meta characters "%1" and 223 * "%2" that indicate where to place the arguments, the passed arguments 224 * are appended at the end of the message text. 225 * <p> 226 * If the msgkey cannot be found, its value is used as the 227 * message text. 228 */ 229 public static final String msg (String msgkey, String parm1, String parm2) { 230 231 if (loadNeeded) 232 loadDefaultProperties (); 233 String result = m.getProperty (msgkey, msgkey); 234 String ending = ""; 235 int i = result.indexOf ("%1"); 236 if (i >= 0) { 237 if ((i+2) < result.length ()) 238 ending = result.substring (i+2); 239 result = result.substring (0, i) + parm1 + ending; 240 } else 241 result += " " + parm1; 242 i = result.indexOf ("%2"); 243 if (i >= 0) { 244 ending = ""; 245 if ((i+2) < result.length ()) 246 ending = result.substring (i+2); 247 result = result.substring (0, i) + parm2 + ending; 248 } else 249 result += " " + parm2; 250 return result; 251 252 } 253 254 /** 255 * Returns the message text corresponding to the passed msgkey 256 * string. The message text is assumed to require the insertion 257 * of two arguments, supplied by the "parm1" and "parm2" parameters. 258 * If the message text does not contain the meta characters "%1" and 259 * "%2" that indicate where to place the arguments, the passed arguments 260 * are appended at the end of the message text. 261 * <p> 262 * If the msgkey cannot be found, its value is used as the 263 * message text. 264 */ 265 public static final String msg (String msgkey, int parm1, String parm2) { 266 267 return msg (msgkey, String.valueOf (parm1), parm2); 268 269 } 270 271 /** 272 * Returns the message text corresponding to the passed msgkey 273 * string. The message text is assumed to require the insertion 274 * of two arguments, supplied by the "parm1" and "parm2" parameters. 275 * If the message text does not contain the meta characters "%1" and 276 * "%2" that indicate where to place the arguments, the passed arguments 277 * are appended at the end of the message text. 278 * <p> 279 * If the msgkey cannot be found, its value is used as the 280 * message text. 281 */ 282 public static final String msg (String msgkey, String parm1, int parm2) { 283 284 return msg (msgkey, parm1, String.valueOf (parm2)); 285 286 } 287 288 /** 289 * Returns the message text corresponding to the passed msgkey 290 * string. The message text is assumed to require the insertion 291 * of two arguments, supplied by the "parm1" and "parm2" parameters. 292 * If the message text does not contain the meta characters "%1" and 293 * "%2" that indicate where to place the arguments, the passed arguments 294 * are appended at the end of the message text. 295 * <p> 296 * If the msgkey cannot be found, its value is used as the 297 * message text. 298 */ 299 public static final String msg (String msgkey, int parm1, int parm2) { 300 301 return msg (msgkey, String.valueOf (parm1), String.valueOf (parm2)); 302 303 } 304 305 306 /** 307 * Returns the message text corresponding to the passed msgkey 308 * string. The message text is assumed to require the insertion 309 * of three arguments, supplied by the "parm1", "parm2" and "parm3" 310 * parameters. 311 * If the message text does not contain the meta characters "%1" and 312 * "%2" that indicate where to place the arguments, the passed arguments 313 * are appended at the end of the message text. 314 * <p> 315 * If the msgkey cannot be found, its value is used as the 316 * message text. 317 */ 318 public static final String msg (String msgkey, String parm1, 319 String parm2, String parm3) { 320 if (loadNeeded) 321 loadDefaultProperties (); 322 String result = m.getProperty (msgkey, msgkey); 323 result = substituteString(result, 1, parm1); 324 result = substituteString(result, 2, parm2); 325 result = substituteString(result, 3, parm3); 326 327 return result; 328 } 329 330 /* helper function for string substition. 331 @return the substituted string, it substitution is possible. 332 Otherwise, return a new string with subst at the end. 333 @orig: original string 334 @paramNum the parameter number to search. For example, 335 paramNam == 1 means search for "%1". 336 @subst: string for the substitution. 337 */ 338 private static String substituteString(String orig, int paramNum, 339 String subst){ 340 String result = orig; 341 String paramSubst = "%"+ paramNum; 342 int len = paramSubst.length(); 343 int index = result.indexOf (paramSubst); 344 String ending = ""; 345 if (index >= 0) { 346 if ((index+len) < result.length ()) 347 ending = result.substring (index+len); 348 result = result.substring (0, index) + subst + ending; 349 } 350 else result += " " + subst; 351 352 return result; 353 } 354 355 356 }