mirror of
https://github.com/apache/struts.git
synced 2026-08-07 15:46:57 +00:00
Merge pull request #1113 from apache/feature/WW-5481-text
WW-5481 Extract text related classes into org.apache.struts2.text
This commit is contained in:
@@ -25,6 +25,8 @@ import org.apache.struts2.conversion.impl.ConversionData;
|
||||
import org.apache.struts2.inject.Container;
|
||||
import org.apache.struts2.inject.Inject;
|
||||
import org.apache.struts2.interceptor.ValidationAware;
|
||||
import org.apache.struts2.text.TextProvider;
|
||||
import org.apache.struts2.text.TextProviderFactory;
|
||||
import org.apache.struts2.util.ValueStack;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.text.StringEscapeUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.text.LocalizedTextProvider;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
@@ -23,15 +23,14 @@ import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
|
||||
/**
|
||||
* Indicates that the implementing class can provide its own {@link Locale}.
|
||||
*
|
||||
* <p>
|
||||
* This is useful for when an action may wish override the default locale. All that is
|
||||
* needed is to implement this interface and return your own custom locale.
|
||||
* The {@link TextProvider} interface uses this interface heavily for retrieving
|
||||
* internationalized messages from resource bundles.
|
||||
* The {@link org.apache.struts2.text.TextProvider} interface uses this interface
|
||||
* heavily for retrieving internationalized messages from resource bundles.
|
||||
* </p>
|
||||
*
|
||||
* @author Jason Carreira
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* 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 org.apache.struts2;
|
||||
|
||||
import org.apache.struts2.util.ValueStack;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Locale;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
public interface LocalizedTextProvider extends Serializable {
|
||||
|
||||
String findDefaultText(String aTextName, Locale locale);
|
||||
|
||||
String findDefaultText(String aTextName, Locale locale, Object[] params);
|
||||
|
||||
ResourceBundle findResourceBundle(String aBundleName, Locale locale);
|
||||
|
||||
String findText(Class aClass, String aTextName, Locale locale);
|
||||
|
||||
String findText(Class aClass, String aTextName, Locale locale, String defaultMessage, Object[] args);
|
||||
|
||||
String findText(Class aClass, String aTextName, Locale locale, String defaultMessage, Object[] args, ValueStack valueStack);
|
||||
|
||||
String findText(ResourceBundle bundle, String aTextName, Locale locale);
|
||||
|
||||
String findText(ResourceBundle bundle, String aTextName, Locale locale, String defaultMessage, Object[] args);
|
||||
|
||||
String findText(ResourceBundle bundle, String aTextName, Locale locale, String defaultMessage, Object[] args, ValueStack valueStack);
|
||||
|
||||
void addDefaultResourceBundle(String resourceBundleName);
|
||||
|
||||
}
|
||||
@@ -18,7 +18,7 @@
|
||||
*/
|
||||
package org.apache.struts2.components;
|
||||
|
||||
import org.apache.struts2.TextProvider;
|
||||
import org.apache.struts2.text.TextProvider;
|
||||
import org.apache.struts2.inject.Inject;
|
||||
import org.apache.struts2.util.ValueStack;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
|
||||
@@ -22,14 +22,14 @@ import java.io.Writer;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import org.apache.struts2.LocaleProviderFactory;
|
||||
import org.apache.struts2.LocalizedTextProvider;
|
||||
import org.apache.struts2.TextProviderFactory;
|
||||
import org.apache.struts2.text.LocalizedTextProvider;
|
||||
import org.apache.struts2.text.TextProviderFactory;
|
||||
import org.apache.struts2.views.annotations.StrutsTag;
|
||||
import org.apache.struts2.views.annotations.StrutsTagAttribute;
|
||||
import org.apache.struts2.StrutsException;
|
||||
|
||||
import org.apache.struts2.LocaleProvider;
|
||||
import org.apache.struts2.TextProvider;
|
||||
import org.apache.struts2.text.TextProvider;
|
||||
import org.apache.struts2.inject.Inject;
|
||||
import org.apache.struts2.util.ValueStack;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
|
||||
@@ -23,11 +23,11 @@ import org.apache.struts2.ActionProxyFactory;
|
||||
import org.apache.struts2.FileManager;
|
||||
import org.apache.struts2.FileManagerFactory;
|
||||
import org.apache.struts2.LocaleProviderFactory;
|
||||
import org.apache.struts2.LocalizedTextProvider;
|
||||
import org.apache.struts2.text.LocalizedTextProvider;
|
||||
import org.apache.struts2.ObjectFactory;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
import org.apache.struts2.TextProvider;
|
||||
import org.apache.struts2.TextProviderFactory;
|
||||
import org.apache.struts2.text.TextProvider;
|
||||
import org.apache.struts2.text.TextProviderFactory;
|
||||
import org.apache.struts2.UnknownHandlerManager;
|
||||
import org.apache.struts2.components.UrlRenderer;
|
||||
import org.apache.struts2.components.date.DateFormatter;
|
||||
|
||||
@@ -20,15 +20,15 @@ package org.apache.struts2.config.impl;
|
||||
|
||||
import org.apache.struts2.ActionContext;
|
||||
import org.apache.struts2.DefaultLocaleProviderFactory;
|
||||
import org.apache.struts2.DefaultTextProvider;
|
||||
import org.apache.struts2.text.DefaultTextProvider;
|
||||
import org.apache.struts2.FileManager;
|
||||
import org.apache.struts2.FileManagerFactory;
|
||||
import org.apache.struts2.LocaleProviderFactory;
|
||||
import org.apache.struts2.LocalizedTextProvider;
|
||||
import org.apache.struts2.text.LocalizedTextProvider;
|
||||
import org.apache.struts2.ObjectFactory;
|
||||
import org.apache.struts2.StrutsTextProviderFactory;
|
||||
import org.apache.struts2.TextProvider;
|
||||
import org.apache.struts2.TextProviderFactory;
|
||||
import org.apache.struts2.text.StrutsTextProviderFactory;
|
||||
import org.apache.struts2.text.TextProvider;
|
||||
import org.apache.struts2.text.TextProviderFactory;
|
||||
import org.apache.struts2.config.Configuration;
|
||||
import org.apache.struts2.config.ConfigurationException;
|
||||
import org.apache.struts2.config.ContainerProvider;
|
||||
@@ -92,7 +92,7 @@ import org.apache.struts2.ognl.accessor.RootAccessor;
|
||||
import org.apache.struts2.ognl.accessor.XWorkMethodAccessor;
|
||||
import org.apache.struts2.util.OgnlTextParser;
|
||||
import org.apache.struts2.util.PatternMatcher;
|
||||
import org.apache.struts2.util.StrutsLocalizedTextProvider;
|
||||
import org.apache.struts2.text.StrutsLocalizedTextProvider;
|
||||
import org.apache.struts2.util.TextParser;
|
||||
import org.apache.struts2.util.ValueStack;
|
||||
import org.apache.struts2.util.ValueStackFactory;
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
package org.apache.struts2.conversion.impl;
|
||||
|
||||
import org.apache.struts2.ActionContext;
|
||||
import org.apache.struts2.TextProvider;
|
||||
import org.apache.struts2.text.TextProvider;
|
||||
import org.apache.struts2.util.ValueStack;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
@@ -21,7 +21,7 @@ package org.apache.struts2.conversion.impl;
|
||||
import org.apache.struts2.ActionContext;
|
||||
import org.apache.struts2.FileManager;
|
||||
import org.apache.struts2.FileManagerFactory;
|
||||
import org.apache.struts2.LocalizedTextProvider;
|
||||
import org.apache.struts2.text.LocalizedTextProvider;
|
||||
import org.apache.struts2.conversion.ConversionAnnotationProcessor;
|
||||
import org.apache.struts2.conversion.ConversionFileProcessor;
|
||||
import org.apache.struts2.conversion.TypeConverter;
|
||||
|
||||
+2
-4
@@ -20,12 +20,10 @@ package org.apache.struts2.interceptor;
|
||||
|
||||
import org.apache.struts2.LocaleProvider;
|
||||
import org.apache.struts2.LocaleProviderFactory;
|
||||
import org.apache.struts2.TextProvider;
|
||||
import org.apache.struts2.TextProviderFactory;
|
||||
import org.apache.struts2.text.TextProvider;
|
||||
import org.apache.struts2.text.TextProviderFactory;
|
||||
import org.apache.struts2.inject.Container;
|
||||
import org.apache.struts2.inject.Inject;
|
||||
import org.apache.struts2.interceptor.AbstractInterceptor;
|
||||
import org.apache.struts2.interceptor.ValidationAware;
|
||||
import org.apache.struts2.util.TextParseUtil;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
@@ -22,7 +22,7 @@ import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.ActionContext;
|
||||
import org.apache.struts2.ActionInvocation;
|
||||
import org.apache.struts2.LocalizedTextProvider;
|
||||
import org.apache.struts2.text.LocalizedTextProvider;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
import org.apache.struts2.config.entities.ActionConfig;
|
||||
import org.apache.struts2.dispatcher.HttpParameters;
|
||||
|
||||
@@ -23,7 +23,7 @@ import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.ActionContext;
|
||||
import org.apache.struts2.ActionInvocation;
|
||||
import org.apache.struts2.LocalizedTextProvider;
|
||||
import org.apache.struts2.text.LocalizedTextProvider;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
import org.apache.struts2.config.entities.ActionConfig;
|
||||
import org.apache.struts2.config.entities.Parameterizable;
|
||||
|
||||
@@ -19,11 +19,9 @@
|
||||
package org.apache.struts2.interceptor;
|
||||
|
||||
import org.apache.struts2.ActionInvocation;
|
||||
import org.apache.struts2.TextProvider;
|
||||
import org.apache.struts2.TextProviderFactory;
|
||||
import org.apache.struts2.interceptor.ValidationAware;
|
||||
import org.apache.struts2.text.TextProvider;
|
||||
import org.apache.struts2.text.TextProviderFactory;
|
||||
import org.apache.struts2.inject.Inject;
|
||||
import org.apache.struts2.interceptor.MethodFilterInterceptor;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.ServletActionContext;
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
package org.apache.struts2.ognl;
|
||||
|
||||
import org.apache.struts2.ActionContext;
|
||||
import org.apache.struts2.TextProvider;
|
||||
import org.apache.struts2.text.TextProvider;
|
||||
import org.apache.struts2.conversion.impl.XWorkConverter;
|
||||
import org.apache.struts2.inject.Container;
|
||||
import org.apache.struts2.inject.Inject;
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
*/
|
||||
package org.apache.struts2.ognl;
|
||||
|
||||
import org.apache.struts2.TextProvider;
|
||||
import org.apache.struts2.text.TextProvider;
|
||||
import org.apache.struts2.conversion.NullHandler;
|
||||
import org.apache.struts2.conversion.impl.XWorkConverter;
|
||||
import org.apache.struts2.inject.Container;
|
||||
|
||||
+97
-123
@@ -16,15 +16,16 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.struts2.util;
|
||||
package org.apache.struts2.text;
|
||||
|
||||
import org.apache.struts2.ActionContext;
|
||||
import org.apache.struts2.LocalizedTextProvider;
|
||||
import org.apache.struts2.inject.Inject;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.ActionContext;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
import org.apache.struts2.inject.Inject;
|
||||
import org.apache.struts2.util.TextParseUtil;
|
||||
import org.apache.struts2.util.ValueStack;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
@@ -66,24 +67,18 @@ abstract class AbstractLocalizedTextProvider implements LocalizedTextProvider {
|
||||
private final Set<String> missingBundles = ConcurrentHashMap.newKeySet();
|
||||
private final ConcurrentMap<Integer, ClassLoader> delegatedClassLoaderMap = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* Adds the bundle to the internal list of default bundles.
|
||||
* If the bundle already exists in the list it will be re-added.
|
||||
*
|
||||
* @param resourceBundleName the name of the bundle to add.
|
||||
*/
|
||||
@Override
|
||||
public void addDefaultResourceBundle(String resourceBundleName) {
|
||||
public void addDefaultResourceBundle(String bundleName) {
|
||||
//make sure this doesn't get added more than once
|
||||
final ClassLoader ccl = getCurrentThreadContextClassLoader();
|
||||
synchronized (XWORK_MESSAGES_BUNDLE) {
|
||||
List<String> bundles = classLoaderMap.computeIfAbsent(ccl.hashCode(), k -> new CopyOnWriteArrayList<>());
|
||||
bundles.remove(resourceBundleName);
|
||||
bundles.add(0, resourceBundleName);
|
||||
bundles.remove(bundleName);
|
||||
bundles.add(0, bundleName);
|
||||
}
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Added default resource bundle '{}' to default resource bundles for the following classloader '{}'", resourceBundleName, ccl.toString());
|
||||
LOG.debug("Added default resource bundle '{}' to default resource bundles for the following classloader '{}'", bundleName, ccl.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,16 +107,8 @@ abstract class AbstractLocalizedTextProvider implements LocalizedTextProvider {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a localized message for the specified key, aTextName. Neither the key nor the
|
||||
* message is evaluated.
|
||||
*
|
||||
* @param aTextName the message key
|
||||
* @param locale the locale the message should be for
|
||||
* @return a localized message based on the specified key, or null if no localized message can be found for it
|
||||
*/
|
||||
@Override
|
||||
public String findDefaultText(String aTextName, Locale locale) {
|
||||
public String findDefaultText(String textKey, Locale locale) {
|
||||
List<String> localList = getCurrentBundleNames();
|
||||
|
||||
for (String bundleName : localList) {
|
||||
@@ -129,7 +116,7 @@ abstract class AbstractLocalizedTextProvider implements LocalizedTextProvider {
|
||||
if (bundle != null) {
|
||||
reloadBundles();
|
||||
try {
|
||||
return bundle.getString(aTextName);
|
||||
return bundle.getString(textKey);
|
||||
} catch (MissingResourceException e) {
|
||||
// will be logged when not found in any bundle
|
||||
}
|
||||
@@ -137,26 +124,17 @@ abstract class AbstractLocalizedTextProvider implements LocalizedTextProvider {
|
||||
}
|
||||
|
||||
if (devMode) {
|
||||
LOG.warn("Missing key [{}] in bundles [{}]!", aTextName, localList);
|
||||
LOG.warn("Missing key [{}] in bundles [{}]!", textKey, localList);
|
||||
} else {
|
||||
LOG.debug("Missing key [{}] in bundles [{}]!", aTextName, localList);
|
||||
LOG.debug("Missing key [{}] in bundles [{}]!", textKey, localList);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a localized message for the specified key, aTextName, substituting variables from the
|
||||
* array of params into the message. Neither the key nor the message is evaluated.
|
||||
*
|
||||
* @param aTextName the message key
|
||||
* @param locale the locale the message should be for
|
||||
* @param params an array of objects to be substituted into the message text
|
||||
* @return A formatted message based on the specified key, or null if no localized message can be found for it
|
||||
*/
|
||||
@Override
|
||||
public String findDefaultText(String aTextName, Locale locale, Object[] params) {
|
||||
String defaultText = findDefaultText(aTextName, locale);
|
||||
public String findDefaultText(String textKey, Locale locale, Object[] params) {
|
||||
String defaultText = findDefaultText(textKey, locale);
|
||||
if (defaultText != null) {
|
||||
MessageFormat mf = buildMessageFormat(defaultText, locale);
|
||||
return formatWithNullDetection(mf, params);
|
||||
@@ -164,51 +142,27 @@ abstract class AbstractLocalizedTextProvider implements LocalizedTextProvider {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Finds a localized text message for the given key, aTextName, in the specified resource
|
||||
* bundle.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* If a message is found, it will also be interpolated. Anything within <code>${...}</code>
|
||||
* will be treated as an OGNL expression and evaluated as such.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* If a message is <b>not</b> found a WARN log will be logged.
|
||||
* </p>
|
||||
*
|
||||
* @param bundle the bundle
|
||||
* @param aTextName the key
|
||||
* @param locale the locale
|
||||
* @param defaultMessage the default message to use if no message was found in the bundle
|
||||
* @param args arguments for the message formatter.
|
||||
* @param valueStack the OGNL value stack.
|
||||
* @return the localized text, or null if none can be found and no defaultMessage is provided
|
||||
*/
|
||||
@Override
|
||||
public String findText(ResourceBundle bundle, String aTextName, Locale locale, String defaultMessage, Object[] args,
|
||||
public String findText(ResourceBundle bundle, String textKey, Locale locale, String defaultMessage, Object[] args,
|
||||
ValueStack valueStack) {
|
||||
try {
|
||||
reloadBundles(valueStack.getContext());
|
||||
|
||||
String message = TextParseUtil.translateVariables(bundle.getString(aTextName), valueStack);
|
||||
String message = TextParseUtil.translateVariables(bundle.getString(textKey), valueStack);
|
||||
MessageFormat mf = buildMessageFormat(message, locale);
|
||||
|
||||
return formatWithNullDetection(mf, args);
|
||||
} catch (MissingResourceException ex) {
|
||||
if (devMode) {
|
||||
LOG.warn("Missing key [{}] in bundle [{}]!", aTextName, bundle);
|
||||
LOG.warn("Missing key [{}] in bundle [{}]!", textKey, bundle);
|
||||
} else {
|
||||
LOG.debug("Missing key [{}] in bundle [{}]!", aTextName, bundle);
|
||||
LOG.debug("Missing key [{}] in bundle [{}]!", textKey, bundle);
|
||||
}
|
||||
}
|
||||
|
||||
GetDefaultMessageReturnArg result = getDefaultMessage(aTextName, locale, valueStack, args, defaultMessage);
|
||||
GetDefaultMessageReturnArg result = getDefaultMessage(textKey, locale, valueStack, args, defaultMessage);
|
||||
if (unableToFindTextForKey(result)) {
|
||||
LOG.warn("Unable to find text for key '{}' in ResourceBundles for locale '{}'", aTextName, locale);
|
||||
LOG.warn("Unable to find text for key '{}' in ResourceBundles for locale '{}'", textKey, locale);
|
||||
}
|
||||
return result != null ? result.message : null;
|
||||
}
|
||||
@@ -224,11 +178,10 @@ abstract class AbstractLocalizedTextProvider implements LocalizedTextProvider {
|
||||
|
||||
/**
|
||||
* Clear a specific bundle + locale combination from the <code>bundlesMap</code>.
|
||||
* Intended for descendants to use clear a bundle + locale combination.
|
||||
* Intended for descendants to use clear a bundle + locale combination.
|
||||
*
|
||||
* @param bundleName The bundle (combined with locale) to remove from the bundle map
|
||||
* @param locale Provides the locale to combine with the bundle to get the key
|
||||
*
|
||||
* @since 6.0.0
|
||||
*/
|
||||
protected void clearBundle(final String bundleName, Locale locale) {
|
||||
@@ -239,13 +192,13 @@ abstract class AbstractLocalizedTextProvider implements LocalizedTextProvider {
|
||||
|
||||
/**
|
||||
* Clears the <code>missingBundles</code> contents. This allows descendants to
|
||||
* clear the <b>"missing bundles cache"</b> when desired (or needed).
|
||||
*
|
||||
* clear the <b>"missing bundles cache"</b> when desired (or needed).
|
||||
* <p>
|
||||
* Note: This method may be used when the <code>bundlesMap</code> state has changed
|
||||
* in such a way that bundles that were previously "missing" may now be available
|
||||
* (e.g. after calling {@link #addDefaultResourceBundle(java.lang.String)} when the
|
||||
* {@link AbstractLocalizedTextProvider} has already been used for failed bundle
|
||||
* lookups of a given key, or some transitory state made a bundle lookup fail.
|
||||
* in such a way that bundles that were previously "missing" may now be available
|
||||
* (e.g. after calling {@link #addDefaultResourceBundle(java.lang.String)} when the
|
||||
* {@link AbstractLocalizedTextProvider} has already been used for failed bundle
|
||||
* lookups of a given key, or some transitory state made a bundle lookup fail.
|
||||
*
|
||||
* @since 6.0.0
|
||||
*/
|
||||
@@ -287,10 +240,10 @@ abstract class AbstractLocalizedTextProvider implements LocalizedTextProvider {
|
||||
|
||||
/**
|
||||
* A helper method for {@link ResourceBundle} bundle reload logic.
|
||||
*
|
||||
* <p>
|
||||
* Uses standard {@link ResourceBundle} methods to clear the bundle caches for the
|
||||
* {@link ClassLoader} instances that this class is aware of at the time of the call.
|
||||
*
|
||||
* <p>
|
||||
* The <code>clearCache()</code> methods have been available since Java 1.6, so
|
||||
* it is anticipated the logic will work on any subsequent JVM versions.
|
||||
*
|
||||
@@ -301,27 +254,29 @@ abstract class AbstractLocalizedTextProvider implements LocalizedTextProvider {
|
||||
ResourceBundle.clearCache(); // Bundles loaded by the caller's classloader.
|
||||
ResourceBundle.clearCache(ccl); // Bundles loaded by the context classloader (may be the same).
|
||||
// Clear the bundle cache for any non-null delegated classloaders.
|
||||
delegatedClassLoaderMap.forEach( (key, value) -> { if (value != null) ResourceBundle.clearCache(value) ;} );
|
||||
delegatedClassLoaderMap.forEach((key, value) -> {
|
||||
if (value != null) ResourceBundle.clearCache(value);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* "Hacky" helper method that attempts to clear the Tomcat <code>ResourceEntry</code>
|
||||
* {@link Map} using knowledge of the Tomcat source code.
|
||||
*
|
||||
* <p>
|
||||
* It relies on the {@link #TOMCAT_RESOURCE_ENTRIES_FIELD} field name, base class name
|
||||
* {@link #TOMCAT_WEBAPP_CLASSLOADER_BASE}. and descendant class names {@link #TOMCAT_WEBAPP_CLASSLOADER},
|
||||
* {@link #TOMCAT_PARALLEL_WEBAPP_CLASSLOADER}, to keep the values identified in the constants.
|
||||
* It appears to be valid for Tomcat versions 7-10 so far, but could become invalid at any time in the future
|
||||
* when the resource handling logic in Tomcat changes.
|
||||
*
|
||||
* <p>
|
||||
* Note: With Java 9+, calling this method may result in "Illegal reflective access" warnings. Be aware
|
||||
* its logic may fail in a future version of Java that blocks the reflection calls needed for this method.
|
||||
* its logic may fail in a future version of Java that blocks the reflection calls needed for this method.
|
||||
*/
|
||||
private void clearTomcatCache() {
|
||||
ClassLoader loader = getCurrentThreadContextClassLoader();
|
||||
// no need for compilation here.
|
||||
Class cl = loader.getClass();
|
||||
Class superCl = cl.getSuperclass();
|
||||
Class<?> cl = loader.getClass();
|
||||
Class<?> superCl = cl.getSuperclass();
|
||||
|
||||
try {
|
||||
if ((TOMCAT_WEBAPP_CLASSLOADER.equals(cl.getName()) || TOMCAT_PARALLEL_WEBAPP_CLASSLOADER.equals(cl.getName())) &&
|
||||
@@ -348,19 +303,19 @@ abstract class AbstractLocalizedTextProvider implements LocalizedTextProvider {
|
||||
|
||||
/**
|
||||
* Helper method that is intended to clear a {@link Map} instance by name.
|
||||
*
|
||||
* <p>
|
||||
* This method relies on reflection to perform its operations, and may be blocked in Java 9 and later,
|
||||
* depending on the accessibility of the field.
|
||||
*
|
||||
* @param cl The {@link Class} of the obj parameter.
|
||||
* @param obj The {@link Object} from which the named field is to be extracted (may be <code>null</code> for a static field).
|
||||
* @param cl The {@link Class} of the obj parameter.
|
||||
* @param obj The {@link Object} from which the named field is to be extracted (may be <code>null</code> for a static field).
|
||||
* @param name The name of the field containing a {@link Map} reference.
|
||||
* @throws NoSuchFieldException if a field accessed by this call does not exist.
|
||||
* @throws IllegalAccessException if a field, method or or class accessed by this call cannot be accessed.
|
||||
* @throws NoSuchMethodException if a method accessed by this call does not exist.
|
||||
* @throws NoSuchFieldException if a field accessed by this call does not exist.
|
||||
* @throws IllegalAccessException if a field, method or or class accessed by this call cannot be accessed.
|
||||
* @throws NoSuchMethodException if a method accessed by this call does not exist.
|
||||
* @throws InvocationTargetException if a method accessed by this call fails invocation.
|
||||
*/
|
||||
private void clearMap(Class cl, Object obj, String name)
|
||||
private void clearMap(Class<?> cl, Object obj, String name)
|
||||
throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
|
||||
|
||||
Field field = cl.getDeclaredField(name);
|
||||
@@ -372,7 +327,7 @@ abstract class AbstractLocalizedTextProvider implements LocalizedTextProvider {
|
||||
Object cache = field.get(obj);
|
||||
|
||||
synchronized (cache) {
|
||||
Class ccl = cache.getClass();
|
||||
Class<?> ccl = cache.getClass();
|
||||
Method clearMethod = ccl.getMethod("clear");
|
||||
clearMethod.invoke(cache);
|
||||
}
|
||||
@@ -416,7 +371,6 @@ abstract class AbstractLocalizedTextProvider implements LocalizedTextProvider {
|
||||
* flow of the {@link LocalizedTextProvider} implementation the descendant provides).
|
||||
*
|
||||
* @param searchDefaultBundlesFirst provide {@link String} "true" or "false" to set the flag state accordingly.
|
||||
*
|
||||
* @since 6.0.0
|
||||
*/
|
||||
@Inject(value = StrutsConstants.STRUTS_I18N_SEARCH_DEFAULTBUNDLES_FIRST, required = false)
|
||||
@@ -424,20 +378,10 @@ abstract class AbstractLocalizedTextProvider implements LocalizedTextProvider {
|
||||
this.searchDefaultBundlesFirst = Boolean.parseBoolean(searchDefaultBundlesFirst);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the given resource bundle by it's name.
|
||||
* <p>
|
||||
* Will use <code>Thread.currentThread().getContextClassLoader()</code> as the classloader.
|
||||
* </p>
|
||||
*
|
||||
* @param aBundleName the name of the bundle (usually it's FQN classname).
|
||||
* @param locale the locale.
|
||||
* @return the bundle, <tt>null</tt> if not found.
|
||||
*/
|
||||
@Override
|
||||
public ResourceBundle findResourceBundle(String aBundleName, Locale locale) {
|
||||
public ResourceBundle findResourceBundle(String bundleName, Locale locale) {
|
||||
ClassLoader classLoader = getCurrentThreadContextClassLoader();
|
||||
String key = createMissesKey(String.valueOf(classLoader.hashCode()), aBundleName, locale);
|
||||
String key = createMissesKey(String.valueOf(classLoader.hashCode()), bundleName, locale);
|
||||
|
||||
if (missingBundles.contains(key)) {
|
||||
return null;
|
||||
@@ -448,7 +392,7 @@ abstract class AbstractLocalizedTextProvider implements LocalizedTextProvider {
|
||||
if (bundlesMap.containsKey(key)) {
|
||||
bundle = bundlesMap.get(key);
|
||||
} else {
|
||||
bundle = ResourceBundle.getBundle(aBundleName, locale, classLoader);
|
||||
bundle = ResourceBundle.getBundle(bundleName, locale, classLoader);
|
||||
bundlesMap.putIfAbsent(key, bundle);
|
||||
}
|
||||
} catch (MissingResourceException ex) {
|
||||
@@ -457,15 +401,15 @@ abstract class AbstractLocalizedTextProvider implements LocalizedTextProvider {
|
||||
if (bundlesMap.containsKey(key)) {
|
||||
bundle = bundlesMap.get(key);
|
||||
} else {
|
||||
bundle = ResourceBundle.getBundle(aBundleName, locale, delegatedClassLoaderMap.get(classLoader.hashCode()));
|
||||
bundle = ResourceBundle.getBundle(bundleName, locale, delegatedClassLoaderMap.get(classLoader.hashCode()));
|
||||
bundlesMap.putIfAbsent(key, bundle);
|
||||
}
|
||||
} catch (MissingResourceException e) {
|
||||
LOG.debug("Missing resource bundle [{}]!", aBundleName, e);
|
||||
LOG.debug("Missing resource bundle [{}]!", bundleName, e);
|
||||
missingBundles.add(key);
|
||||
}
|
||||
} else {
|
||||
LOG.debug("Missing resource bundle [{}]!", aBundleName);
|
||||
LOG.debug("Missing resource bundle [{}]!", bundleName);
|
||||
missingBundles.add(key);
|
||||
}
|
||||
}
|
||||
@@ -503,7 +447,7 @@ abstract class AbstractLocalizedTextProvider implements LocalizedTextProvider {
|
||||
* @return the default message.
|
||||
*/
|
||||
protected GetDefaultMessageReturnArg getDefaultMessage(String key, Locale locale, ValueStack valueStack, Object[] args,
|
||||
String defaultMessage) {
|
||||
String defaultMessage) {
|
||||
GetDefaultMessageReturnArg result = null;
|
||||
boolean found = true;
|
||||
|
||||
@@ -539,18 +483,18 @@ abstract class AbstractLocalizedTextProvider implements LocalizedTextProvider {
|
||||
* general key would be passed in the alternateKey parameter.
|
||||
* </p>
|
||||
*
|
||||
* @param key the initial key to search for a value within the default resource bundles.
|
||||
* @param alternateKey the alternate (fall-back) key to search for a value within the default resource bundles, if the initial key lookup fails.
|
||||
* @param locale the {@link Locale} to be used for the default resource bundle lookup.
|
||||
* @param valueStack the {@link ValueStack} associated with the operation.
|
||||
* @param args the argument array for parameterized messages (may be <code>null</code>).
|
||||
* @param defaultMessage the default message {@link String} to use if both key lookup operations fail.
|
||||
* @param key the initial key to search for a value within the default resource bundles.
|
||||
* @param alternateKey the alternate (fall-back) key to search for a value within the default resource bundles, if the initial key lookup fails.
|
||||
* @param locale the {@link Locale} to be used for the default resource bundle lookup.
|
||||
* @param valueStack the {@link ValueStack} associated with the operation.
|
||||
* @param args the argument array for parameterized messages (may be <code>null</code>).
|
||||
* @param defaultMessage the default message {@link String} to use if both key lookup operations fail.
|
||||
* @return the {@link GetDefaultMessageReturnArg} result containing the processed message lookup (by key first, then alternateKey if key's lookup fails).
|
||||
* If both key lookup operations fail, defaultMessage is used for processing.
|
||||
* If defaultMessage is <code>null</code> then the return result may be <code>null</code>.
|
||||
* If both key lookup operations fail, defaultMessage is used for processing.
|
||||
* If defaultMessage is <code>null</code> then the return result may be <code>null</code>.
|
||||
*/
|
||||
protected GetDefaultMessageReturnArg getDefaultMessageWithAlternateKey(String key, String alternateKey, Locale locale, ValueStack valueStack,
|
||||
Object[] args, String defaultMessage) {
|
||||
Object[] args, String defaultMessage) {
|
||||
GetDefaultMessageReturnArg result;
|
||||
if (alternateKey == null || alternateKey.isEmpty()) {
|
||||
result = getDefaultMessage(key, locale, valueStack, args, defaultMessage);
|
||||
@@ -593,8 +537,8 @@ abstract class AbstractLocalizedTextProvider implements LocalizedTextProvider {
|
||||
*
|
||||
* @return the message
|
||||
*/
|
||||
protected String findMessage(Class clazz, String key, String indexedKey, Locale locale, Object[] args, Set<String> checked,
|
||||
ValueStack valueStack) {
|
||||
protected String findMessage(Class<?> clazz, String key, String indexedKey, Locale locale, Object[] args, Set<String> checked,
|
||||
ValueStack valueStack) {
|
||||
if (checked == null) {
|
||||
checked = new TreeSet<>();
|
||||
} else if (checked.contains(clazz.getName())) {
|
||||
@@ -617,9 +561,9 @@ abstract class AbstractLocalizedTextProvider implements LocalizedTextProvider {
|
||||
}
|
||||
|
||||
// look in properties of implemented interfaces
|
||||
Class[] interfaces = clazz.getInterfaces();
|
||||
Class<?>[] interfaces = clazz.getInterfaces();
|
||||
|
||||
for (Class anInterface : interfaces) {
|
||||
for (Class<?> anInterface : interfaces) {
|
||||
msg = getMessage(anInterface.getName(), locale, key, valueStack, args);
|
||||
|
||||
if (msg != null) {
|
||||
@@ -639,7 +583,7 @@ abstract class AbstractLocalizedTextProvider implements LocalizedTextProvider {
|
||||
if (clazz.isInterface()) {
|
||||
interfaces = clazz.getInterfaces();
|
||||
|
||||
for (Class anInterface : interfaces) {
|
||||
for (Class<?> anInterface : interfaces) {
|
||||
msg = findMessage(anInterface, key, indexedKey, locale, args, checked, valueStack);
|
||||
|
||||
if (msg != null) {
|
||||
@@ -655,6 +599,36 @@ abstract class AbstractLocalizedTextProvider implements LocalizedTextProvider {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected String extractIndexedName(String textKey) {
|
||||
String indexedTextName = null;
|
||||
// calculate indexedTextName (collection[*]) if applicable
|
||||
if (textKey.contains("[")) {
|
||||
int i = -1;
|
||||
|
||||
indexedTextName = textKey;
|
||||
|
||||
while ((i = indexedTextName.indexOf('[', i + 1)) != -1) {
|
||||
int j = indexedTextName.indexOf(']', i);
|
||||
String a = indexedTextName.substring(0, i);
|
||||
String b = indexedTextName.substring(j);
|
||||
indexedTextName = a + "[*" + b;
|
||||
}
|
||||
}
|
||||
return indexedTextName;
|
||||
}
|
||||
|
||||
protected void logMissingText(Class<?> startClazz, String textKey, Locale locale, GetDefaultMessageReturnArg result, String indexedTextName) {
|
||||
// could we find the text, if not log a WARN
|
||||
if (unableToFindTextForKey(result) && LOG.isDebugEnabled()) {
|
||||
String warn = "Unable to find text for key '" + textKey + "' ";
|
||||
if (indexedTextName != null) {
|
||||
warn += " or indexed key '" + indexedTextName + "' ";
|
||||
}
|
||||
warn += "in class '" + startClazz.getName() + "' and locale '" + locale + "'";
|
||||
LOG.debug(warn);
|
||||
}
|
||||
}
|
||||
|
||||
static class MessageFormatKey {
|
||||
String pattern;
|
||||
Locale locale;
|
||||
+1
-1
@@ -16,7 +16,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.struts2;
|
||||
package org.apache.struts2.text;
|
||||
|
||||
import org.apache.struts2.util.ValueStack;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
+3
-1
@@ -16,8 +16,10 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.struts2;
|
||||
package org.apache.struts2.text;
|
||||
|
||||
import org.apache.struts2.ActionContext;
|
||||
import org.apache.struts2.Unchainable;
|
||||
import org.apache.struts2.inject.Inject;
|
||||
import org.apache.struts2.util.ValueStack;
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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 org.apache.struts2.text;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.ActionContext;
|
||||
import org.apache.struts2.util.ValueStack;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
* Provides support for localization in the framework, it can be used to read only default bundles.
|
||||
* <p>
|
||||
* Note that unlike {@link StrutsLocalizedTextProvider}, this class {@link GlobalLocalizedTextProvider} will
|
||||
* <em>only</em> search the default bundles for localized text.
|
||||
*/
|
||||
public class GlobalLocalizedTextProvider extends AbstractLocalizedTextProvider {
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(GlobalLocalizedTextProvider.class);
|
||||
|
||||
public GlobalLocalizedTextProvider() {
|
||||
addDefaultResourceBundle(XWORK_MESSAGES_BUNDLE);
|
||||
addDefaultResourceBundle(STRUTS_MESSAGES_BUNDLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String findText(Class<?> startClazz, String textKey, Locale locale) {
|
||||
return findText(startClazz, textKey, locale, textKey, new Object[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String findText(Class<?> startClazz, String textKey, Locale locale, String defaultMessage, Object[] args) {
|
||||
ValueStack valueStack = ActionContext.getContext().getValueStack();
|
||||
return findText(startClazz, textKey, locale, defaultMessage, args, valueStack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String findText(Class<?> startClazz, String textKey, Locale locale, String defaultMessage, Object[] args, ValueStack valueStack) {
|
||||
if (textKey == null) {
|
||||
LOG.debug("Key is null, short-circuit to default message");
|
||||
return defaultMessage;
|
||||
}
|
||||
String indexedTextName = extractIndexedName(textKey);
|
||||
|
||||
// get default
|
||||
GetDefaultMessageReturnArg result = getDefaultMessageWithAlternateKey(textKey, indexedTextName, locale, valueStack, args, defaultMessage);
|
||||
|
||||
logMissingText(startClazz, textKey, locale, result, indexedTextName);
|
||||
|
||||
return result != null ? result.message : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String findText(ResourceBundle bundle, String textKey, Locale locale) {
|
||||
return findText(bundle, textKey, locale, textKey, new Object[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String findText(ResourceBundle bundle, String textKey, Locale locale, String defaultMessage, Object[] args) {
|
||||
ValueStack valueStack = ActionContext.getContext().getValueStack();
|
||||
return findText(bundle, textKey, locale, defaultMessage, args, valueStack);
|
||||
}
|
||||
|
||||
}
|
||||
+85
-113
@@ -16,70 +16,80 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.struts2.util;
|
||||
package org.apache.struts2.text;
|
||||
|
||||
import org.apache.struts2.ActionContext;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.util.ValueStack;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Locale;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
* Provides support for localization in the framework, it can be used to read only default bundles.
|
||||
*
|
||||
* Note that unlike {@link StrutsLocalizedTextProvider}, this class {@link GlobalLocalizedTextProvider} will
|
||||
* <em>only</em> search the default bundles for localized text.
|
||||
*/
|
||||
public class GlobalLocalizedTextProvider extends AbstractLocalizedTextProvider {
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(GlobalLocalizedTextProvider.class);
|
||||
|
||||
public GlobalLocalizedTextProvider() {
|
||||
addDefaultResourceBundle(XWORK_MESSAGES_BUNDLE);
|
||||
addDefaultResourceBundle(STRUTS_MESSAGES_BUNDLE);
|
||||
}
|
||||
public interface LocalizedTextProvider extends Serializable {
|
||||
|
||||
/**
|
||||
* Calls {@link #findText(Class aClass, String aTextName, Locale locale, String defaultMessage, Object[] args)}
|
||||
* with aTextName as the default message.
|
||||
* Returns a localized message for the specified key, aTextName. Neither the key nor the
|
||||
* message is evaluated.
|
||||
*
|
||||
* @param aClass class name
|
||||
* @param aTextName text name
|
||||
* @param locale the locale
|
||||
* @return the localized text, or null if none can be found and no defaultMessage is provided
|
||||
* @see #findText(Class aClass, String aTextName, Locale locale, String defaultMessage, Object[] args)
|
||||
* @param textKey the message key
|
||||
* @param locale the locale the message should be for
|
||||
* @return a localized message based on the specified key, or null if no localized message can be found for it
|
||||
*/
|
||||
@Override
|
||||
public String findText(Class aClass, String aTextName, Locale locale) {
|
||||
return findText(aClass, aTextName, locale, aTextName, new Object[0]);
|
||||
}
|
||||
String findDefaultText(String textKey, Locale locale);
|
||||
|
||||
/**
|
||||
* Returns a localized message for the specified key, aTextName, substituting variables from the
|
||||
* array of params into the message. Neither the key nor the message is evaluated.
|
||||
*
|
||||
* @param textKey the message key
|
||||
* @param locale the locale the message should be for
|
||||
* @param params an array of objects to be substituted into the message text
|
||||
* @return A formatted message based on the specified key, or null if no localized message can be found for it
|
||||
*/
|
||||
String findDefaultText(String textKey, Locale locale, Object[] params);
|
||||
|
||||
/**
|
||||
* Finds the given resource bundle by it's name.
|
||||
* <p>
|
||||
* Finds a localized text message for the given key, aTextName. Both the key and the message
|
||||
* Will use <code>Thread.currentThread().getContextClassLoader()</code> as the classloader.
|
||||
* </p>
|
||||
*
|
||||
* @param bundleName the name of the bundle (usually it's FQN classname).
|
||||
* @param locale the locale.
|
||||
* @return the bundle, <tt>null</tt> if not found.
|
||||
*/
|
||||
ResourceBundle findResourceBundle(String bundleName, Locale locale);
|
||||
|
||||
/**
|
||||
* Calls {@link #findText(Class startClazz, String textKey, Locale locale, String defaultMessage, Object[] args)}
|
||||
* with textKey as the default message.
|
||||
*
|
||||
* @param startClazz class name
|
||||
* @param textKey text name
|
||||
* @param locale the locale
|
||||
* @return the localized text, or null if none can be found and no defaultMessage is provided
|
||||
* @see #findText(Class startClazz, String textKey, Locale locale, String defaultMessage, Object[] args)
|
||||
*/
|
||||
String findText(Class<?> startClazz, String textKey, Locale locale);
|
||||
|
||||
/**
|
||||
* Finds a localized text message for the given key, textKey. Both the key and the message
|
||||
* itself is evaluated as required. The following algorithm is used to find the requested
|
||||
* message:
|
||||
* </p>
|
||||
*
|
||||
* <ol>
|
||||
* <li>Look for the message in the default resource bundles.</li>
|
||||
* <li>If not found, return defaultMessage</li>
|
||||
* </ol>
|
||||
*
|
||||
* <p>
|
||||
* When looking for the message, if the key indexes a collection (e.g. user.phone[0]) and a
|
||||
* message for that specific key cannot be found, the general form will also be looked up
|
||||
* (i.e. user.phone[*]).
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* If a message is found, it will also be interpolated. Anything within <code>${...}</code>
|
||||
* will be treated as an OGNL expression and evaluated as such.
|
||||
* </p>
|
||||
*
|
||||
* @param aClass the class whose name to use as the start point for the search
|
||||
* @param aTextName the key to find the text message for
|
||||
* @param startClazz the class whose name to use as the start point for the search
|
||||
* @param textKey the key to find the text message for
|
||||
* @param locale the locale the message should be for
|
||||
* @param defaultMessage the message to be returned if no text message can be found in any
|
||||
* resource bundle
|
||||
@@ -87,42 +97,29 @@ public class GlobalLocalizedTextProvider extends AbstractLocalizedTextProvider {
|
||||
* resource bundle
|
||||
* @return the localized text, or null if none can be found and no defaultMessage is provided
|
||||
*/
|
||||
@Override
|
||||
public String findText(Class aClass, String aTextName, Locale locale, String defaultMessage, Object[] args) {
|
||||
ValueStack valueStack = ActionContext.getContext().getValueStack();
|
||||
return findText(aClass, aTextName, locale, defaultMessage, args, valueStack);
|
||||
|
||||
}
|
||||
String findText(Class<?> startClazz, String textKey, Locale locale, String defaultMessage, Object[] args);
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Finds a localized text message for the given key, aTextName. Both the key and the message
|
||||
* Finds a localized text message for the given key, textKey. Both the key and the message
|
||||
* itself is evaluated as required. The following algorithm is used to find the requested
|
||||
* message:
|
||||
* </p>
|
||||
*
|
||||
* <ol>
|
||||
* <li>Look for the message in the default resource bundles.</li>
|
||||
* <li>If not found, return defaultMessage</li>
|
||||
* </ol>
|
||||
*
|
||||
* <p>
|
||||
* When looking for the message, if the key indexes a collection (e.g. user.phone[0]) and a
|
||||
* message for that specific key cannot be found, the general form will also be looked up
|
||||
* (i.e. user.phone[*]).
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* If a message is found, it will also be interpolated. Anything within <code>${...}</code>
|
||||
* will be treated as an OGNL expression and evaluated as such.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* If a message is <b>not</b> found a DEBUG level log warning will be logged.
|
||||
* </p>
|
||||
*
|
||||
* @param aClass the class whose name to use as the start point for the search
|
||||
* @param aTextName the key to find the text message for
|
||||
* @param startClazz the class whose name to use as the start point for the search
|
||||
* @param textKey the key to find the text message for
|
||||
* @param locale the locale the message should be for
|
||||
* @param defaultMessage the message to be returned if no text message can be found in any
|
||||
* resource bundle
|
||||
@@ -131,91 +128,66 @@ public class GlobalLocalizedTextProvider extends AbstractLocalizedTextProvider {
|
||||
* one in the ActionContext ThreadLocal
|
||||
* @return the localized text, or null if none can be found and no defaultMessage is provided
|
||||
*/
|
||||
@Override
|
||||
public String findText(Class aClass, String aTextName, Locale locale, String defaultMessage, Object[] args, ValueStack valueStack) {
|
||||
String indexedTextName = null;
|
||||
if (aTextName == null) {
|
||||
LOG.warn("Trying to find text with null key!");
|
||||
aTextName = "";
|
||||
}
|
||||
// calculate indexedTextName (collection[*]) if applicable
|
||||
if (aTextName.contains("[")) {
|
||||
int i = -1;
|
||||
|
||||
indexedTextName = aTextName;
|
||||
|
||||
while ((i = indexedTextName.indexOf('[', i + 1)) != -1) {
|
||||
int j = indexedTextName.indexOf(']', i);
|
||||
String a = indexedTextName.substring(0, i);
|
||||
String b = indexedTextName.substring(j);
|
||||
indexedTextName = a + "[*" + b;
|
||||
}
|
||||
}
|
||||
|
||||
// get default
|
||||
GetDefaultMessageReturnArg result = getDefaultMessageWithAlternateKey(aTextName, indexedTextName, locale, valueStack, args, defaultMessage);
|
||||
|
||||
// could we find the text, if not log a warn
|
||||
if (unableToFindTextForKey(result) && LOG.isDebugEnabled()) {
|
||||
String warn = "Unable to find text for key '" + aTextName + "' ";
|
||||
if (indexedTextName != null) {
|
||||
warn += " or indexed key '" + indexedTextName + "' ";
|
||||
}
|
||||
warn += "in class '" + aClass.getName() + "' and locale '" + locale + "'";
|
||||
LOG.debug(warn);
|
||||
}
|
||||
|
||||
return result != null ? result.message : null;
|
||||
}
|
||||
String findText(Class<?> startClazz, String textKey, Locale locale, String defaultMessage, Object[] args, ValueStack valueStack);
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Finds a localized text message for the given key, aTextName, in the specified resource bundle
|
||||
* with aTextName as the default message.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* If a message is found, it will also be interpolated. Anything within <code>${...}</code>
|
||||
* will be treated as an OGNL expression and evaluated as such.
|
||||
* </p>
|
||||
*
|
||||
* @param bundle a resource bundle name
|
||||
* @param aTextName text name
|
||||
* @param locale the locale
|
||||
* @param bundle a resource bundle name
|
||||
* @param textKey text name
|
||||
* @param locale the locale
|
||||
* @return the localized text, or null if none can be found and no defaultMessage is provided
|
||||
* @see #findText(ResourceBundle, String, Locale, String, Object[])
|
||||
*/
|
||||
@Override
|
||||
public String findText(ResourceBundle bundle, String aTextName, Locale locale) {
|
||||
return findText(bundle, aTextName, locale, aTextName, new Object[0]);
|
||||
}
|
||||
String findText(ResourceBundle bundle, String textKey, Locale locale);
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Finds a localized text message for the given key, aTextName, in the specified resource
|
||||
* bundle.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* If a message is found, it will also be interpolated. Anything within <code>${...}</code>
|
||||
* will be treated as an OGNL expression and evaluated as such.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* If a message is <b>not</b> found a WARN log will be logged.
|
||||
* </p>
|
||||
*
|
||||
* @param bundle the bundle
|
||||
* @param aTextName the key
|
||||
* @param textKey the key
|
||||
* @param locale the locale
|
||||
* @param defaultMessage the default message to use if no message was found in the bundle
|
||||
* @param args arguments for the message formatter.
|
||||
* @return the localized text, or null if none can be found and no defaultMessage is provided
|
||||
*/
|
||||
@Override
|
||||
public String findText(ResourceBundle bundle, String aTextName, Locale locale, String defaultMessage, Object[] args) {
|
||||
ValueStack valueStack = ActionContext.getContext().getValueStack();
|
||||
return findText(bundle, aTextName, locale, defaultMessage, args, valueStack);
|
||||
}
|
||||
String findText(ResourceBundle bundle, String textKey, Locale locale, String defaultMessage, Object[] args);
|
||||
|
||||
/**
|
||||
* Finds a localized text message for the given key, aTextName, in the specified resource
|
||||
* bundle.
|
||||
* <p>
|
||||
* If a message is found, it will also be interpolated. Anything within <code>${...}</code>
|
||||
* will be treated as an OGNL expression and evaluated as such.
|
||||
* <p>
|
||||
* If a message is <b>not</b> found a WARN log will be logged.
|
||||
*
|
||||
* @param bundle the bundle
|
||||
* @param textKey the key
|
||||
* @param locale the locale
|
||||
* @param defaultMessage the default message to use if no message was found in the bundle
|
||||
* @param args arguments for the message formatter.
|
||||
* @param valueStack the OGNL value stack.
|
||||
* @return the localized text, or null if none can be found and no defaultMessage is provided
|
||||
*/
|
||||
String findText(ResourceBundle bundle, String textKey, Locale locale, String defaultMessage, Object[] args, ValueStack valueStack);
|
||||
|
||||
/**
|
||||
* Adds the bundle to the internal list of default bundles.
|
||||
* If the bundle already exists in the list it will be re-added.
|
||||
*
|
||||
* @param bundleName the name of the bundle to add.
|
||||
*/
|
||||
void addDefaultResourceBundle(String bundleName);
|
||||
|
||||
}
|
||||
+4
-2
@@ -16,7 +16,9 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.struts2;
|
||||
package org.apache.struts2.text;
|
||||
|
||||
import org.apache.struts2.LocaleProvider;
|
||||
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
@@ -39,7 +41,7 @@ public interface ResourceBundleTextProvider extends TextProvider {
|
||||
*
|
||||
* @param clazz the class to use for loading.
|
||||
*/
|
||||
void setClazz(Class clazz);
|
||||
void setClazz(Class<?> clazz);
|
||||
|
||||
/**
|
||||
* Set the LocaleProvider to use.
|
||||
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
* 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 org.apache.struts2.text;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.ActionContext;
|
||||
import org.apache.struts2.ActionInvocation;
|
||||
import org.apache.struts2.ModelDriven;
|
||||
import org.apache.struts2.conversion.impl.XWorkConverter;
|
||||
import org.apache.struts2.inject.Inject;
|
||||
import org.apache.struts2.util.ValueStack;
|
||||
import org.apache.struts2.util.reflection.ReflectionProvider;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.util.Locale;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
* Provides support for localization in the framework, it can be used to read only default bundles,
|
||||
* or it can search the class hierarchy to find proper bundles.
|
||||
*/
|
||||
public class StrutsLocalizedTextProvider extends AbstractLocalizedTextProvider {
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(StrutsLocalizedTextProvider.class);
|
||||
private transient ReflectionProvider reflectionProvider;
|
||||
|
||||
public StrutsLocalizedTextProvider() {
|
||||
addDefaultResourceBundle(XWORK_MESSAGES_BUNDLE);
|
||||
addDefaultResourceBundle(STRUTS_MESSAGES_BUNDLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String findText(Class<?> startClazz, String textKey, Locale locale) {
|
||||
return findText(startClazz, textKey, locale, textKey, new Object[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String findText(Class<?> startClazz, String textKey, Locale locale, String defaultMessage, Object[] args) {
|
||||
ValueStack valueStack = ActionContext.getContext().getValueStack();
|
||||
return findText(startClazz, textKey, locale, defaultMessage, args, valueStack);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String findText(Class<?> startClazz, String textKey, Locale locale, String defaultMessage, Object[] args,
|
||||
ValueStack valueStack) {
|
||||
if (textKey == null) {
|
||||
LOG.debug("Key is null, short-circuit to default message");
|
||||
return defaultMessage;
|
||||
}
|
||||
String indexedTextName = extractIndexedName(textKey);
|
||||
|
||||
// Allow for and track an early lookup for the message in the default resource bundles first, before searching the class hierarchy.
|
||||
// The early lookup is only performed when the text provider has been configured to do so, otherwise follow the standard processing order.
|
||||
boolean performedInitialDefaultBundlesMessageLookup = false;
|
||||
GetDefaultMessageReturnArg result = null;
|
||||
|
||||
// If search default bundles first is set true, call alternative logic first.
|
||||
if (searchDefaultBundlesFirst) {
|
||||
result = getDefaultMessageWithAlternateKey(textKey, indexedTextName, locale, valueStack, args, defaultMessage);
|
||||
performedInitialDefaultBundlesMessageLookup = true;
|
||||
if (!unableToFindTextForKey(result)) {
|
||||
return result.message; // Found a message in the default resource bundles for textKey or indexedTextName.
|
||||
}
|
||||
}
|
||||
|
||||
// search up class hierarchy
|
||||
String msg = findMessage(startClazz, textKey, indexedTextName, locale, args, null, valueStack);
|
||||
|
||||
if (msg != null) {
|
||||
return msg;
|
||||
}
|
||||
|
||||
if (ModelDriven.class.isAssignableFrom(startClazz)) {
|
||||
ActionContext context = ActionContext.getContext();
|
||||
// search up model's class hierarchy
|
||||
ActionInvocation actionInvocation = context.getActionInvocation();
|
||||
|
||||
// ActionInvocation may be null if we're being run from a Sitemesh filter, so we won't get model texts if this is null
|
||||
if (actionInvocation != null) {
|
||||
Object action = actionInvocation.getAction();
|
||||
if (action instanceof ModelDriven) {
|
||||
Object model = ((ModelDriven<?>) action).getModel();
|
||||
if (model != null) {
|
||||
msg = findMessage(model.getClass(), textKey, indexedTextName, locale, args, null, valueStack);
|
||||
if (msg != null) {
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// nothing still? alright, search the package hierarchy now
|
||||
for (Class<?> clazz = startClazz;
|
||||
(clazz != null) && !clazz.equals(Object.class);
|
||||
clazz = clazz.getSuperclass()) {
|
||||
|
||||
String basePackageName = clazz.getName();
|
||||
while (basePackageName.lastIndexOf('.') != -1) {
|
||||
basePackageName = basePackageName.substring(0, basePackageName.lastIndexOf('.'));
|
||||
String packageName = basePackageName + ".package";
|
||||
msg = getMessage(packageName, locale, textKey, valueStack, args);
|
||||
|
||||
if (msg != null) {
|
||||
return msg;
|
||||
}
|
||||
|
||||
if (indexedTextName != null) {
|
||||
msg = getMessage(packageName, locale, indexedTextName, valueStack, args);
|
||||
|
||||
if (msg != null) {
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// see if it's a child property
|
||||
int idx = textKey.indexOf('.');
|
||||
|
||||
if (idx != -1) {
|
||||
String newKey = null;
|
||||
String prop = null;
|
||||
|
||||
if (textKey.startsWith(XWorkConverter.CONVERSION_ERROR_PROPERTY_PREFIX)) {
|
||||
idx = textKey.indexOf('.', XWorkConverter.CONVERSION_ERROR_PROPERTY_PREFIX.length());
|
||||
|
||||
if (idx != -1) {
|
||||
prop = textKey.substring(XWorkConverter.CONVERSION_ERROR_PROPERTY_PREFIX.length(), idx);
|
||||
newKey = XWorkConverter.CONVERSION_ERROR_PROPERTY_PREFIX + textKey.substring(idx + 1);
|
||||
}
|
||||
} else {
|
||||
prop = textKey.substring(0, idx);
|
||||
newKey = textKey.substring(idx + 1);
|
||||
}
|
||||
|
||||
if (prop != null) {
|
||||
Object obj = valueStack.findValue(prop);
|
||||
try {
|
||||
Object actionObj = reflectionProvider.getRealTarget(prop, valueStack.getContext(), valueStack.getRoot());
|
||||
if (actionObj != null) {
|
||||
PropertyDescriptor propertyDescriptor = reflectionProvider.getPropertyDescriptor(actionObj.getClass(), prop);
|
||||
|
||||
if (propertyDescriptor != null) {
|
||||
Class<?> clazz = propertyDescriptor.getPropertyType();
|
||||
|
||||
if (clazz != null) {
|
||||
if (obj != null) {
|
||||
valueStack.push(obj);
|
||||
}
|
||||
msg = findText(clazz, newKey, locale, null, args);
|
||||
if (obj != null) {
|
||||
valueStack.pop();
|
||||
}
|
||||
if (msg != null) {
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.debug("unable to find property {}", prop, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get default
|
||||
// Note: The default bundles lookup may already have been performed (via alternate early lookup),
|
||||
// so we check first to avoid repeating the same operation twice.
|
||||
if (!performedInitialDefaultBundlesMessageLookup) {
|
||||
result = getDefaultMessageWithAlternateKey(textKey, indexedTextName, locale, valueStack, args, defaultMessage);
|
||||
}
|
||||
|
||||
logMissingText(startClazz, textKey, locale, result, indexedTextName);
|
||||
|
||||
return result != null ? result.message : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String findText(ResourceBundle bundle, String textKey, Locale locale) {
|
||||
return findText(bundle, textKey, locale, textKey, new Object[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String findText(ResourceBundle bundle, String textKey, Locale locale, String defaultMessage, Object[] args) {
|
||||
ValueStack valueStack = ActionContext.getContext().getValueStack();
|
||||
return findText(bundle, textKey, locale, defaultMessage, args, valueStack);
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void setReflectionProvider(ReflectionProvider reflectionProvider) {
|
||||
this.reflectionProvider = reflectionProvider;
|
||||
}
|
||||
|
||||
}
|
||||
+3
-2
@@ -16,8 +16,9 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.struts2;
|
||||
package org.apache.struts2.text;
|
||||
|
||||
import org.apache.struts2.LocaleProviderFactory;
|
||||
import org.apache.struts2.inject.Inject;
|
||||
|
||||
import java.util.ResourceBundle;
|
||||
@@ -49,7 +50,7 @@ public class StrutsTextProviderFactory implements TextProviderFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextProvider createInstance(Class clazz) {
|
||||
public TextProvider createInstance(Class<?> clazz) {
|
||||
TextProvider instance = getTextProvider(clazz);
|
||||
if (instance instanceof ResourceBundleTextProvider) {
|
||||
((ResourceBundleTextProvider) instance).setClazz(clazz);
|
||||
+4
-4
@@ -16,7 +16,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.struts2;
|
||||
package org.apache.struts2.text;
|
||||
|
||||
import org.apache.struts2.util.ValueStack;
|
||||
|
||||
@@ -33,9 +33,9 @@ import java.util.ResourceBundle;
|
||||
* global texts to be defined for an application base class.
|
||||
*
|
||||
* <p>
|
||||
* You can override {@link LocaleProvider#getLocale()} to change the behaviour of how
|
||||
* You can override {@link org.apache.struts2.LocaleProvider#getLocale()} to change the behaviour of how
|
||||
* to choose locale for the bundles that are returned. Typically you would
|
||||
* use the {@link LocaleProvider} interface to get the users configured locale.
|
||||
* use the {@link org.apache.struts2.LocaleProvider} interface to get the users configured locale.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
@@ -56,7 +56,7 @@ import java.util.ResourceBundle;
|
||||
* </p>
|
||||
* @author Jason Carreira
|
||||
* @author Rainer Hermanns
|
||||
* @see LocaleProvider
|
||||
* @see org.apache.struts2.LocaleProvider
|
||||
* @see TextProviderSupport
|
||||
*/
|
||||
public interface TextProvider {
|
||||
+2
-2
@@ -16,13 +16,13 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.struts2;
|
||||
package org.apache.struts2.text;
|
||||
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
public interface TextProviderFactory {
|
||||
|
||||
TextProvider createInstance(Class clazz);
|
||||
TextProvider createInstance(Class<?> clazz);
|
||||
|
||||
TextProvider createInstance(ResourceBundle bundle);
|
||||
|
||||
+29
-37
@@ -16,12 +16,19 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.struts2;
|
||||
package org.apache.struts2.text;
|
||||
|
||||
import org.apache.struts2.LocaleProvider;
|
||||
import org.apache.struts2.LocaleProviderFactory;
|
||||
import org.apache.struts2.inject.Inject;
|
||||
import org.apache.struts2.util.ValueStack;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
* Default TextProvider implementation.
|
||||
@@ -31,7 +38,7 @@ import java.util.*;
|
||||
*/
|
||||
public class TextProviderSupport implements ResourceBundleTextProvider {
|
||||
|
||||
protected Class clazz;
|
||||
protected Class<?> clazz;
|
||||
protected LocaleProvider localeProvider;
|
||||
protected ResourceBundle bundle;
|
||||
protected LocalizedTextProvider localizedTextProvider;
|
||||
@@ -42,7 +49,7 @@ public class TextProviderSupport implements ResourceBundleTextProvider {
|
||||
* @param clazz a clazz to use for reading the resource bundle.
|
||||
* @param provider a locale provider.
|
||||
*/
|
||||
public TextProviderSupport(Class clazz, LocaleProvider provider, LocalizedTextProvider localizedTextProvider) {
|
||||
public TextProviderSupport(Class<?> clazz, LocaleProvider provider, LocalizedTextProvider localizedTextProvider) {
|
||||
this.clazz = clazz;
|
||||
this.localeProvider = provider;
|
||||
this.localizedTextProvider = localizedTextProvider;
|
||||
@@ -72,7 +79,7 @@ public class TextProviderSupport implements ResourceBundleTextProvider {
|
||||
* @param clazz a clazz to use for reading the resource bundle.
|
||||
*/
|
||||
@Override
|
||||
public void setClazz(Class clazz) {
|
||||
public void setClazz(Class<?> clazz) {
|
||||
this.clazz = clazz;
|
||||
}
|
||||
|
||||
@@ -103,13 +110,13 @@ public class TextProviderSupport implements ResourceBundleTextProvider {
|
||||
* class.
|
||||
*/
|
||||
public boolean hasKey(String key) {
|
||||
String message;
|
||||
if (clazz != null) {
|
||||
message = localizedTextProvider.findText(clazz, key, getLocale(), null, new Object[0] );
|
||||
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;
|
||||
return message != null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -135,7 +142,7 @@ public class TextProviderSupport implements ResourceBundleTextProvider {
|
||||
* 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 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
|
||||
*/
|
||||
@@ -151,7 +158,7 @@ public class TextProviderSupport implements ResourceBundleTextProvider {
|
||||
* 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 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
|
||||
*/
|
||||
@@ -169,8 +176,8 @@ public class TextProviderSupport implements ResourceBundleTextProvider {
|
||||
* 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
|
||||
* @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) {
|
||||
@@ -185,8 +192,8 @@ public class TextProviderSupport implements ResourceBundleTextProvider {
|
||||
* 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
|
||||
* @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) {
|
||||
@@ -201,7 +208,7 @@ public class TextProviderSupport implements ResourceBundleTextProvider {
|
||||
* 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 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
|
||||
@@ -242,7 +249,7 @@ public class TextProviderSupport implements ResourceBundleTextProvider {
|
||||
* 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 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
|
||||
@@ -251,10 +258,10 @@ public class TextProviderSupport implements ResourceBundleTextProvider {
|
||||
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 (stack == null) {
|
||||
locale = getLocale();
|
||||
} else {
|
||||
locale = stack.getActionContext().getLocale();
|
||||
}
|
||||
if (locale == null) {
|
||||
locale = getLocale();
|
||||
@@ -266,7 +273,6 @@ public class TextProviderSupport implements ResourceBundleTextProvider {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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
|
||||
@@ -280,21 +286,7 @@ public class TextProviderSupport implements ResourceBundleTextProvider {
|
||||
* @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);
|
||||
}
|
||||
|
||||
return getText(key, defaultValue, args != null ? Arrays.stream(args).toList() : List.of(), stack);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -18,7 +18,7 @@
|
||||
*/
|
||||
package org.apache.struts2.util;
|
||||
|
||||
import org.apache.struts2.TextProvider;
|
||||
import org.apache.struts2.text.TextProvider;
|
||||
import org.apache.struts2.interceptor.ValidationAware;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
|
||||
@@ -1,382 +0,0 @@
|
||||
/*
|
||||
* 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 org.apache.struts2.util;
|
||||
|
||||
import org.apache.struts2.ActionContext;
|
||||
import org.apache.struts2.ActionInvocation;
|
||||
import org.apache.struts2.ModelDriven;
|
||||
import org.apache.struts2.conversion.impl.XWorkConverter;
|
||||
import org.apache.struts2.inject.Inject;
|
||||
import org.apache.struts2.util.reflection.ReflectionProvider;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.util.Locale;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
* Provides support for localization in the framework, it can be used to read only default bundles,
|
||||
* or it can search the class hierarchy to find proper bundles.
|
||||
*/
|
||||
public class StrutsLocalizedTextProvider extends AbstractLocalizedTextProvider {
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(StrutsLocalizedTextProvider.class);
|
||||
private transient ReflectionProvider reflectionProvider;
|
||||
|
||||
public StrutsLocalizedTextProvider() {
|
||||
addDefaultResourceBundle(XWORK_MESSAGES_BUNDLE);
|
||||
addDefaultResourceBundle(STRUTS_MESSAGES_BUNDLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls {@link #findText(Class aClass, String aTextName, Locale locale, String defaultMessage, Object[] args)}
|
||||
* with aTextName as the default message.
|
||||
*
|
||||
* @param aClass class name
|
||||
* @param aTextName text name
|
||||
* @param locale the locale
|
||||
* @return the localized text, or null if none can be found and no defaultMessage is provided
|
||||
* @see #findText(Class aClass, String aTextName, Locale locale, String defaultMessage, Object[] args)
|
||||
*/
|
||||
@Override
|
||||
public String findText(Class aClass, String aTextName, Locale locale) {
|
||||
return findText(aClass, aTextName, locale, aTextName, new Object[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Finds a localized text message for the given key, aTextName. Both the key and the message
|
||||
* itself is evaluated as required. The following algorithm is used to find the requested
|
||||
* message:
|
||||
* </p>
|
||||
*
|
||||
* <ol>
|
||||
* <li>If {@link #searchDefaultBundlesFirst} is <code>true</code>, look for the message in the default resource bundles first.</li>
|
||||
* <li>Look for message in aClass' class hierarchy.
|
||||
* <ol>
|
||||
* <li>Look for the message in a resource bundle for aClass</li>
|
||||
* <li>If not found, look for the message in a resource bundle for any implemented interface</li>
|
||||
* <li>If not found, traverse up the Class' hierarchy and repeat from the first sub-step</li>
|
||||
* </ol></li>
|
||||
* <li>If not found and aClass is a {@link ModelDriven} Action, then look for message in
|
||||
* the model's class hierarchy (repeat sub-steps listed above).</li>
|
||||
* <li>If not found, look for message in child property. This is determined by evaluating
|
||||
* the message key as an OGNL expression. For example, if the key is
|
||||
* <i>user.address.state</i>, then it will attempt to see if "user" can be resolved into an
|
||||
* object. If so, repeat the entire process from the beginning with the object's class as
|
||||
* aClass and "address.state" as the message key.</li>
|
||||
* <li>If not found, look for the message in aClass' package hierarchy.</li>
|
||||
* <li>If still not found, look for the message in the default resource bundles
|
||||
* (Note: the lookup is not repeated again if {@link #searchDefaultBundlesFirst} was <code>true</code>).</li>
|
||||
* <li>Return defaultMessage</li>
|
||||
* </ol>
|
||||
*
|
||||
* <p>
|
||||
* When looking for the message, if the key indexes a collection (e.g. user.phone[0]) and a
|
||||
* message for that specific key cannot be found, the general form will also be looked up
|
||||
* (i.e. user.phone[*]).
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* If a message is found, it will also be interpolated. Anything within <code>${...}</code>
|
||||
* will be treated as an OGNL expression and evaluated as such.
|
||||
* </p>
|
||||
*
|
||||
* @param aClass the class whose name to use as the start point for the search
|
||||
* @param aTextName the key to find the text message for
|
||||
* @param locale the locale the message should be for
|
||||
* @param defaultMessage the message to be returned if no text message can be found in any
|
||||
* resource bundle
|
||||
* @param args arguments
|
||||
* resource bundle
|
||||
* @return the localized text, or null if none can be found and no defaultMessage is provided
|
||||
*/
|
||||
@Override
|
||||
public String findText(Class aClass, String aTextName, Locale locale, String defaultMessage, Object[] args) {
|
||||
ValueStack valueStack = ActionContext.getContext().getValueStack();
|
||||
return findText(aClass, aTextName, locale, defaultMessage, args, valueStack);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Finds a localized text message for the given key, aTextName. Both the key and the message
|
||||
* itself is evaluated as required. The following algorithm is used to find the requested
|
||||
* message:
|
||||
* </p>
|
||||
*
|
||||
* <ol>
|
||||
* <li>If {@link #searchDefaultBundlesFirst} is <code>true</code>, look for the message in the default resource bundles first.</li>
|
||||
* <li>Look for message in aClass' class hierarchy.
|
||||
* <ol>
|
||||
* <li>Look for the message in a resource bundle for aClass</li>
|
||||
* <li>If not found, look for the message in a resource bundle for any implemented interface</li>
|
||||
* <li>If not found, traverse up the Class' hierarchy and repeat from the first sub-step</li>
|
||||
* </ol></li>
|
||||
* <li>If not found and aClass is a {@link ModelDriven} Action, then look for message in
|
||||
* the model's class hierarchy (repeat sub-steps listed above).</li>
|
||||
* <li>If not found, look for message in child property. This is determined by evaluating
|
||||
* the message key as an OGNL expression. For example, if the key is
|
||||
* <i>user.address.state</i>, then it will attempt to see if "user" can be resolved into an
|
||||
* object. If so, repeat the entire process from the beginning with the object's class as
|
||||
* aClass and "address.state" as the message key.</li>
|
||||
* <li>If not found, look for the message in aClass' package hierarchy.</li>
|
||||
* <li>If still not found, look for the message in the default resource bundles
|
||||
* (Note: the lookup is not repeated again if {@link #searchDefaultBundlesFirst} was <code>true</code>).</li>
|
||||
* <li>Return defaultMessage</li>
|
||||
* </ol>
|
||||
*
|
||||
* <p>
|
||||
* When looking for the message, if the key indexes a collection (e.g. user.phone[0]) and a
|
||||
* message for that specific key cannot be found, the general form will also be looked up
|
||||
* (i.e. user.phone[*]).
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* If a message is found, it will also be interpolated. Anything within <code>${...}</code>
|
||||
* will be treated as an OGNL expression and evaluated as such.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* If a message is <b>not</b> found a DEBUG level log warning will be logged.
|
||||
* </p>
|
||||
*
|
||||
* @param aClass the class whose name to use as the start point for the search
|
||||
* @param aTextName the key to find the text message for
|
||||
* @param locale the locale the message should be for
|
||||
* @param defaultMessage the message to be returned if no text message can be found in any
|
||||
* resource bundle
|
||||
* @param args arguments
|
||||
* @param valueStack the value stack to use to evaluate expressions instead of the
|
||||
* one in the ActionContext ThreadLocal
|
||||
* @return the localized text, or null if none can be found and no defaultMessage is provided
|
||||
*/
|
||||
@Override
|
||||
public String findText(Class aClass, String aTextName, Locale locale, String defaultMessage, Object[] args,
|
||||
ValueStack valueStack) {
|
||||
String indexedTextName = null;
|
||||
if (aTextName == null) {
|
||||
LOG.warn("Trying to find text with null key!");
|
||||
aTextName = "";
|
||||
}
|
||||
// calculate indexedTextName (collection[*]) if applicable
|
||||
if (aTextName.contains("[")) {
|
||||
int i = -1;
|
||||
|
||||
indexedTextName = aTextName;
|
||||
|
||||
while ((i = indexedTextName.indexOf('[', i + 1)) != -1) {
|
||||
int j = indexedTextName.indexOf(']', i);
|
||||
String a = indexedTextName.substring(0, i);
|
||||
String b = indexedTextName.substring(j);
|
||||
indexedTextName = a + "[*" + b;
|
||||
}
|
||||
}
|
||||
|
||||
// Allow for and track an early lookup for the message in the default resource bundles first, before searching the class hierarchy.
|
||||
// The early lookup is only performed when the text provider has been configured to do so, otherwise follow the standard processing order.
|
||||
boolean performedInitialDefaultBundlesMessageLookup = false;
|
||||
GetDefaultMessageReturnArg result = null;
|
||||
|
||||
// If search default bundles first is set true, call alternative logic first.
|
||||
if (searchDefaultBundlesFirst) {
|
||||
result = getDefaultMessageWithAlternateKey(aTextName, indexedTextName, locale, valueStack, args, defaultMessage);
|
||||
performedInitialDefaultBundlesMessageLookup = true;
|
||||
if (!unableToFindTextForKey(result)) {
|
||||
return result.message; // Found a message in the default resource bundles for aTextName or indexedTextName.
|
||||
}
|
||||
}
|
||||
|
||||
// search up class hierarchy
|
||||
String msg = findMessage(aClass, aTextName, indexedTextName, locale, args, null, valueStack);
|
||||
|
||||
if (msg != null) {
|
||||
return msg;
|
||||
}
|
||||
|
||||
if (ModelDriven.class.isAssignableFrom(aClass)) {
|
||||
ActionContext context = ActionContext.getContext();
|
||||
// search up model's class hierarchy
|
||||
ActionInvocation actionInvocation = context.getActionInvocation();
|
||||
|
||||
// ActionInvocation may be null if we're being run from a Sitemesh filter, so we won't get model texts if this is null
|
||||
if (actionInvocation != null) {
|
||||
Object action = actionInvocation.getAction();
|
||||
if (action instanceof ModelDriven) {
|
||||
Object model = ((ModelDriven) action).getModel();
|
||||
if (model != null) {
|
||||
msg = findMessage(model.getClass(), aTextName, indexedTextName, locale, args, null, valueStack);
|
||||
if (msg != null) {
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// nothing still? alright, search the package hierarchy now
|
||||
for (Class clazz = aClass;
|
||||
(clazz != null) && !clazz.equals(Object.class);
|
||||
clazz = clazz.getSuperclass()) {
|
||||
|
||||
String basePackageName = clazz.getName();
|
||||
while (basePackageName.lastIndexOf('.') != -1) {
|
||||
basePackageName = basePackageName.substring(0, basePackageName.lastIndexOf('.'));
|
||||
String packageName = basePackageName + ".package";
|
||||
msg = getMessage(packageName, locale, aTextName, valueStack, args);
|
||||
|
||||
if (msg != null) {
|
||||
return msg;
|
||||
}
|
||||
|
||||
if (indexedTextName != null) {
|
||||
msg = getMessage(packageName, locale, indexedTextName, valueStack, args);
|
||||
|
||||
if (msg != null) {
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// see if it's a child property
|
||||
int idx = aTextName.indexOf('.');
|
||||
|
||||
if (idx != -1) {
|
||||
String newKey = null;
|
||||
String prop = null;
|
||||
|
||||
if (aTextName.startsWith(XWorkConverter.CONVERSION_ERROR_PROPERTY_PREFIX)) {
|
||||
idx = aTextName.indexOf('.', XWorkConverter.CONVERSION_ERROR_PROPERTY_PREFIX.length());
|
||||
|
||||
if (idx != -1) {
|
||||
prop = aTextName.substring(XWorkConverter.CONVERSION_ERROR_PROPERTY_PREFIX.length(), idx);
|
||||
newKey = XWorkConverter.CONVERSION_ERROR_PROPERTY_PREFIX + aTextName.substring(idx + 1);
|
||||
}
|
||||
} else {
|
||||
prop = aTextName.substring(0, idx);
|
||||
newKey = aTextName.substring(idx + 1);
|
||||
}
|
||||
|
||||
if (prop != null) {
|
||||
Object obj = valueStack.findValue(prop);
|
||||
try {
|
||||
Object actionObj = reflectionProvider.getRealTarget(prop, valueStack.getContext(), valueStack.getRoot());
|
||||
if (actionObj != null) {
|
||||
PropertyDescriptor propertyDescriptor = reflectionProvider.getPropertyDescriptor(actionObj.getClass(), prop);
|
||||
|
||||
if (propertyDescriptor != null) {
|
||||
Class clazz = propertyDescriptor.getPropertyType();
|
||||
|
||||
if (clazz != null) {
|
||||
if (obj != null) {
|
||||
valueStack.push(obj);
|
||||
}
|
||||
msg = findText(clazz, newKey, locale, null, args);
|
||||
if (obj != null) {
|
||||
valueStack.pop();
|
||||
}
|
||||
if (msg != null) {
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.debug("unable to find property {}", prop, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get default
|
||||
// Note: The default bundles lookup may already have been performed (via alternate early lookup),
|
||||
// so we check first to avoid repeating the same operation twice.
|
||||
if (!performedInitialDefaultBundlesMessageLookup) {
|
||||
result = getDefaultMessageWithAlternateKey(aTextName, indexedTextName, locale, valueStack, args, defaultMessage);
|
||||
}
|
||||
|
||||
// could we find the text, if not log a warn
|
||||
if (unableToFindTextForKey(result) && LOG.isDebugEnabled()) {
|
||||
String warn = "Unable to find text for key '" + aTextName + "' ";
|
||||
if (indexedTextName != null) {
|
||||
warn += " or indexed key '" + indexedTextName + "' ";
|
||||
}
|
||||
warn += "in class '" + aClass.getName() + "' and locale '" + locale + "'";
|
||||
LOG.debug(warn);
|
||||
}
|
||||
|
||||
return result != null ? result.message : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Finds a localized text message for the given key, aTextName, in the specified resource bundle
|
||||
* with aTextName as the default message.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* If a message is found, it will also be interpolated. Anything within <code>${...}</code>
|
||||
* will be treated as an OGNL expression and evaluated as such.
|
||||
* </p>
|
||||
*
|
||||
* @param bundle a resource bundle name
|
||||
* @param aTextName text name
|
||||
* @param locale the locale
|
||||
* @return the localized text, or null if none can be found and no defaultMessage is provided
|
||||
* @see #findText(java.util.ResourceBundle, String, java.util.Locale, String, Object[])
|
||||
*/
|
||||
@Override
|
||||
public String findText(ResourceBundle bundle, String aTextName, Locale locale) {
|
||||
return findText(bundle, aTextName, locale, aTextName, new Object[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Finds a localized text message for the given key, aTextName, in the specified resource
|
||||
* bundle.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* If a message is found, it will also be interpolated. Anything within <code>${...}</code>
|
||||
* will be treated as an OGNL expression and evaluated as such.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* If a message is <b>not</b> found a WARN log will be logged.
|
||||
* </p>
|
||||
*
|
||||
* @param bundle the bundle
|
||||
* @param aTextName the key
|
||||
* @param locale the locale
|
||||
* @param defaultMessage the default message to use if no message was found in the bundle
|
||||
* @param args arguments for the message formatter.
|
||||
* @return the localized text, or null if none can be found and no defaultMessage is provided
|
||||
*/
|
||||
@Override
|
||||
public String findText(ResourceBundle bundle, String aTextName, Locale locale, String defaultMessage, Object[] args) {
|
||||
ValueStack valueStack = ActionContext.getContext().getValueStack();
|
||||
return findText(bundle, aTextName, locale, defaultMessage, args, valueStack);
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void setReflectionProvider(ReflectionProvider reflectionProvider) {
|
||||
this.reflectionProvider = reflectionProvider;
|
||||
}
|
||||
}
|
||||
@@ -18,8 +18,7 @@
|
||||
*/
|
||||
package org.apache.struts2.util;
|
||||
|
||||
import org.apache.struts2.TextProvider;
|
||||
import org.apache.struts2.util.ValueStack;
|
||||
import org.apache.struts2.text.TextProvider;
|
||||
import org.apache.commons.text.StringEscapeUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
package org.apache.struts2.util;
|
||||
|
||||
import org.apache.struts2.ActionContext;
|
||||
import org.apache.struts2.LocalizedTextProvider;
|
||||
import org.apache.struts2.text.LocalizedTextProvider;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.dispatcher.Parameter;
|
||||
|
||||
@@ -21,7 +21,7 @@ package org.apache.struts2.validator;
|
||||
import org.apache.struts2.ActionContext;
|
||||
import org.apache.struts2.FileManager;
|
||||
import org.apache.struts2.FileManagerFactory;
|
||||
import org.apache.struts2.TextProviderFactory;
|
||||
import org.apache.struts2.text.TextProviderFactory;
|
||||
import org.apache.struts2.inject.Inject;
|
||||
import org.apache.struts2.util.ClassLoaderUtil;
|
||||
import org.apache.struts2.util.ValueStack;
|
||||
|
||||
@@ -21,11 +21,11 @@ package org.apache.struts2.validator;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.ActionContext;
|
||||
import org.apache.struts2.CompositeTextProvider;
|
||||
import org.apache.struts2.text.CompositeTextProvider;
|
||||
import org.apache.struts2.LocaleProvider;
|
||||
import org.apache.struts2.LocaleProviderFactory;
|
||||
import org.apache.struts2.TextProvider;
|
||||
import org.apache.struts2.TextProviderFactory;
|
||||
import org.apache.struts2.text.TextProvider;
|
||||
import org.apache.struts2.text.TextProviderFactory;
|
||||
import org.apache.struts2.interceptor.ValidationAware;
|
||||
import org.apache.struts2.util.ValueStack;
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
package org.apache.struts2.validator;
|
||||
|
||||
import org.apache.struts2.LocaleProvider;
|
||||
import org.apache.struts2.TextProvider;
|
||||
import org.apache.struts2.text.TextProvider;
|
||||
import org.apache.struts2.interceptor.ValidationAware;
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
*/
|
||||
package org.apache.struts2.validator.validators;
|
||||
|
||||
import org.apache.struts2.TextProviderFactory;
|
||||
import org.apache.struts2.text.TextProviderFactory;
|
||||
import org.apache.struts2.inject.Inject;
|
||||
import org.apache.struts2.util.TextParseUtil;
|
||||
import org.apache.struts2.util.ValueStack;
|
||||
|
||||
+2
-2
@@ -19,8 +19,8 @@
|
||||
package org.apache.struts2.validator.validators;
|
||||
|
||||
import org.apache.struts2.ActionContext;
|
||||
import org.apache.struts2.CompositeTextProvider;
|
||||
import org.apache.struts2.TextProvider;
|
||||
import org.apache.struts2.text.CompositeTextProvider;
|
||||
import org.apache.struts2.text.TextProvider;
|
||||
import org.apache.struts2.inject.Inject;
|
||||
import org.apache.struts2.util.ValueStack;
|
||||
import org.apache.struts2.validator.ActionValidatorManager;
|
||||
|
||||
@@ -128,15 +128,15 @@
|
||||
<bean type="org.apache.struts2.conversion.impl.StringConverter" name="struts"
|
||||
class="org.apache.struts2.conversion.impl.StringConverter" scope="singleton"/>
|
||||
|
||||
<bean type="org.apache.struts2.LocalizedTextProvider" name="global-only"
|
||||
class="org.apache.struts2.util.GlobalLocalizedTextProvider" scope="singleton"/>
|
||||
<bean type="org.apache.struts2.LocalizedTextProvider" name="struts"
|
||||
class="org.apache.struts2.util.StrutsLocalizedTextProvider" scope="singleton"/>
|
||||
<bean type="org.apache.struts2.text.LocalizedTextProvider" name="global-only"
|
||||
class="org.apache.struts2.text.GlobalLocalizedTextProvider" scope="singleton"/>
|
||||
<bean type="org.apache.struts2.text.LocalizedTextProvider" name="struts"
|
||||
class="org.apache.struts2.text.StrutsLocalizedTextProvider" scope="singleton"/>
|
||||
|
||||
<bean type="org.apache.struts2.TextProvider" name="system" class="org.apache.struts2.DefaultTextProvider"
|
||||
<bean type="org.apache.struts2.text.TextProvider" name="system" class="org.apache.struts2.text.DefaultTextProvider"
|
||||
scope="singleton"/>
|
||||
<bean type="org.apache.struts2.TextProviderFactory" name="struts"
|
||||
class="org.apache.struts2.StrutsTextProviderFactory" scope="singleton"/>
|
||||
<bean type="org.apache.struts2.text.TextProviderFactory" name="struts"
|
||||
class="org.apache.struts2.text.StrutsTextProviderFactory" scope="singleton"/>
|
||||
<bean type="org.apache.struts2.LocaleProviderFactory" name="struts"
|
||||
class="org.apache.struts2.DefaultLocaleProviderFactory" scope="singleton"/>
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ package org.apache.struts2;
|
||||
|
||||
import org.apache.struts2.action.Action;
|
||||
import org.apache.struts2.conversion.impl.ConversionData;
|
||||
import org.apache.struts2.text.TextProvider;
|
||||
import org.apache.struts2.util.ValueStack;
|
||||
import org.apache.struts2.interceptor.parameter.StrutsParameter;
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ package org.apache.struts2;
|
||||
|
||||
import org.apache.struts2.config.providers.MockConfigurationProvider;
|
||||
import org.apache.struts2.config.providers.XmlConfigurationProvider;
|
||||
import org.apache.struts2.text.TextProvider;
|
||||
import org.apache.struts2.util.ValueStack;
|
||||
import org.apache.struts2.util.ValueStackFactory;
|
||||
import org.apache.struts2.config.StrutsXmlConfigurationProvider;
|
||||
|
||||
@@ -27,7 +27,7 @@ import org.apache.struts2.interceptor.parameter.StrutsParameter;
|
||||
* @author Jason Carreira
|
||||
* Created Apr 8, 2003 6:27:29 PM
|
||||
*/
|
||||
public class ModelDrivenAction extends ActionSupport implements ModelDriven {
|
||||
public class ModelDrivenAction extends ActionSupport implements ModelDriven<TestBean> {
|
||||
|
||||
private String foo;
|
||||
private final TestBean model = new TestBean();
|
||||
|
||||
@@ -20,6 +20,7 @@ package org.apache.struts2;
|
||||
|
||||
import org.apache.struts2.mock.DummyTextProvider;
|
||||
import org.apache.struts2.mock.InjectableAction;
|
||||
import org.apache.struts2.text.TextProvider;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
*/
|
||||
package org.apache.struts2.components;
|
||||
|
||||
import org.apache.struts2.LocalizedTextProvider;
|
||||
import org.apache.struts2.text.LocalizedTextProvider;
|
||||
import org.apache.struts2.StrutsException;
|
||||
import org.apache.struts2.TestConfigurationProvider;
|
||||
import org.apache.struts2.views.jsp.AbstractTagTest;
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
*/
|
||||
package org.apache.struts2.config;
|
||||
|
||||
import org.apache.struts2.LocalizedTextProvider;
|
||||
import org.apache.struts2.text.LocalizedTextProvider;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
import org.apache.struts2.StrutsInternalTestCase;
|
||||
|
||||
|
||||
@@ -21,8 +21,7 @@ package org.apache.struts2.config;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.apache.struts2.XWorkTestCase;
|
||||
import org.apache.struts2.LocalizedTextProvider;
|
||||
import org.apache.struts2.config.ConfigurationException;
|
||||
import org.apache.struts2.text.LocalizedTextProvider;
|
||||
import org.apache.struts2.test.StubConfigurationProvider;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
|
||||
|
||||
+3
-3
@@ -52,7 +52,7 @@ public class ConfigurationProviderOgnlAllowlistTest extends XWorkJUnit4TestCase
|
||||
Class.forName("org.apache.struts2.interceptor.ConditionalInterceptor"),
|
||||
Class.forName("org.apache.struts2.ActionSupport"),
|
||||
Class.forName("org.apache.struts2.result.ActionChainResult"),
|
||||
Class.forName("org.apache.struts2.TextProvider"),
|
||||
Class.forName("org.apache.struts2.text.TextProvider"),
|
||||
Class.forName("org.apache.struts2.interceptor.NoOpInterceptor"),
|
||||
Class.forName("org.apache.struts2.interceptor.Interceptor"),
|
||||
Class.forName("java.lang.Object"),
|
||||
@@ -77,7 +77,7 @@ public class ConfigurationProviderOgnlAllowlistTest extends XWorkJUnit4TestCase
|
||||
Class.forName("org.apache.struts2.mock.MockResult"),
|
||||
Class.forName("org.apache.struts2.interceptor.ConditionalInterceptor"),
|
||||
Class.forName("org.apache.struts2.ActionSupport"),
|
||||
Class.forName("org.apache.struts2.TextProvider"),
|
||||
Class.forName("org.apache.struts2.text.TextProvider"),
|
||||
Class.forName("org.apache.struts2.interceptor.Interceptor"),
|
||||
Class.forName("java.lang.Object"),
|
||||
Class.forName("org.apache.struts2.Validateable"),
|
||||
@@ -101,7 +101,7 @@ public class ConfigurationProviderOgnlAllowlistTest extends XWorkJUnit4TestCase
|
||||
Class.forName("org.apache.struts2.interceptor.ConditionalInterceptor"),
|
||||
Class.forName("org.apache.struts2.ActionSupport"),
|
||||
Class.forName("org.apache.struts2.result.ActionChainResult"),
|
||||
Class.forName("org.apache.struts2.TextProvider"),
|
||||
Class.forName("org.apache.struts2.text.TextProvider"),
|
||||
Class.forName("org.apache.struts2.interceptor.NoOpInterceptor"),
|
||||
Class.forName("org.apache.struts2.interceptor.Interceptor"),
|
||||
Class.forName("java.lang.Object"),
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
package org.apache.struts2.conversion.impl;
|
||||
|
||||
import org.apache.struts2.ActionContext;
|
||||
import org.apache.struts2.StubTextProvider;
|
||||
import org.apache.struts2.text.StubTextProvider;
|
||||
import org.apache.struts2.StubValueStack;
|
||||
import org.apache.struts2.util.ValueStack;
|
||||
import org.apache.struts2.StrutsInternalTestCase;
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
package org.apache.struts2.conversion.impl;
|
||||
|
||||
import org.apache.struts2.ActionContext;
|
||||
import org.apache.struts2.StubTextProvider;
|
||||
import org.apache.struts2.text.StubTextProvider;
|
||||
import org.apache.struts2.StubValueStack;
|
||||
import org.apache.struts2.XWorkTestCase;
|
||||
import org.apache.struts2.util.ValueStack;
|
||||
|
||||
@@ -21,10 +21,10 @@ package org.apache.struts2.conversion.impl;
|
||||
import org.apache.struts2.ActionContext;
|
||||
import org.apache.struts2.ModelDrivenAction;
|
||||
import org.apache.struts2.SimpleAction;
|
||||
import org.apache.struts2.StubTextProvider;
|
||||
import org.apache.struts2.text.StubTextProvider;
|
||||
import org.apache.struts2.StubValueStack;
|
||||
import org.apache.struts2.TestBean;
|
||||
import org.apache.struts2.TextProvider;
|
||||
import org.apache.struts2.text.TextProvider;
|
||||
import org.apache.struts2.XWorkTestCase;
|
||||
import org.apache.struts2.ognl.OgnlValueStack;
|
||||
import org.apache.struts2.test.ModelDrivenAction2;
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
package org.apache.struts2.dispatcher;
|
||||
|
||||
import org.apache.struts2.ActionContext;
|
||||
import org.apache.struts2.LocalizedTextProvider;
|
||||
import org.apache.struts2.text.LocalizedTextProvider;
|
||||
import org.apache.struts2.ObjectFactory;
|
||||
import org.apache.struts2.StubValueStack;
|
||||
import org.apache.struts2.config.ConfigurationException;
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ import org.apache.struts2.ActionSupport;
|
||||
import org.apache.struts2.ModelDrivenAction;
|
||||
import org.apache.struts2.SimpleAction;
|
||||
import org.apache.struts2.TestBean;
|
||||
import org.apache.struts2.TextProvider;
|
||||
import org.apache.struts2.text.TextProvider;
|
||||
import org.apache.struts2.XWorkTestCase;
|
||||
import org.apache.struts2.config.entities.ActionConfig;
|
||||
import org.apache.struts2.config.providers.MockConfigurationProvider;
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
*/
|
||||
package org.apache.struts2.mock;
|
||||
|
||||
import org.apache.struts2.TextProvider;
|
||||
import org.apache.struts2.text.TextProvider;
|
||||
import org.apache.struts2.util.ValueStack;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
*/
|
||||
package org.apache.struts2.mock;
|
||||
|
||||
import org.apache.struts2.TextProvider;
|
||||
import org.apache.struts2.text.TextProvider;
|
||||
import org.apache.struts2.inject.Inject;
|
||||
|
||||
public class InjectableAction {
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
package org.apache.struts2.ognl;
|
||||
|
||||
import org.apache.struts2.ActionContext;
|
||||
import org.apache.struts2.StubTextProvider;
|
||||
import org.apache.struts2.text.StubTextProvider;
|
||||
import org.apache.struts2.StubValueStack;
|
||||
import org.apache.struts2.XWorkTestCase;
|
||||
import org.apache.struts2.config.ConfigurationException;
|
||||
|
||||
@@ -20,7 +20,7 @@ package org.apache.struts2.ognl;
|
||||
|
||||
import org.apache.struts2.SimpleAction;
|
||||
import org.apache.struts2.TestBean;
|
||||
import org.apache.struts2.TextProvider;
|
||||
import org.apache.struts2.text.TextProvider;
|
||||
import org.apache.struts2.XWorkTestCase;
|
||||
import org.apache.struts2.config.ConfigurationException;
|
||||
import org.apache.struts2.conversion.impl.ConversionData;
|
||||
|
||||
@@ -30,7 +30,6 @@ public class ModelDrivenAction2 extends ModelDrivenAction {
|
||||
|
||||
private final TestBean2 model = new TestBean2();
|
||||
|
||||
|
||||
/**
|
||||
* @return the model to be pushed onto the ValueStack after the Action itself
|
||||
*/
|
||||
|
||||
+24
-22
@@ -16,25 +16,20 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.struts2;
|
||||
package org.apache.struts2.text;
|
||||
|
||||
import org.apache.struts2.ActionContext;
|
||||
import org.apache.struts2.XWorkTestCase;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Locale;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
* <code>CompositeTextProviderTest</code>
|
||||
*
|
||||
* @author <a href="mailto:hermanns@aixcept.de">Rainer Hermanns</a>
|
||||
* @version $Id$
|
||||
*/
|
||||
public class CompositeTextProviderTest extends XWorkTestCase {
|
||||
|
||||
|
||||
private CompositeTextProvider textProvider = null;
|
||||
|
||||
|
||||
public void testGetText() throws Exception {
|
||||
public void testGetText() {
|
||||
// we should get the text from the 1st text provider
|
||||
assertEquals(textProvider.getText("name"), "1 name");
|
||||
assertEquals(textProvider.getText("age"), "1 age");
|
||||
@@ -45,8 +40,7 @@ public class CompositeTextProviderTest extends XWorkTestCase {
|
||||
assertEquals(textProvider.getText("someNonExistingKey"), "someNonExistingKey");
|
||||
}
|
||||
|
||||
|
||||
public void testGetTextWithDefaultValues() throws Exception {
|
||||
public void testGetTextWithDefaultValues() {
|
||||
assertEquals(textProvider.getText("name", "some default name"), "1 name");
|
||||
assertEquals(textProvider.getText("age", "some default age"), "1 age");
|
||||
assertEquals(textProvider.getText("no_such_key", "default value"), "default value");
|
||||
@@ -56,16 +50,24 @@ public class CompositeTextProviderTest extends XWorkTestCase {
|
||||
assertEquals(textProvider.getText("bike", "some default bike"), "This is a bike");
|
||||
}
|
||||
|
||||
|
||||
public void testGetTextWithDefaultValuesAndArgs() throws Exception {
|
||||
public void testGetTextWithDefaultValuesAndArgs() {
|
||||
assertEquals(textProvider.getText("goodnight", "say good night", "Adam"), "1 good night Adam");
|
||||
assertEquals(textProvider.getText("goodnight", "say good night", new String[] { "Adam" }), "1 good night Adam");
|
||||
assertEquals(textProvider.getText("goodnight", "say good night", new ArrayList<Object>() { {add("Adam");} }), "1 good night Adam");
|
||||
assertEquals(textProvider.getText("goodmorning", "say good morning", new String[] { "Jack", "Jim" }), "1 good morning Jack and Jim");
|
||||
assertEquals(textProvider.getText("goodmorning", "say good morning", new ArrayList<Object>() { { add("Jack"); add("Jim"); }}), "1 good morning Jack and Jim");
|
||||
assertEquals(textProvider.getText("goodnight", "say good night", new String[]{"Adam"}), "1 good night Adam");
|
||||
assertEquals(textProvider.getText("goodnight", "say good night", new ArrayList<>() {
|
||||
{
|
||||
add("Adam");
|
||||
}
|
||||
}), "1 good night Adam");
|
||||
assertEquals(textProvider.getText("goodmorning", "say good morning", new String[]{"Jack", "Jim"}), "1 good morning Jack and Jim");
|
||||
assertEquals(textProvider.getText("goodmorning", "say good morning", new ArrayList<>() {
|
||||
{
|
||||
add("Jack");
|
||||
add("Jim");
|
||||
}
|
||||
}), "1 good morning Jack and Jim");
|
||||
}
|
||||
|
||||
public void testHasKey() throws Exception {
|
||||
public void testHasKey() {
|
||||
assertTrue(textProvider.hasKey("name"));
|
||||
assertTrue(textProvider.hasKey("age"));
|
||||
assertTrue(textProvider.hasKey("cat"));
|
||||
@@ -77,15 +79,15 @@ public class CompositeTextProviderTest extends XWorkTestCase {
|
||||
assertFalse(textProvider.hasKey("nosuchkey"));
|
||||
}
|
||||
|
||||
public void testGetResourceBundleByName() throws Exception {
|
||||
public void testGetResourceBundleByName() {
|
||||
assertNotNull(textProvider.getTexts("org.apache.struts2.validator.CompositeTextProviderTestResourceBundle1"));
|
||||
assertNotNull(textProvider.getTexts("org.apache.struts2.validator.CompositeTextProviderTestResourceBundle2"));
|
||||
assertNull(textProvider.getTexts("org.apache.struts2.validator.CompositeTextProviderTestResourceBundle3"));
|
||||
}
|
||||
|
||||
public void testGetResourceBundle() throws Exception {
|
||||
public void testGetResourceBundle() {
|
||||
assertNotNull(textProvider.getTexts());
|
||||
// we should get the first resource bundle where 'car' and 'bike' has a i18n msg
|
||||
// we should get the first resource bundle where 'car' and 'bike' has an i18n msg
|
||||
assertNotNull(textProvider.getTexts().getString("car"));
|
||||
assertNotNull(textProvider.getTexts().getString("bike"));
|
||||
}
|
||||
+15
-17
@@ -16,22 +16,20 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.struts2;
|
||||
package org.apache.struts2.text;
|
||||
|
||||
import org.apache.struts2.ActionContext;
|
||||
import org.apache.struts2.XWorkTestCase;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Unit test for {@link DefaultTextProvider}.
|
||||
*
|
||||
* @author Claus Ibsen
|
||||
*/
|
||||
public class DefaultTextProviderTest extends XWorkTestCase {
|
||||
|
||||
private DefaultTextProvider tp;
|
||||
|
||||
public void testSimpleGetTexts() throws Exception {
|
||||
public void testSimpleGetTexts() {
|
||||
assertEquals("Hello World", tp.getText("hello"));
|
||||
assertEquals(null, tp.getText("not.in.bundle"));
|
||||
assertNull(tp.getText("not.in.bundle"));
|
||||
|
||||
assertEquals("Hello World", tp.getText("hello", "this is default"));
|
||||
assertEquals("this is default", tp.getText("not.in.bundle", "this is default"));
|
||||
@@ -43,16 +41,16 @@ public class DefaultTextProviderTest extends XWorkTestCase {
|
||||
assertEquals("Hello World", tp.getText("hello", nullStrings));
|
||||
}
|
||||
|
||||
public void testGetTextsWithArgs() throws Exception {
|
||||
public void testGetTextsWithArgs() {
|
||||
assertEquals("Hello World", tp.getText("hello", "this is default", "from me")); // no args in bundle
|
||||
assertEquals("Hello World from me", tp.getText("hello.0", "this is default", "from me"));
|
||||
assertEquals("this is default", tp.getText("not.in.bundle", "this is default", "from me"));
|
||||
assertEquals("this is default from me", tp.getText("not.in.bundle", "this is default {0}", "from me"));
|
||||
|
||||
assertEquals(null, tp.getText("not.in.bundle"));
|
||||
assertNull(tp.getText("not.in.bundle"));
|
||||
}
|
||||
|
||||
public void testGetTextsWithListArgs() throws Exception {
|
||||
public void testGetTextsWithListArgs() {
|
||||
List<Object> args = new ArrayList<>();
|
||||
args.add("Santa");
|
||||
args.add("loud");
|
||||
@@ -68,13 +66,13 @@ public class DefaultTextProviderTest extends XWorkTestCase {
|
||||
assertEquals("Hello World Santa", tp.getText("hello.0", args)); // only 1 arg in bundle
|
||||
assertEquals("Hello World. This is Santa speaking loud", tp.getText("hello.1", args));
|
||||
|
||||
assertEquals(null, tp.getText("not.in.bundle", args));
|
||||
assertNull(tp.getText("not.in.bundle", args));
|
||||
|
||||
assertEquals("Hello World", tp.getText("hello", "this is default", (List) null));
|
||||
assertEquals("this is default", tp.getText("not.in.bundle", "this is default", (List) null));
|
||||
}
|
||||
|
||||
public void testGetTextsWithArrayArgs() throws Exception {
|
||||
public void testGetTextsWithArrayArgs() {
|
||||
String[] args = { "Santa", "loud" };
|
||||
assertEquals("Hello World", tp.getText("hello", "this is default", args)); // no args in bundle
|
||||
assertEquals("Hello World Santa", tp.getText("hello.0", "this is default", args)); // only 1 arg in bundle
|
||||
@@ -88,13 +86,13 @@ public class DefaultTextProviderTest extends XWorkTestCase {
|
||||
assertEquals("Hello World Santa", tp.getText("hello.0", args)); // only 1 arg in bundle
|
||||
assertEquals("Hello World. This is Santa speaking loud", tp.getText("hello.1", args));
|
||||
|
||||
assertEquals(null, tp.getText("not.in.bundle", args));
|
||||
assertNull(tp.getText("not.in.bundle", args));
|
||||
|
||||
assertEquals("Hello World", tp.getText("hello", "this is default", (String[]) null));
|
||||
assertEquals("this is default", tp.getText("not.in.bundle", "this is default", (String[]) null));
|
||||
}
|
||||
|
||||
public void testGetTextsWithListAndStack() throws Exception {
|
||||
public void testGetTextsWithListAndStack() {
|
||||
List<Object> args = new ArrayList<>();
|
||||
args.add("Santa");
|
||||
args.add("loud");
|
||||
@@ -107,7 +105,7 @@ public class DefaultTextProviderTest extends XWorkTestCase {
|
||||
assertEquals("this is default Santa speaking loud", tp.getText("not.in.bundle", "this is default {0} speaking {1}", args, null));
|
||||
}
|
||||
|
||||
public void testGetTextsWithArrayAndStack() throws Exception {
|
||||
public void testGetTextsWithArrayAndStack() {
|
||||
String[] args = { "Santa", "loud" };
|
||||
assertEquals("Hello World", tp.getText("hello", "this is default", args, null)); // no args in bundle
|
||||
assertEquals("Hello World Santa", tp.getText("hello.0", "this is default", args, null)); // only 1 arg in bundle
|
||||
@@ -118,7 +116,7 @@ public class DefaultTextProviderTest extends XWorkTestCase {
|
||||
assertEquals("this is default Santa speaking loud", tp.getText("not.in.bundle", "this is default {0} speaking {1}", args, null));
|
||||
}
|
||||
|
||||
public void testGetBundle() throws Exception {
|
||||
public void testGetBundle() {
|
||||
assertNull(tp.getTexts()); // always returns null
|
||||
|
||||
ResourceBundle rb = ResourceBundle.getBundle(TextProviderSupportTest.class.getName(), Locale.CANADA);
|
||||
+50
-61
@@ -16,23 +16,24 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.struts2.util;
|
||||
package org.apache.struts2.text;
|
||||
|
||||
import com.mockobjects.dynamic.Mock;
|
||||
import org.apache.struts2.action.Action;
|
||||
import org.apache.struts2.ActionContext;
|
||||
import org.apache.struts2.ActionInvocation;
|
||||
import org.apache.struts2.ActionProxy;
|
||||
import org.apache.struts2.ActionSupport;
|
||||
import org.apache.struts2.LocalizedTextProvider;
|
||||
import org.apache.struts2.ModelDriven;
|
||||
import org.apache.struts2.SimpleAction;
|
||||
import org.apache.struts2.XWorkTestCase;
|
||||
import org.apache.struts2.action.Action;
|
||||
import org.apache.struts2.config.StrutsXmlConfigurationProvider;
|
||||
import org.apache.struts2.config.providers.XmlConfigurationProvider;
|
||||
import org.apache.struts2.interceptor.parameter.StrutsParameter;
|
||||
import org.apache.struts2.test.ModelDrivenAction2;
|
||||
import org.apache.struts2.test.TestBean2;
|
||||
import org.apache.struts2.config.StrutsXmlConfigurationProvider;
|
||||
import org.apache.struts2.interceptor.parameter.StrutsParameter;
|
||||
import org.apache.struts2.util.Bar;
|
||||
import org.apache.struts2.util.ValueStack;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.ParseException;
|
||||
@@ -41,19 +42,11 @@ import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
|
||||
/**
|
||||
* Unit test for {@link StrutsLocalizedTextProvider}.
|
||||
*
|
||||
* @author jcarreira
|
||||
* @author tm_jee
|
||||
* @version $Date$ $Id$
|
||||
*/
|
||||
public class StrutsLocalizedTextProviderTest extends XWorkTestCase {
|
||||
|
||||
private LocalizedTextProvider localizedTextProvider;
|
||||
|
||||
public void testNpeWhenClassIsPrimitive() throws Exception {
|
||||
public void testNpeWhenClassIsPrimitive() {
|
||||
ValueStack stack = ActionContext.getContext().getValueStack();
|
||||
stack.push(new MyObject());
|
||||
String result = localizedTextProvider.findText(MyObject.class, "someObj.someI18nKey", Locale.ENGLISH, "default message", null, stack);
|
||||
@@ -66,15 +59,15 @@ public class StrutsLocalizedTextProviderTest extends XWorkTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
public void testActionGetTextWithNullObject() throws Exception {
|
||||
public void testActionGetTextWithNullObject() {
|
||||
MyAction action = new MyAction();
|
||||
container.inject(action);
|
||||
|
||||
Mock mockActionInvocation = new Mock(ActionInvocation.class);
|
||||
mockActionInvocation.expectAndReturn("getAction", action);
|
||||
ActionContext.getContext()
|
||||
.withActionInvocation((ActionInvocation) mockActionInvocation.proxy())
|
||||
.getValueStack().push(action);
|
||||
.withActionInvocation((ActionInvocation) mockActionInvocation.proxy())
|
||||
.getValueStack().push(action);
|
||||
|
||||
String message = action.getText("barObj.title");
|
||||
assertEquals("Title:", message);
|
||||
@@ -94,11 +87,11 @@ public class StrutsLocalizedTextProviderTest extends XWorkTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
public void testActionGetText() throws Exception {
|
||||
public void testActionGetText() {
|
||||
ModelDrivenAction2 action = new ModelDrivenAction2();
|
||||
container.inject(action);
|
||||
|
||||
TestBean2 bean = (TestBean2) action.getModel();
|
||||
TestBean2 bean = action.getModel();
|
||||
Bar bar = new Bar();
|
||||
bean.setBarObj(bar);
|
||||
|
||||
@@ -116,7 +109,7 @@ public class StrutsLocalizedTextProviderTest extends XWorkTestCase {
|
||||
localizedTextProvider.findText(this.getClass(), null, Locale.getDefault());
|
||||
}
|
||||
|
||||
public void testActionGetTextXXX() throws Exception {
|
||||
public void testActionGetTextXXX() {
|
||||
localizedTextProvider.addDefaultResourceBundle("org/apache/struts2/util/FindMe");
|
||||
|
||||
SimpleAction action = new SimpleAction();
|
||||
@@ -125,8 +118,8 @@ public class StrutsLocalizedTextProviderTest extends XWorkTestCase {
|
||||
Mock mockActionInvocation = new Mock(ActionInvocation.class);
|
||||
mockActionInvocation.expectAndReturn("getAction", action);
|
||||
ActionContext.getContext()
|
||||
.withActionInvocation((ActionInvocation) mockActionInvocation.proxy())
|
||||
.getValueStack().push(action);
|
||||
.withActionInvocation((ActionInvocation) mockActionInvocation.proxy())
|
||||
.getValueStack().push(action);
|
||||
|
||||
String message = action.getText("bean.name");
|
||||
String foundBean2 = action.getText("bean2.name");
|
||||
@@ -148,16 +141,16 @@ public class StrutsLocalizedTextProviderTest extends XWorkTestCase {
|
||||
public void testAddDefaultResourceBundle2() throws Exception {
|
||||
localizedTextProvider.addDefaultResourceBundle("org/apache/struts2/SimpleAction");
|
||||
|
||||
ActionProxy proxy = actionProxyFactory.createActionProxy("/", "packagelessAction", null, new HashMap<String, Object>(), false, true);
|
||||
ActionProxy proxy = actionProxyFactory.createActionProxy("/", "packagelessAction", null, new HashMap<>(), false, true);
|
||||
proxy.execute();
|
||||
}
|
||||
|
||||
public void testDefaultMessage() throws Exception {
|
||||
public void testDefaultMessage() {
|
||||
String message = localizedTextProvider.findDefaultText("xwork.error.action.execution", Locale.getDefault());
|
||||
assertEquals("Error during Action invocation", message);
|
||||
}
|
||||
|
||||
public void testDefaultMessageOverride() throws Exception {
|
||||
public void testDefaultMessageOverride() {
|
||||
String message = localizedTextProvider.findDefaultText("xwork.error.action.execution", Locale.getDefault());
|
||||
assertEquals("Error during Action invocation", message);
|
||||
|
||||
@@ -167,8 +160,8 @@ public class StrutsLocalizedTextProviderTest extends XWorkTestCase {
|
||||
assertEquals("Testing resource bundle override", message);
|
||||
}
|
||||
|
||||
public void testFindTextInChildProperty() throws Exception {
|
||||
ModelDriven action = new ModelDrivenAction2();
|
||||
public void testFindTextInChildProperty() {
|
||||
ModelDriven<?> action = new ModelDrivenAction2();
|
||||
TestBean2 bean = (TestBean2) action.getModel();
|
||||
Bar bar = new Bar();
|
||||
bean.setBarObj(bar);
|
||||
@@ -184,7 +177,7 @@ public class StrutsLocalizedTextProviderTest extends XWorkTestCase {
|
||||
assertEquals("Title is invalid!", message);
|
||||
}
|
||||
|
||||
public void testFindTextInInterface() throws Exception {
|
||||
public void testFindTextInInterface() {
|
||||
Action action = new ModelDrivenAction2();
|
||||
Mock mockActionInvocation = new Mock(ActionInvocation.class);
|
||||
mockActionInvocation.expectAndReturn("getAction", action);
|
||||
@@ -194,8 +187,8 @@ public class StrutsLocalizedTextProviderTest extends XWorkTestCase {
|
||||
assertEquals("Foo!", message);
|
||||
}
|
||||
|
||||
public void testFindTextInPackage() throws Exception {
|
||||
ModelDriven action = new ModelDrivenAction2();
|
||||
public void testFindTextInPackage() {
|
||||
ModelDriven<?> action = new ModelDrivenAction2();
|
||||
|
||||
Mock mockActionInvocation = new Mock(ActionInvocation.class);
|
||||
mockActionInvocation.expectAndReturn("getAction", action);
|
||||
@@ -205,12 +198,12 @@ public class StrutsLocalizedTextProviderTest extends XWorkTestCase {
|
||||
assertEquals("It works!", message);
|
||||
}
|
||||
|
||||
public void testParameterizedDefaultMessage() throws Exception {
|
||||
public void testParameterizedDefaultMessage() {
|
||||
String message = localizedTextProvider.findDefaultText("xwork.exception.missing-action", Locale.getDefault(), new String[]{"AddUser"});
|
||||
assertEquals("There is no Action mapped for action name AddUser.", message);
|
||||
}
|
||||
|
||||
public void testParameterizedDefaultMessageWithPackage() throws Exception {
|
||||
public void testParameterizedDefaultMessageWithPackage() {
|
||||
String message = localizedTextProvider.findDefaultText("xwork.exception.missing-package-action", Locale.getDefault(), new String[]{"blah", "AddUser"});
|
||||
assertEquals("There is no Action mapped for namespace blah and action name AddUser.", message);
|
||||
}
|
||||
@@ -270,20 +263,18 @@ public class StrutsLocalizedTextProviderTest extends XWorkTestCase {
|
||||
*/
|
||||
public void testLocalizedTextProviderClearingMethods() {
|
||||
TestStrutsLocalizedTextProvider testStrutsLocalizedTextProvider = new TestStrutsLocalizedTextProvider();
|
||||
assertTrue("testStrutsLocalizedTextProvider not instance of AbstractLocalizedTextProvider ?",
|
||||
testStrutsLocalizedTextProvider instanceof AbstractLocalizedTextProvider);
|
||||
assertEquals("testStrutsLocalizedTextProvider starting default bundle map size not 0 before any retrievals ?",
|
||||
0, testStrutsLocalizedTextProvider.currentBundlesMapSize());
|
||||
0, testStrutsLocalizedTextProvider.currentBundlesMapSize());
|
||||
|
||||
// Access the two default bundles to populate their cache entries and test bundle map size.
|
||||
ResourceBundle tempBundle = testStrutsLocalizedTextProvider.findResourceBundle(
|
||||
TestStrutsLocalizedTextProvider.XWORK_MESSAGES_BUNDLE, Locale.ENGLISH);
|
||||
TestStrutsLocalizedTextProvider.XWORK_MESSAGES_BUNDLE, Locale.ENGLISH);
|
||||
assertNotNull("XWORK_MESSAGES_BUNDLE retrieval null ?", tempBundle);
|
||||
tempBundle = testStrutsLocalizedTextProvider.findResourceBundle(
|
||||
TestStrutsLocalizedTextProvider.STRUTS_MESSAGES_BUNDLE, Locale.ENGLISH);
|
||||
TestStrutsLocalizedTextProvider.STRUTS_MESSAGES_BUNDLE, Locale.ENGLISH);
|
||||
assertNotNull("STRUTS_MESSAGES_BUNDLE retrieval null ?", tempBundle);
|
||||
assertEquals("testStrutsLocalizedTextProvider bundle map size not 2 after retrievals ?",
|
||||
2, testStrutsLocalizedTextProvider.currentBundlesMapSize());
|
||||
2, testStrutsLocalizedTextProvider.currentBundlesMapSize());
|
||||
|
||||
// Add and then access four test bundles to populate their cache entries and test bundle map size.
|
||||
testStrutsLocalizedTextProvider.addDefaultResourceBundle("org/apache/struts2/util/LocalizedTextUtilTest");
|
||||
@@ -291,34 +282,34 @@ public class StrutsLocalizedTextProviderTest extends XWorkTestCase {
|
||||
testStrutsLocalizedTextProvider.addDefaultResourceBundle("org/apache/struts2/SimpleAction");
|
||||
testStrutsLocalizedTextProvider.addDefaultResourceBundle("org/apache/struts2/test");
|
||||
tempBundle = testStrutsLocalizedTextProvider.findResourceBundle(
|
||||
"org/apache/struts2/util/LocalizedTextUtilTest", Locale.ENGLISH);
|
||||
"org/apache/struts2/util/LocalizedTextUtilTest", Locale.ENGLISH);
|
||||
assertNotNull("org/apache/struts2/util/LocalizedTextUtilTest retrieval null ?", tempBundle);
|
||||
tempBundle = testStrutsLocalizedTextProvider.findResourceBundle(
|
||||
"org/apache/struts2/util/FindMe", Locale.ENGLISH);
|
||||
"org/apache/struts2/util/FindMe", Locale.ENGLISH);
|
||||
assertNotNull("org/apache/struts2/util/FindMe retrieval null ?", tempBundle);
|
||||
tempBundle = testStrutsLocalizedTextProvider.findResourceBundle(
|
||||
"org/apache/struts2/SimpleAction", Locale.ENGLISH);
|
||||
"org/apache/struts2/SimpleAction", Locale.ENGLISH);
|
||||
assertNotNull("org/apache/struts2/SimpleAction retrieval null ?", tempBundle);
|
||||
tempBundle = testStrutsLocalizedTextProvider.findResourceBundle(
|
||||
"org/apache/struts2/test", Locale.ENGLISH);
|
||||
"org/apache/struts2/test", Locale.ENGLISH);
|
||||
assertNotNull("org/apache/struts2/test retrieval null ?", tempBundle);
|
||||
assertEquals("testStrutsLocalizedTextProvider bundle map size not 6 after retrievals ?",
|
||||
6, testStrutsLocalizedTextProvider.currentBundlesMapSize());
|
||||
6, testStrutsLocalizedTextProvider.currentBundlesMapSize());
|
||||
|
||||
// Expect the call to function with bundle name + locale. Remove all four of the non-default
|
||||
// bundles and confirm the bundle map size changes.
|
||||
testStrutsLocalizedTextProvider.callClearBundleWithLocale("org/apache/struts2/test", Locale.ENGLISH);
|
||||
assertEquals("testStrutsLocalizedTextProvider bundle map size not 5 after locale clear call ?",
|
||||
5, testStrutsLocalizedTextProvider.currentBundlesMapSize());
|
||||
5, testStrutsLocalizedTextProvider.currentBundlesMapSize());
|
||||
testStrutsLocalizedTextProvider.callClearBundleWithLocale("org/apache/struts2/SimpleAction", Locale.ENGLISH);
|
||||
assertEquals("testStrutsLocalizedTextProvider bundle map size not 4 after locale clear call ?",
|
||||
4, testStrutsLocalizedTextProvider.currentBundlesMapSize());
|
||||
4, testStrutsLocalizedTextProvider.currentBundlesMapSize());
|
||||
testStrutsLocalizedTextProvider.callClearBundleWithLocale("org/apache/struts2/util/FindMe", Locale.ENGLISH);
|
||||
assertEquals("testStrutsLocalizedTextProvider bundle map size not 3 after locale clear call ?",
|
||||
3, testStrutsLocalizedTextProvider.currentBundlesMapSize());
|
||||
3, testStrutsLocalizedTextProvider.currentBundlesMapSize());
|
||||
testStrutsLocalizedTextProvider.callClearBundleWithLocale("org/apache/struts2/util/LocalizedTextUtilTest", Locale.ENGLISH);
|
||||
assertEquals("testStrutsLocalizedTextProvider bundle map size not 2 after locale clear call ?",
|
||||
2, testStrutsLocalizedTextProvider.currentBundlesMapSize());
|
||||
2, testStrutsLocalizedTextProvider.currentBundlesMapSize());
|
||||
|
||||
// Confirm the missing bundles cache clearing method does not produce any Exceptions or failures.
|
||||
testStrutsLocalizedTextProvider.callClearMissingBundlesCache();
|
||||
@@ -332,20 +323,18 @@ public class StrutsLocalizedTextProviderTest extends XWorkTestCase {
|
||||
*/
|
||||
public void testLocalizedTextProviderReloadMethods() {
|
||||
TestStrutsLocalizedTextProvider testStrutsLocalizedTextProvider = new TestStrutsLocalizedTextProvider();
|
||||
assertTrue("testStrutsLocalizedTextProvider not instance of AbstractLocalizedTextProvider ?",
|
||||
testStrutsLocalizedTextProvider instanceof AbstractLocalizedTextProvider);
|
||||
assertEquals("testStrutsLocalizedTextProvider starting default bundle map size not 0 before any retrievals ?",
|
||||
0, testStrutsLocalizedTextProvider.currentBundlesMapSize());
|
||||
0, testStrutsLocalizedTextProvider.currentBundlesMapSize());
|
||||
|
||||
// Access the two default bundles to populate their cache entries and test bundle map size.
|
||||
ResourceBundle tempBundle = testStrutsLocalizedTextProvider.findResourceBundle(
|
||||
TestStrutsLocalizedTextProvider.XWORK_MESSAGES_BUNDLE, Locale.ENGLISH);
|
||||
TestStrutsLocalizedTextProvider.XWORK_MESSAGES_BUNDLE, Locale.ENGLISH);
|
||||
assertNotNull("XWORK_MESSAGES_BUNDLE retrieval null ?", tempBundle);
|
||||
tempBundle = testStrutsLocalizedTextProvider.findResourceBundle(
|
||||
TestStrutsLocalizedTextProvider.STRUTS_MESSAGES_BUNDLE, Locale.ENGLISH);
|
||||
TestStrutsLocalizedTextProvider.STRUTS_MESSAGES_BUNDLE, Locale.ENGLISH);
|
||||
assertNotNull("STRUTS_MESSAGES_BUNDLE retrieval null ?", tempBundle);
|
||||
assertEquals("testStrutsLocalizedTextProvider bundle map size not 2 after retrievals ?",
|
||||
2, testStrutsLocalizedTextProvider.currentBundlesMapSize());
|
||||
2, testStrutsLocalizedTextProvider.currentBundlesMapSize());
|
||||
|
||||
// Force a bundle reload call for code coverage and to confirm it causes the bundle map to be emptied.
|
||||
assertNotNull("ActionContext is somehow null ?", ActionContext.getContext());
|
||||
@@ -355,17 +344,17 @@ public class StrutsLocalizedTextProviderTest extends XWorkTestCase {
|
||||
boolean bundlesReloadedAfterCall = testStrutsLocalizedTextProvider.getBundlesReloadedIndicatorValue();
|
||||
assertTrue("Bundles reload value false after forced reload ?", bundlesReloadedAfterCall);
|
||||
assertEquals("testStrutsLocalizedTextProvider bundle map size not 0 after reload (which should clear it) ?",
|
||||
0, testStrutsLocalizedTextProvider.currentBundlesMapSize());
|
||||
0, testStrutsLocalizedTextProvider.currentBundlesMapSize());
|
||||
|
||||
// Access the two default bundles again (after reload) to populate their cache entries and test bundle map size.
|
||||
tempBundle = testStrutsLocalizedTextProvider.findResourceBundle(
|
||||
TestStrutsLocalizedTextProvider.XWORK_MESSAGES_BUNDLE, Locale.ENGLISH);
|
||||
TestStrutsLocalizedTextProvider.XWORK_MESSAGES_BUNDLE, Locale.ENGLISH);
|
||||
assertNotNull("XWORK_MESSAGES_BUNDLE retrieval null ?", tempBundle);
|
||||
tempBundle = testStrutsLocalizedTextProvider.findResourceBundle(
|
||||
TestStrutsLocalizedTextProvider.STRUTS_MESSAGES_BUNDLE, Locale.ENGLISH);
|
||||
TestStrutsLocalizedTextProvider.STRUTS_MESSAGES_BUNDLE, Locale.ENGLISH);
|
||||
assertNotNull("STRUTS_MESSAGES_BUNDLE retrieval null ?", tempBundle);
|
||||
assertEquals("testStrutsLocalizedTextProvider bundle map size not 2 after retrievals ?",
|
||||
2, testStrutsLocalizedTextProvider.currentBundlesMapSize());
|
||||
2, testStrutsLocalizedTextProvider.currentBundlesMapSize());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -391,7 +380,7 @@ public class StrutsLocalizedTextProviderTest extends XWorkTestCase {
|
||||
final String DEFAULT_MESSAGE_WITH_PARAMS = DEFAULT_MESSAGE + " We provide a couple of parameter placeholders: -{0}- and -{1}- for fun.";
|
||||
final String param1 = "param1_String";
|
||||
final String param2 = "param2_String";
|
||||
final String[] paramArray = { param1, param2 };
|
||||
final String[] paramArray = {param1, param2};
|
||||
TestStrutsLocalizedTextProvider testStrutsLocalizedTextProvider = new TestStrutsLocalizedTextProvider();
|
||||
|
||||
// Load some specific default bundles already provided and used by other tests within this module.
|
||||
@@ -457,7 +446,7 @@ public class StrutsLocalizedTextProviderTest extends XWorkTestCase {
|
||||
/**
|
||||
* Test the {@link StrutsLocalizedTextProvider#findText(java.lang.Class, java.lang.String, java.util.Locale, java.lang.String, java.lang.Object[], org.apache.struts2.util.ValueStack) }
|
||||
* method for basic correctness.
|
||||
*
|
||||
* <p>
|
||||
* It is the version of the method that will search the class hierarchy resource bundles first, unless {@link StrutsLocalizedTextProvider#searchDefaultBundlesFirst}
|
||||
* is true (in which case it will search the default resource bundles first). No matter the flag setting, it should search until it finds a match, or fails to find
|
||||
* a match and returns the default message parameter that was passed.
|
||||
@@ -469,7 +458,7 @@ public class StrutsLocalizedTextProviderTest extends XWorkTestCase {
|
||||
final String DEFAULT_MESSAGE_WITH_PARAMS = DEFAULT_MESSAGE + " We provide a couple of parameter placeholders: -{0}- and -{1}- for fun.";
|
||||
final String param1 = "param1_String";
|
||||
final String param2 = "param2_String";
|
||||
final String[] paramArray = { param1, param2 };
|
||||
final String[] paramArray = {param1, param2};
|
||||
TestStrutsLocalizedTextProvider testStrutsLocalizedTextProvider = new TestStrutsLocalizedTextProvider();
|
||||
|
||||
// Load some specific default bundles already provided and used by other tests within this module.
|
||||
@@ -585,7 +574,7 @@ public class StrutsLocalizedTextProviderTest extends XWorkTestCase {
|
||||
|
||||
/**
|
||||
* Some test correctness depends on this {@link #RELOADED} value matching that of the private ancestor
|
||||
* field {@link AbstractLocalizedTextProvider#RELOADED}. If the ancestor field value changes, ensure this
|
||||
* field {@link AbstractLocalizedTextProvider#RELOADED}. If the ancestor field value changes, ensure this
|
||||
* field's value is updated to match it exactly.
|
||||
*/
|
||||
private static final String RELOADED = "org.apache.struts2.util.LocalizedTextProvider.reloaded";
|
||||
+1
-1
@@ -16,7 +16,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.struts2;
|
||||
package org.apache.struts2.text;
|
||||
|
||||
import org.apache.struts2.util.ValueStack;
|
||||
|
||||
+16
-17
@@ -16,29 +16,27 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.struts2;
|
||||
package org.apache.struts2.text;
|
||||
|
||||
import org.apache.struts2.LocaleProvider;
|
||||
import org.apache.struts2.XWorkTestCase;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
* Unit test for {@link TextProviderSupport}.
|
||||
*
|
||||
* @author Claus Ibsen
|
||||
*/
|
||||
public class TextProviderSupportTest extends XWorkTestCase {
|
||||
|
||||
private TextProviderSupport tp;
|
||||
private java.util.ResourceBundle rb;
|
||||
|
||||
public void testHasKey() throws Exception {
|
||||
assertTrue(tp.hasKey("hello"));
|
||||
assertFalse(tp.hasKey("not.in.bundle"));
|
||||
public void testHasKey() {
|
||||
assertTrue(tp.hasKey("hello"));
|
||||
assertFalse(tp.hasKey("not.in.bundle"));
|
||||
}
|
||||
|
||||
public void testSimpleGetTexts() throws Exception {
|
||||
public void testSimpleGetTexts() {
|
||||
assertEquals("Hello World", tp.getText("hello"));
|
||||
assertEquals("not.in.bundle", tp.getText("not.in.bundle"));
|
||||
|
||||
@@ -46,7 +44,7 @@ public class TextProviderSupportTest extends XWorkTestCase {
|
||||
assertEquals("this is default", tp.getText("not.in.bundle", "this is default"));
|
||||
}
|
||||
|
||||
public void testGetTextsWithArgs() throws Exception {
|
||||
public void testGetTextsWithArgs() {
|
||||
assertEquals("Hello World", tp.getText("hello", "this is default", "from me")); // no args in bundle
|
||||
assertEquals("Hello World from me", tp.getText("hello.0", "this is default", "from me"));
|
||||
assertEquals("this is default", tp.getText("not.in.bundle", "this is default", "from me"));
|
||||
@@ -55,7 +53,7 @@ public class TextProviderSupportTest extends XWorkTestCase {
|
||||
assertEquals("not.in.bundle", tp.getText("not.in.bundle"));
|
||||
}
|
||||
|
||||
public void testGetTextsWithListArgs() throws Exception {
|
||||
public void testGetTextsWithListArgs() {
|
||||
List<Object> args = new ArrayList<>();
|
||||
args.add("Santa");
|
||||
args.add("loud");
|
||||
@@ -74,8 +72,8 @@ public class TextProviderSupportTest extends XWorkTestCase {
|
||||
assertEquals("not.in.bundle", tp.getText("not.in.bundle", args));
|
||||
}
|
||||
|
||||
public void testGetTextsWithArrayArgs() throws Exception {
|
||||
String[] args = { "Santa", "loud" };
|
||||
public void testGetTextsWithArrayArgs() {
|
||||
String[] args = {"Santa", "loud"};
|
||||
assertEquals("Hello World", tp.getText("hello", "this is default", args)); // no args in bundle
|
||||
assertEquals("Hello World Santa", tp.getText("hello.0", "this is default", args)); // only 1 arg in bundle
|
||||
assertEquals("Hello World. This is Santa speaking loud", tp.getText("hello.1", "this is default", args));
|
||||
@@ -91,18 +89,18 @@ public class TextProviderSupportTest extends XWorkTestCase {
|
||||
assertEquals("not.in.bundle", tp.getText("not.in.bundle", args));
|
||||
}
|
||||
|
||||
public void testGetBundle() throws Exception {
|
||||
public void testGetBundle() {
|
||||
assertEquals(rb, tp.getTexts());
|
||||
assertEquals(rb, tp.getTexts(TextProviderSupportTest.class.getName()));
|
||||
}
|
||||
|
||||
public void testDifficultSymbols1() {
|
||||
String val= tp.getText("symbols1");
|
||||
String val = tp.getText("symbols1");
|
||||
assertEquals("\"=!@#$%^&*(){qwe}<>?:|}{[]\\';/.,<>`~'", val);
|
||||
}
|
||||
|
||||
public void testDifficultSymbols2() {
|
||||
String val= tp.getText("symbols2");
|
||||
String val = tp.getText("symbols2");
|
||||
assertEquals("\"=!@#$%^&*()<>?:|[]\\';/.,<>`~'", val);
|
||||
}
|
||||
|
||||
@@ -132,6 +130,7 @@ public class TextProviderSupportTest extends XWorkTestCase {
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
rb = null;
|
||||
tp = null;
|
||||
}
|
||||
+1
-1
@@ -27,7 +27,7 @@ import org.apache.struts2.FileManager;
|
||||
import org.apache.struts2.FileManagerFactory;
|
||||
import org.apache.struts2.SimpleAction;
|
||||
import org.apache.struts2.SimpleAnnotationAction;
|
||||
import org.apache.struts2.TextProviderFactory;
|
||||
import org.apache.struts2.text.TextProviderFactory;
|
||||
import org.apache.struts2.XWorkTestCase;
|
||||
import org.apache.struts2.config.entities.ActionConfig;
|
||||
import org.apache.struts2.test.AnnotationDataAware2;
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@
|
||||
package org.apache.struts2.validator;
|
||||
|
||||
import org.apache.struts2.ActionContext;
|
||||
import org.apache.struts2.TextProviderFactory;
|
||||
import org.apache.struts2.text.TextProviderFactory;
|
||||
import org.apache.struts2.interceptor.ValidationAware;
|
||||
import org.apache.struts2.ValidationAwareSupport;
|
||||
import org.apache.struts2.XWorkTestCase;
|
||||
|
||||
@@ -21,7 +21,7 @@ package org.apache.struts2.validator;
|
||||
import org.apache.struts2.ActionContext;
|
||||
import org.apache.struts2.ActionProxy;
|
||||
import org.apache.struts2.ActionSupport;
|
||||
import org.apache.struts2.TextProviderFactory;
|
||||
import org.apache.struts2.text.TextProviderFactory;
|
||||
import org.apache.struts2.ValidationAwareSupport;
|
||||
import org.apache.struts2.XWorkTestCase;
|
||||
import org.apache.struts2.config.providers.MockConfigurationProvider;
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
*/
|
||||
package org.apache.struts2.validator;
|
||||
|
||||
import org.apache.struts2.TextProviderFactory;
|
||||
import org.apache.struts2.text.TextProviderFactory;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ package org.apache.struts2.validator;
|
||||
|
||||
import org.apache.struts2.ActionContext;
|
||||
import org.apache.struts2.ActionSupport;
|
||||
import org.apache.struts2.TextProviderFactory;
|
||||
import org.apache.struts2.text.TextProviderFactory;
|
||||
import org.apache.struts2.XWorkTestCase;
|
||||
import org.apache.struts2.util.ValueStack;
|
||||
import org.apache.struts2.validator.validators.EmailValidator;
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.apache.struts2.ActionContext;
|
||||
import org.apache.struts2.ActionInvocation;
|
||||
import org.apache.struts2.ActionProxy;
|
||||
import org.apache.struts2.TestBean;
|
||||
import org.apache.struts2.TextProviderFactory;
|
||||
import org.apache.struts2.text.TextProviderFactory;
|
||||
import org.apache.struts2.ValidationAwareSupport;
|
||||
import org.apache.struts2.XWorkTestCase;
|
||||
import org.apache.struts2.config.entities.ActionConfig;
|
||||
|
||||
@@ -19,9 +19,8 @@
|
||||
package org.apache.struts2.validator;
|
||||
|
||||
import org.apache.struts2.ActionContext;
|
||||
import org.apache.struts2.TextProviderFactory;
|
||||
import org.apache.struts2.text.TextProviderFactory;
|
||||
import org.apache.struts2.XWorkTestCase;
|
||||
import org.apache.struts2.util.ValueStack;
|
||||
import org.apache.struts2.validator.validators.RegexFieldValidator;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ package org.apache.struts2.validator;
|
||||
|
||||
import org.apache.struts2.ActionContext;
|
||||
import org.apache.struts2.ActionSupport;
|
||||
import org.apache.struts2.TextProviderFactory;
|
||||
import org.apache.struts2.text.TextProviderFactory;
|
||||
import org.apache.struts2.XWorkTestCase;
|
||||
import org.apache.struts2.conversion.impl.ConversionData;
|
||||
import org.apache.struts2.mock.MockActionInvocation;
|
||||
|
||||
@@ -21,9 +21,7 @@ package org.apache.struts2.validator;
|
||||
import org.apache.struts2.ActionContext;
|
||||
import org.apache.struts2.ActionProxy;
|
||||
import org.apache.struts2.SimpleAction;
|
||||
import org.apache.struts2.StubTextProvider;
|
||||
import org.apache.struts2.StubValueStack;
|
||||
import org.apache.struts2.TextProviderFactory;
|
||||
import org.apache.struts2.text.TextProviderFactory;
|
||||
import org.apache.struts2.XWorkTestCase;
|
||||
import org.apache.struts2.config.providers.MockConfigurationProvider;
|
||||
import org.apache.struts2.config.providers.XmlConfigurationProvider;
|
||||
|
||||
@@ -20,7 +20,7 @@ package org.apache.struts2.validator;
|
||||
|
||||
import org.apache.struts2.ActionContext;
|
||||
import org.apache.struts2.ActionSupport;
|
||||
import org.apache.struts2.TextProviderFactory;
|
||||
import org.apache.struts2.text.TextProviderFactory;
|
||||
import org.apache.struts2.XWorkTestCase;
|
||||
import org.apache.struts2.util.ValueStack;
|
||||
import org.apache.struts2.validator.validators.StringLengthFieldValidator;
|
||||
|
||||
@@ -22,7 +22,7 @@ import org.apache.struts2.action.Action;
|
||||
import org.apache.struts2.ActionContext;
|
||||
import org.apache.struts2.ActionInvocation;
|
||||
import org.apache.struts2.ActionProxy;
|
||||
import org.apache.struts2.TextProviderFactory;
|
||||
import org.apache.struts2.text.TextProviderFactory;
|
||||
import org.apache.struts2.ValidationAwareSupport;
|
||||
import org.apache.struts2.XWorkTestCase;
|
||||
import org.apache.struts2.config.entities.ActionConfig;
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
package org.apache.struts2.validator;
|
||||
|
||||
import org.apache.struts2.ActionContext;
|
||||
import org.apache.struts2.TextProviderFactory;
|
||||
import org.apache.struts2.text.TextProviderFactory;
|
||||
import org.apache.struts2.XWorkTestCase;
|
||||
import org.apache.struts2.util.ValueStack;
|
||||
import org.apache.struts2.validator.validators.URLValidator;
|
||||
|
||||
+3
-3
@@ -22,9 +22,9 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.struts2.CompositeTextProvider;
|
||||
import org.apache.struts2.TextProvider;
|
||||
import org.apache.struts2.TextProviderFactory;
|
||||
import org.apache.struts2.text.CompositeTextProvider;
|
||||
import org.apache.struts2.text.TextProvider;
|
||||
import org.apache.struts2.text.TextProviderFactory;
|
||||
import org.apache.struts2.XWorkTestCase;
|
||||
import org.apache.struts2.validator.DelegatingValidatorContext;
|
||||
import org.apache.struts2.validator.ValidatorContext;
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
*/
|
||||
package org.apache.struts2.validator.validators;
|
||||
|
||||
import org.apache.struts2.TextProviderFactory;
|
||||
import org.apache.struts2.text.TextProviderFactory;
|
||||
import org.apache.struts2.util.ValueStack;
|
||||
import org.apache.struts2.util.ValueStackFactory;
|
||||
import org.apache.struts2.validator.DummyValidatorContext;
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@
|
||||
package org.apache.struts2.validator.validators;
|
||||
|
||||
import org.apache.struts2.ActionContext;
|
||||
import org.apache.struts2.TextProviderFactory;
|
||||
import org.apache.struts2.text.TextProviderFactory;
|
||||
import org.apache.struts2.XWorkTestCase;
|
||||
import org.apache.struts2.util.ValueStack;
|
||||
import org.apache.struts2.util.ValueStackFactory;
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
*/
|
||||
package org.apache.struts2.validator.validators;
|
||||
|
||||
import org.apache.struts2.TextProviderFactory;
|
||||
import org.apache.struts2.text.TextProviderFactory;
|
||||
import org.apache.struts2.XWorkTestCase;
|
||||
import org.apache.struts2.util.ValueStack;
|
||||
import org.apache.struts2.util.ValueStackFactory;
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
*/
|
||||
package org.apache.struts2.validator.validators;
|
||||
|
||||
import org.apache.struts2.TextProviderFactory;
|
||||
import org.apache.struts2.text.TextProviderFactory;
|
||||
import org.apache.struts2.XWorkTestCase;
|
||||
import org.apache.struts2.util.ValueStack;
|
||||
import org.apache.struts2.util.ValueStackFactory;
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@
|
||||
package org.apache.struts2.validator.validators;
|
||||
|
||||
import org.apache.struts2.ActionContext;
|
||||
import org.apache.struts2.TextProviderFactory;
|
||||
import org.apache.struts2.text.TextProviderFactory;
|
||||
import org.apache.struts2.validator.DummyValidatorContext;
|
||||
import org.apache.struts2.StrutsInternalTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ package org.apache.struts2.validator.validators;
|
||||
|
||||
import org.apache.struts2.ActionContext;
|
||||
import org.apache.struts2.ActionSupport;
|
||||
import org.apache.struts2.TextProviderFactory;
|
||||
import org.apache.struts2.text.TextProviderFactory;
|
||||
import org.apache.struts2.XWorkTestCase;
|
||||
import org.apache.struts2.util.ValueStack;
|
||||
import org.apache.struts2.validator.DummyValidatorContext;
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
*/
|
||||
package org.apache.struts2.validator.validators;
|
||||
|
||||
import org.apache.struts2.TextProviderFactory;
|
||||
import org.apache.struts2.text.TextProviderFactory;
|
||||
import org.apache.struts2.XWorkTestCase;
|
||||
import org.apache.struts2.util.ValueStack;
|
||||
import org.apache.struts2.util.ValueStackFactory;
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ package org.apache.struts.beanvalidation.validation.interceptor;
|
||||
import org.apache.struts2.ActionInvocation;
|
||||
import org.apache.struts2.ActionProxy;
|
||||
import org.apache.struts2.ModelDriven;
|
||||
import org.apache.struts2.TextProviderFactory;
|
||||
import org.apache.struts2.text.TextProviderFactory;
|
||||
import org.apache.struts2.inject.Inject;
|
||||
import org.apache.struts2.interceptor.MethodFilterInterceptor;
|
||||
import org.apache.struts2.validator.DelegatingValidatorContext;
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
*/
|
||||
package org.apache.struts2.mock;
|
||||
|
||||
import org.apache.struts2.TextProvider;
|
||||
import org.apache.struts2.text.TextProvider;
|
||||
import org.apache.struts2.util.ValueStack;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.apache.struts2.ModelDrivenAction;
|
||||
import org.apache.struts2.ObjectFactory;
|
||||
import org.apache.struts2.SimpleAction;
|
||||
import org.apache.struts2.TestBean;
|
||||
import org.apache.struts2.TextProvider;
|
||||
import org.apache.struts2.text.TextProvider;
|
||||
import org.apache.struts2.XWorkTestCase;
|
||||
import org.apache.struts2.config.ConfigurationException;
|
||||
import org.apache.struts2.config.entities.ActionConfig;
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
package org.apache.struts2.tiles;
|
||||
|
||||
import org.apache.struts2.ActionContext;
|
||||
import org.apache.struts2.TextProvider;
|
||||
import org.apache.struts2.TextProviderFactory;
|
||||
import org.apache.struts2.text.TextProvider;
|
||||
import org.apache.struts2.text.TextProviderFactory;
|
||||
import org.apache.struts2.config.ConfigurationException;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
Reference in New Issue
Block a user