Messages.java revision 608:7e06bf1dcb09
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
37package com.sun.tools.corba.se.idl.som.cff;
38
39import java.io.IOException;
40import java.util.Enumeration;
41import java.util.Properties;
42import java.lang.String;
43import 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
63public 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}
357