blob: 7f8afbc9a4549695898624f8914d8d97d4c0bee6 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.opensymphony.xwork2;
import com.opensymphony.xwork2.inject.Inject;
import com.opensymphony.xwork2.util.ValueStack;
import java.util.*;
/**
* Default TextProvider implementation.
*
* @author Jason Carreira
* @author Rainer Hermanns
*/
public class TextProviderSupport implements ResourceBundleTextProvider {
protected Class clazz;
protected LocaleProvider localeProvider;
protected ResourceBundle bundle;
protected LocalizedTextProvider localizedTextProvider;
/**
* Constructor.
*
* @param clazz a clazz to use for reading the resource bundle.
* @param provider a locale provider.
*/
public TextProviderSupport(Class clazz, LocaleProvider provider, LocalizedTextProvider localizedTextProvider) {
this.clazz = clazz;
this.localeProvider = provider;
this.localizedTextProvider = localizedTextProvider;
}
/**
* Constructor.
*
* @param bundle the resource bundle.
* @param provider a locale provider.
*/
public TextProviderSupport(ResourceBundle bundle, LocaleProvider provider, LocalizedTextProvider localizedTextProvider) {
this.bundle = bundle;
this.localeProvider = provider;
this.localizedTextProvider = localizedTextProvider;
}
/**
* @param bundle the resource bundle.
*/
@Override
public void setBundle(ResourceBundle bundle) {
this.bundle = bundle;
}
/**
* @param clazz a clazz to use for reading the resource bundle.
*/
@Override
public void setClazz(Class clazz) {
this.clazz = clazz;
}
/**
* @param localeProvider a locale provider.
*/
@Override
public void setLocaleProvider(LocaleProvider localeProvider) {
this.localeProvider = localeProvider;
}
@Inject
public void setLocaleProviderFactory(LocaleProviderFactory localeProviderFactory) {
this.localeProvider = localeProviderFactory.createLocaleProvider();
}
@Inject
public void setLocalizedTextProvider(LocalizedTextProvider localizedTextProvider) {
this.localizedTextProvider = localizedTextProvider;
}
/**
* Checks if a key is available in the resource bundles associated with this action.
* The resource bundles are searched, starting with the one associated
* with this particular action, and testing all its superclasses' bundles.
* It will stop once a bundle is found that contains the given text. This gives
* a cascading style that allow global texts to be defined for an application base
* class.
*/
public boolean hasKey(String key) {
String message;
if (clazz != null) {
message = localizedTextProvider.findText(clazz, key, getLocale(), null, new Object[0] );
} else {
message = localizedTextProvider.findText(bundle, key, getLocale(), null, new Object[0]);
}
return message != null;
}
/**
* Get a text from the resource bundles associated with this action.
* The resource bundles are searched, starting with the one associated
* with this particular action, and testing all its superclasses' bundles.
* It will stop once a bundle is found that contains the given text. This gives
* a cascading style that allow global texts to be defined for an application base
* class.
*
* @param key name of text to be found
* @return value of named text or the provided key if no value is found
*/
public String getText(String key) {
return getText(key, key, Collections.emptyList());
}
/**
* Get a text from the resource bundles associated with this action.
* The resource bundles are searched, starting with the one associated
* with this particular action, and testing all its superclasses' bundles.
* It will stop once a bundle is found that contains the given text. This gives
* a cascading style that allow global texts to be defined for an application base
* class. If no text is found for this text name, the default value is returned.
*
* @param key name of text to be found
* @param defaultValue the default value which will be returned if no text is found
* @return value of named text or the provided defaultValue if no value is found
*/
public String getText(String key, String defaultValue) {
return getText(key, defaultValue, Collections.emptyList());
}
/**
* Get a text from the resource bundles associated with this action.
* The resource bundles are searched, starting with the one associated
* with this particular action, and testing all its superclasses' bundles.
* It will stop once a bundle is found that contains the given text. This gives
* a cascading style that allow global texts to be defined for an application base
* class. If no text is found for this text name, the default value is returned.
*
* @param key name of text to be found
* @param defaultValue the default value which will be returned if no text is found
* @return value of named text or the provided defaultValue if no value is found
*/
public String getText(String key, String defaultValue, String arg) {
List<Object> args = new ArrayList<>();
args.add(arg);
return getText(key, defaultValue, args);
}
/**
* Get a text from the resource bundles associated with this action.
* The resource bundles are searched, starting with the one associated
* with this particular action, and testing all its superclasses' bundles.
* It will stop once a bundle is found that contains the given text. This gives
* a cascading style that allow global texts to be defined for an application base
* class. If no text is found for this text name, the default value is returned.
*
* @param key name of text to be found
* @param args a List of args to be used in a MessageFormat message
* @return value of named text or the provided key if no value is found
*/
public String getText(String key, List<?> args) {
return getText(key, key, args);
}
/**
* Get a text from the resource bundles associated with this action.
* The resource bundles are searched, starting with the one associated
* with this particular action, and testing all its superclasses' bundles.
* It will stop once a bundle is found that contains the given text. This gives
* a cascading style that allow global texts to be defined for an application base
* class. If no text is found for this text name, the default value is returned.
*
* @param key name of text to be found
* @param args an array of args to be used in a MessageFormat message
* @return value of named text or the provided key if no value is found
*/
public String getText(String key, String[] args) {
return getText(key, key, args);
}
/**
* Get a text from the resource bundles associated with this action.
* The resource bundles are searched, starting with the one associated
* with this particular action, and testing all its superclasses' bundles.
* It will stop once a bundle is found that contains the given text. This gives
* a cascading style that allow global texts to be defined for an application base
* class. If no text is found for this text name, the default value is returned.
*
* @param key name of text to be found
* @param defaultValue the default value which will be returned if no text is found
* @param args a List of args to be used in a MessageFormat message
* @return value of named text or the provided defaultValue if no value is found
*/
public String getText(String key, String defaultValue, List<?> args) {
Object[] argsArray = ((args != null && !args.equals(Collections.emptyList())) ? args.toArray() : null);
if (clazz != null) {
return localizedTextProvider.findText(clazz, key, getLocale(), defaultValue, argsArray);
} else {
return localizedTextProvider.findText(bundle, key, getLocale(), defaultValue, argsArray);
}
}
/**
* Get a text from the resource bundles associated with this action.
* The resource bundles are searched, starting with the one associated
* with this particular action, and testing all its superclasses' bundles.
* It will stop once a bundle is found that contains the given text. This gives
* a cascading style that allow global texts to be defined for an application base
* class. If no text is found for this text name, the default value is returned.
*
* @param key name of text to be found
* @param defaultValue the default value which will be returned if no text is found
* @param args an array of args to be used in a MessageFormat message
* @return value of named text or the provided defaultValue if no value is found
*/
public String getText(String key, String defaultValue, String[] args) {
if (clazz != null) {
return localizedTextProvider.findText(clazz, key, getLocale(), defaultValue, args);
} else {
return localizedTextProvider.findText(bundle, key, getLocale(), defaultValue, args);
}
}
/**
* Gets a message based on a key using the supplied args, as defined in
* {@link java.text.MessageFormat}, or, if the message is not found, a supplied
* default value is returned. Instead of using the value stack in the ActionContext
* this version of the getText() method uses the provided value stack.
*
* @param key the resource bundle key that is to be searched for
* @param defaultValue the default value which will be returned if no message is found
* @param args a list args to be used in a {@link java.text.MessageFormat} message
* @param stack the value stack to use for finding the text
* @return the message as found in the resource bundle, or defaultValue if none is found
*/
public String getText(String key, String defaultValue, List<?> args, ValueStack stack) {
Object[] argsArray = ((args != null) ? args.toArray() : null);
Locale locale;
if (stack == null){
locale = getLocale();
}else{
locale = stack.getActionContext().getLocale();
}
if (locale == null) {
locale = getLocale();
}
if (clazz != null) {
return localizedTextProvider.findText(clazz, key, locale, defaultValue, argsArray, stack);
} else {
return localizedTextProvider.findText(bundle, key, locale, defaultValue, argsArray, stack);
}
}
/**
* Gets a message based on a key using the supplied args, as defined in
* {@link java.text.MessageFormat}, or, if the message is not found, a supplied
* default value is returned. Instead of using the value stack in the ActionContext
* this version of the getText() method uses the provided value stack.
*
* @param key the resource bundle key that is to be searched for
* @param defaultValue the default value which will be returned if no message is found
* @param args an array args to be used in a {@link java.text.MessageFormat} message
* @param stack the value stack to use for finding the text
* @return the message as found in the resource bundle, or defaultValue if none is found
*/
public String getText(String key, String defaultValue, String[] args, ValueStack stack) {
Locale locale;
if (stack == null){
locale = getLocale();
}else{
locale = stack.getActionContext().getLocale();
}
if (locale == null) {
locale = getLocale();
}
if (clazz != null) {
return localizedTextProvider.findText(clazz, key, locale, defaultValue, args, stack);
} else {
return localizedTextProvider.findText(bundle, key, locale, defaultValue, args, stack);
}
}
/**
* Get the named bundle.
*
* <p>
* You can override the getLocale() methodName to change the behaviour of how
* to choose locale for the bundles that are returned. Typically you would
* use the TextProvider interface to get the users configured locale, or use
* your own methodName to allow the user to select the locale and store it in
* the session (by using the SessionAware interface).
* </p>
*
* @param aBundleName bundle name
* @return a resource bundle
*/
public ResourceBundle getTexts(String aBundleName) {
return localizedTextProvider.findResourceBundle(aBundleName, getLocale());
}
/**
* Get the resource bundle associated with this action.
* This will be based on the actual subclass that is used.
*
* @return resouce bundle
*/
public ResourceBundle getTexts() {
if (clazz != null) {
return getTexts(clazz.getName());
}
return bundle;
}
/**
* Get's the locale from the localeProvider.
*
* @return the locale from the localeProvider.
*/
private Locale getLocale() {
return localeProvider.getLocale();
}
}