001: /*****************************************************************************
002: * Java Plug-in Framework (JPF)
003: * Copyright (C) 2004-2005 Dmitry Olshansky
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation; either
008: * version 2.1 of the License, or (at your option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public
016: * License along with this library; if not, write to the Free Software
017: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: *****************************************************************************/package org.java.plugin.util;
019:
020: import java.util.Collection;
021: import java.util.Collections;
022: import java.util.HashMap;
023: import java.util.Locale;
024: import java.util.Map;
025: import java.util.MissingResourceException;
026: import java.util.ResourceBundle;
027:
028: /**
029: * Utility class to manage localization resources. This class is not for public
030: * usage but mainly for custom implementations developers to provide them
031: * uniform access and organization of locale specific data.
032: * <br>
033: * Class usage is very simple. Put your locale sensible data into
034: * <code>Resources.properties</code> files and save them near classes that you
035: * are going to get localized. For {@link java.util.Locale} to file mapping
036: * details see {@link ResourceBundle} documentation.
037: *
038: * @version $Id$
039: */
040: public final class ResourceManager {
041: private static final Object FAKE_BUNDLE = new Object();
042: private static final Map<String, Object> bundles = Collections
043: .synchronizedMap(new HashMap<String, Object>());
044:
045: /**
046: * @param packageName package name, used for
047: * <code>Resources.properties</code> file look-up
048: * @param messageKey message key
049: * @return message for {@link Locale#getDefault() default locale}
050: */
051: public static String getMessage(final String packageName,
052: final String messageKey) {
053: return getMessage(packageName, messageKey, Locale.getDefault(),
054: null);
055: }
056:
057: /**
058: * @param packageName package name, used for
059: * <code>Resources.properties</code> file look-up
060: * @param messageKey message key
061: * @param data data for parameter placeholders substitution, may be
062: * <code>Object</code>, <code>array</code> or
063: * <code>Collection</code>.
064: * @return message for {@link Locale#getDefault() default locale}
065: */
066: public static String getMessage(final String packageName,
067: final String messageKey, final Object data) {
068: return getMessage(packageName, messageKey, Locale.getDefault(),
069: data);
070: }
071:
072: /**
073: * @param packageName package name, used for
074: * <code>Resources.properties</code> file look-up
075: * @param messageKey message key
076: * @param locale locale to get message for
077: * @return message for given locale
078: */
079: public static String getMessage(final String packageName,
080: final String messageKey, final Locale locale) {
081: return getMessage(packageName, messageKey, locale, null);
082: }
083:
084: /**
085: * @param packageName package name, used for
086: * <code>Resources.properties</code> file look-up
087: * @param messageKey message key
088: * @param locale locale to get message for
089: * @param data data for parameter placeholders substitution, may be
090: * <code>Object</code>, <code>array</code> or
091: * <code>Collection</code>.
092: * @return message for given locale
093: */
094: public static String getMessage(final String packageName,
095: final String messageKey, final Locale locale,
096: final Object data) {
097: Object obj = bundles.get(packageName + '|' + locale);
098: if (obj == null) {
099: try {
100: obj = ResourceBundle.getBundle(packageName
101: + ".Resources", //$NON-NLS-1$
102: locale);
103: } catch (MissingResourceException mre) {
104: obj = FAKE_BUNDLE;
105: }
106: bundles.put(packageName + '|' + locale, obj);
107: }
108: if (obj == FAKE_BUNDLE) {
109: return "resource " + packageName + '.' + messageKey //$NON-NLS-1$
110: + " not found for locale " + locale; //$NON-NLS-1$
111: }
112: try {
113: String result = ((ResourceBundle) obj)
114: .getString(messageKey);
115: return (data == null) ? result
116: : processParams(result, data);
117: } catch (MissingResourceException mre) {
118: return "resource " + packageName + '.' + messageKey //$NON-NLS-1$
119: + " not found for locale " + locale; //$NON-NLS-1$
120: }
121: }
122:
123: private static String processParams(final String str,
124: final Object data) {
125: String result = str;
126: if ((data != null) && data.getClass().isArray()) {
127: Object[] params = (Object[]) data;
128: for (int i = 0; i < params.length; i++) {
129: result = replaceAll(result,
130: "{" + i + "}", "" + params[i]); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
131: }
132: } else if (data instanceof Collection) {
133: int i = 0;
134: for (Object object : (Collection) data) {
135: result = replaceAll(result,
136: "{" + i++ + "}", "" + object); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
137: }
138: } else {
139: result = replaceAll(result, "{0}", "" + data); //$NON-NLS-1$ //$NON-NLS-2$
140: }
141: return result;
142: }
143:
144: private static String replaceAll(final String str,
145: final String from, final String to) {
146: String result = str;
147: int p = 0;
148: while (true) {
149: p = result.indexOf(from, p);
150: if (p == -1) {
151: break;
152: }
153: result = result.substring(0, p) + to
154: + result.substring(p + from.length());
155: p += to.length();
156: }
157: return result;
158: }
159:
160: private ResourceManager() {
161: // no-op
162: }
163:
164: }
|