001/**
002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003 *
004 * Copyright (c) 2005 Sun Microsystems Inc. All Rights Reserved
005 *
006 * The contents of this file are subject to the terms
007 * of the Common Development and Distribution License
008 * (the License). You may not use this file except in
009 * compliance with the License.
010 *
011 * You can obtain a copy of the License at
012 * https://opensso.dev.java.net/public/CDDLv1.0.html or
013 * opensso/legal/CDDLv1.0.txt
014 * See the License for the specific language governing
015 * permission and limitations under the License.
016 *
017 * When distributing Covered Code, include this CDDL
018 * Header Notice in each file and include the License file
019 * at opensso/legal/CDDLv1.0.txt.
020 * If applicable, add the following below the CDDL Header,
021 * with the fields enclosed by brackets [] replaced by
022 * your own identifying information:
023 * "Portions Copyrighted [year] [name of copyright owner]"
024 *
025 * $Id: I18n.java,v 1.3 2008/06/25 05:41:41 qcheng Exp $
026 *
027 */
028
029/**
030 * Portions Copyrighted [2011] [ForgeRock AS]
031 */
032package com.iplanet.services.util;
033
034import java.io.UnsupportedEncodingException;
035import java.text.DateFormat;
036import java.text.MessageFormat;
037import java.util.Date;
038import java.util.HashMap;
039import java.util.Map;
040import java.util.ResourceBundle;
041import java.util.StringTokenizer;
042import java.util.TimeZone;
043
044/**
045 * The <code>I18n</code> class provides methods for applications and services
046 * to internationalize their messages.
047 * <p>
048 * In order for <code>I18n</code> to internationalize messages, it needs to
049 * determine the resource bundle name, i.e., properties file name.
050 * <code>I18n</code> supports two techniques by which applications and
051 * services can specify their I18N resource bundle name. The recommendation is
052 * to specify them during service (or application) registration via <b> SMS</b>
053 * using a XML file (see <code>com.iplanet.services.ServiceManager
054 * </code> and
055 * service registration DTD). The XML file could specify the resource bundle
056 * name (the attribute defined in the DTD is <code>i18nFileName</code>) and
057 * optionally URL of the jar file which contains the property file (the
058 * attribute defined in the DTD is <code>resourceBundleURL</code>). If URL
059 * for the jar file is not specified it is assumed that the resource bundle is
060 * in the <code>
061 * CLASSPATH</code>. Using this technique it is possible to
062 * customize resource bundle name and URL of the jar file by using SMS APIs,
063 * commands (CLI) or GUI. The solution makes internationalization of messages
064 * very dynamic and highly customizable.
065 * <p>
066 * <code>I18n</code> class be instantiated by calling the static
067 * <code>getInstance(String serviceName)</code> method. The parameter
068 * <code>serviceName</code> specifies the name of the service as mentioned in
069 * the XML file at the time of service registration.
070 * <p>
071 * Alternatively services and application can instantiate <code>I18n</code>
072 * object by specifying the resource bundle name (i.e., properties file name).
073 * Using this technique it is not possible to customize at runtime either the
074 * resource bundle name or the URL of the jar file that contains the properties
075 * file name. It is assumed that the properties file is present in
076 * <code>CLASSPATH</code>
077 *
078 * @supported.api
079 */
080public class I18n {
081
082    /* ASCII ISO */
083    public static final String ASCII_CHARSET = "ISO-8859-1";
084
085    /* Static varibale that holds all the I18n objects */
086    private static Map i18nMap = new HashMap();
087
088    // private static SSOToken userSSOToken = null;
089
090    /* Instance variable */
091    private boolean initialized = false;
092
093    private String serviceName = null;
094
095    private String i18nFile = null;
096
097    private ClassLoader ucl = null;
098
099    private Map resourceBundles = new HashMap();
100
101    /**
102     * This constructor takes the name of the component as an argument and it
103     * should match with name of the resource bundle
104     */
105    protected I18n(String serviceName) {
106        this.serviceName = serviceName;
107    }
108
109    private void initialize() {
110        if (initialized)
111            return;
112
113        // %%% Hack to get around cyclic dependency on I18n
114        // and other components that call I18n
115        i18nFile = serviceName;
116        initialized = true;
117    }
118
119    /**
120     * Method to get an instance of I18n object that has been either previously
121     * created or to obtain a new instance if it does'nt exist
122     * 
123     * @param serviceName
124     *            name of the service for which messages must be
125     *            internationalized
126     * @return I18n object
127     * @supported.api
128     */
129    public static I18n getInstance(String serviceName) {
130        if (serviceName == null)
131            return (null);
132
133        I18n i18nobj = null;
134        synchronized (i18nMap) {
135            if ((i18nobj = (I18n) i18nMap.get(serviceName)) == null) {
136                i18nobj = new I18n(serviceName);
137                i18nMap.put(serviceName, i18nobj);
138            }
139        }
140        return (i18nobj);
141    }
142
143    /**
144     * Method to obtain Locale object given its string representation
145     * 
146     * @param stringformat
147     *            Locale in a string format
148     * @return Locale object
149     */
150    public static java.util.Locale getLocale(String stringformat) {
151        if (stringformat == null)
152            return java.util.Locale.getDefault();
153
154        StringTokenizer tk = new StringTokenizer(stringformat, "_");
155        String lang = "";
156        String country = "";
157        String variant = "";
158        if (tk.hasMoreTokens())
159            lang = tk.nextToken();
160        if (tk.hasMoreTokens())
161            country = tk.nextToken();
162        if (tk.hasMoreTokens())
163            variant = tk.nextToken();
164        return (new java.util.Locale(lang, country, variant));
165    }
166
167    /**
168     * Returns the resource file name associated with the service
169     * 
170     * @return Returns the the ResourceBundle name associated with the service
171     */
172    public String getResBundleName() {
173        initialize();
174        return i18nFile;
175    }
176
177    /* Gets the resource bundle */
178    private synchronized ResourceBundle getResourceBundle(String stringformat) {
179        ResourceBundle bundle = (ResourceBundle) resourceBundles
180                .get(stringformat);
181        if (bundle == null) {
182            if (ucl != null) {
183                bundle = ResourceBundle.getBundle(i18nFile,
184                        getLocale(stringformat), ucl);
185            } else {
186                bundle = ResourceBundle.getBundle(i18nFile,
187                        getLocale(stringformat));
188            }
189            if (initialized)
190                resourceBundles.put(stringformat, bundle);
191        }
192        return (bundle);
193    }
194
195    /* Get the default locale stored in config */
196    private static String getDefaultLocale() {
197        String loc = "en_US";
198
199        /* %%% Get the default locale stored in config - to be implemented */
200        return (loc);
201    }
202
203    /**
204     * Method to obtain internationalized message from the
205     * resource bundle given the key and locale.
206     * 
207     * @param key
208     *            key string in the properties file
209     * @param locale
210     *            locale in a string format
211     * @return returns internationalized message for the specified key
212     * @supported.api
213     */
214    public String getString(String key, String locale) {
215        initialize();
216        if (key == null) {
217            return null;
218        }
219        ResourceBundle bundle = getResourceBundle(locale);
220        return (bundle.getString(key));
221    }
222
223    /**
224     * Method to obtain internationalized message from the
225     * resource bundle given the key.
226     * 
227     * @param key
228     *            Key string in the properties file
229     * @return Returns value to the specified key
230     * @supported.api
231     */
232    public String getString(String key) {
233        initialize();
234        if (key == null) {
235            return null;
236        }
237        ResourceBundle bundle = getResourceBundle(getDefaultLocale());
238        return (bundle.getString(key));
239    }
240
241    /**
242     * Method to obtain internationalized message from the
243     * resource bundle given the key, locale and parameters.
244     * 
245     * @param key
246     *            key string in the properties file
247     * @param locale
248     *            locale in a string format
249     * @param params
250     *            parameters to be applied to the message
251     * @return returns internationalized message for the specified key
252     * @supported.api
253     */
254    public String getString(String key, String locale, Object[] params) {
255        initialize();
256        if (key == null)
257            return (null);
258        return (MessageFormat.format(getString(key, locale), params));
259    }
260
261    /**
262     * Method to obtain internationalized message from the
263     * resource bundle given the key and parameters.
264     * 
265     * @param key
266     *            Key string in the properties file
267     * @param params
268     *            parameters to be applied to the message
269     * @return Returns value to the specified key
270     * @supported.api
271     */
272    public String getString(String key, Object[] params) {
273        initialize();
274        if (key == null)
275            return (null);
276        return (MessageFormat.format(getString(key), params));
277    }
278
279    /**
280     * Decodes the string into specified charset
281     * 
282     * @param s
283     *            string to be decoded
284     * @param charset
285     *            character set in which the string to be decoded
286     * @return Returns the decoded string
287     */
288    public static String decodeCharset(String s, String charset) {
289        if (s == null) {
290            return null;
291        }
292
293        try {
294            byte buf[] = s.getBytes(ASCII_CHARSET);
295            return (new String(buf, 0, buf.length, charset));
296        } catch (UnsupportedEncodingException uee) {
297            return s;
298        }
299    }
300
301    /**
302     * Checks whether the string is ascii or not
303     * 
304     * @param s
305     *            string to be checked
306     * @return true if the string is ascii, otherwise false
307     */
308    public static boolean isAscii(String s) {
309        if (s == null) {
310            return true;
311        }
312
313        try {
314            if (!s.equals(new String(s.getBytes(ASCII_CHARSET), ASCII_CHARSET)))
315            {
316                return false;
317            }
318        } catch (java.io.UnsupportedEncodingException uee) {
319            return false;
320        }
321        return true;
322    }
323
324    private static String format(MessageFormat mf, Object o) {
325        String msg = mf.format(new Object[] { o }, new StringBuffer(), null)
326                .toString();
327        return msg;
328    }
329
330    /**
331     * Formats the objects into specified message format.
332     * 
333     * @param pattern
334     *            pattern for which the message to be formatted
335     * @param j
336     *            Object to be formatted & substituted
337     * @param l
338     *            locale in a string format
339     * @return Returns the formatted message
340     */
341    public static String format(String pattern, Long j, String l) {
342        MessageFormat mf = new MessageFormat("");
343        mf.setLocale(getLocale(l));
344        mf.applyPattern(pattern);
345        String msg = format(mf, j);
346
347        return msg;
348    }
349
350    /**
351     * Formats the objects into specified message format.
352     * 
353     * @param pattern
354     *            pattern for which the message to be formatted
355     * @param i
356     *            Integer to be formatted & substituted
357     * @param l
358     *            locale in a string format
359     * @return Returns the formatted message
360     */
361    public static String format(String pattern, Integer i, String l) {
362        MessageFormat mf = new MessageFormat("");
363        mf.setLocale(getLocale(l));
364        mf.applyPattern(pattern);
365        String msg = format(mf, i);
366
367        return msg;
368    }
369
370    /**
371     * Formats the objects into specified message format
372     * 
373     * @param pattern
374     *            pattern for which the message to be formatted
375     * @param d
376     *            date
377     * @param tz
378     *            Timezone
379     * @param l
380     *            locale in a string format
381     * @return Returns the formatted message
382     */
383    public static String format(String pattern, Date d, TimeZone tz, String l) {
384
385        MessageFormat mf = new MessageFormat("");
386        mf.setLocale(getLocale(l));
387        mf.applyPattern(pattern);
388        ((DateFormat) mf.getFormats()[0]).setTimeZone(tz);
389
390        DateFormat df1 = ((DateFormat) mf.getFormats()[0]);
391        if (df1 != null) {
392            df1.setTimeZone(tz);
393        }
394
395        DateFormat df2 = ((DateFormat) mf.getFormats()[1]);
396        if (df2 != null) {
397            df2.setTimeZone(tz);
398        }
399
400        return format(mf, d);
401    }
402}




























































Copyright © 2010-2017, ForgeRock All Rights Reserved.