001: package org.tigris.scarab.tools.localization;
002:
003: /* ================================================================
004: * Copyright (c) 2000 CollabNet. All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions are
008: * met:
009: *
010: * 1. Redistributions of source code must retain the above copyright
011: * notice, this list of conditions and the following disclaimer.
012: *
013: * 2. Redistributions in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in the
015: * documentation and/or other materials provided with the distribution.
016: *
017: * 3. The end-user documentation included with the redistribution, if
018: * any, must include the following acknowlegement: "This product includes
019: * software developed by CollabNet (http://www.collab.net/)."
020: * Alternately, this acknowlegement may appear in the software itself, if
021: * and wherever such third-party acknowlegements normally appear.
022: *
023: * 4. The hosted project names must not be used to endorse or promote
024: * products derived from this software without prior written
025: * permission. For written permission, please contact info@collab.net.
026: *
027: * 5. Products derived from this software may not use the "Tigris" name
028: * nor may "Tigris" appear in their names without prior written
029: * permission of CollabNet.
030: *
031: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
032: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
033: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
034: * IN NO EVENT SHALL COLLAB.NET OR ITS CONTRIBUTORS BE LIABLE FOR ANY
035: * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
036: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
037: * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
038: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
039: * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
040: * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
041: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
042: *
043: * ====================================================================
044: *
045: * This software consists of voluntary contributions made by many
046: * individuals on behalf of CollabNet.
047: */
048:
049: import org.tigris.scarab.tools.ScarabLocalizationTool;
050:
051: /**
052: * This class defines localizable messages. Each Resource
053: * may contain dynamic parameters ({$1}, {$2}, etc.) These
054: * parameters get resolved, when the ResourceBundle is called
055: * for the String representation of a specific Resource key.
056: *
057: * L10NMessage always contains an L10N key and may contain
058: * an arbitrary set of parameters, which will be used as values
059: * for the {$n} variables in the Resource.
060: *
061: * Note: We check for two special cases:
062: * <ol>
063: * <li>If a paramater is itself an L10NInstance, it will be resolved,
064: * before it's value is used.</li>
065: * <li>If a parameter is a scarabException, it is resolved, before
066: * it's value is used.</li>
067: * <li>If a parameter is an ordinary Exception, it's stored message is
068: * retrieved via Exception.getMessage() before it's value is used.
069: * </li>
070: * </ol>
071: * @author <a href="mailto:dabbous@saxess.com">Hussayn Dabbous</a>
072: */
073: public class L10NMessage implements Localizable {
074: /**
075: * The Localization key to be used.
076: */
077: LocalizationKey l10nKey;
078:
079: /**
080: * The list of localization parameters. may contain L10NInstnaces and
081: * Exceptions. May be null (no parameters)
082: */
083: private Object[] parameters;
084:
085: /**
086: * Constructor always needs the L10N key for creation.
087: * @param theKey
088: */
089: public L10NMessage(LocalizationKey theKey) {
090: l10nKey = theKey;
091: this .parameters = null;
092: }
093:
094: /**
095: * Constructor with parameters. theParameters is an array of objects
096: * and may contain Exceptions and
097: * L10NInstances.
098: * @param theKey
099: * @param theParameters
100: */
101: public L10NMessage(LocalizationKey theKey, Object[] theParameters) {
102: l10nKey = theKey;
103: this .parameters = theParameters;
104: }
105:
106: /**
107: * Convenience constructor with one extra parameter.
108: * @param theKey
109: * @param p1
110: */
111: public L10NMessage(LocalizationKey theKey, Object p1) {
112: this (theKey, new Object[] { p1 });
113: }
114:
115: /**
116: * Convenience constructor with two extra parameters.
117: * @param theKey
118: * @param p1
119: * @param p2
120: */
121: public L10NMessage(LocalizationKey theKey, Object p1, Object p2) {
122: this (theKey, new Object[] { p1, p2 });
123: }
124:
125: /**
126: * Convenience constructor with three extra parameters.
127: * @param theKey
128: * @param p1
129: * @param p2
130: * @param p3
131: */
132: public L10NMessage(LocalizationKey theKey, Object p1, Object p2,
133: Object p3) {
134: this (theKey, new Object[] { p1, p2, p3 });
135: }
136:
137: /**
138: * resolve the instance to the ScarabLocalizationTool.DEFAULT_LOCALE
139: * Note: This method returns english messages independent of
140: * any l10n settings. it is preferreable to use
141: * {@link resolve(ScarabLocalizationTool) }
142: * @return the resolved String
143: */
144: public String getMessage() {
145: ScarabLocalizationTool l10n = new ScarabLocalizationTool();
146: l10n.init(ScarabLocalizationTool.DEFAULT_LOCALE);
147: return getMessage(l10n);
148: }
149:
150: /**
151: * Format the message using the specified ScarabLocalizationTool instance.
152: * The parameters are resolved recursively if necessary.
153: * @return a localized <code>String</code> representation of this message.
154: */
155: public String getMessage(final ScarabLocalizationTool l10n) {
156: final int nbParameters = (parameters == null ? 0
157: : parameters.length);
158: final Object[] formatedParameters = new Object[nbParameters];
159: for (int index = 0; index < nbParameters; index++) {
160: Object param = parameters[index];
161: if (param instanceof Localizable) {
162: formatedParameters[index] = ((Localizable) param)
163: .getMessage(l10n);
164: } else if (param instanceof Throwable) {
165: // Note: We can not simply keep the parameter
166: // as is, because MessageFormat internally uses
167: // toString() which in turn should call Throwable.getLocalizedMessage()
168: // but:
169: // 1- Throwable.toString() is declared to use getMessage() even,
170: // when it also implements getLocalizedMessage()
171: // 2- Throwable.toString() also appends the class name, which we
172: // don't want.
173: //
174: // so we force the localize message ourselves:
175: Throwable t = (Throwable) param;
176: formatedParameters[index] = t.getLocalizedMessage();
177: } else {
178: formatedParameters[index] = param;
179: }
180: }
181: return l10n.format(l10nKey.toString(), formatedParameters);
182: }
183:
184: }
|