- Added some IDE-recommended annotations and cleanup to some of the
  modified files.
- Applied easier-to-read/differentiate names "ognlExpressionCacheFactory"
  and "ognlBeanInfoCacheFactory" for the cache factory configuration
   extension points.
- Reorded default configuration factory init for the cache factories (did
  not help extension override).
- Cleanup of parameterized OgnlUtil constructor.
- Added extension point aliases to StrutsBeanSelectionProvider.
- Added beaninfo for cache factories to ConstantConfig (did not help
  extension override).
- Added cache factory references to default.properties, struts-default.xml.
This commit is contained in:
JCgH4164838Gh792C124B5
2022-05-01 16:25:16 -04:00
parent 084c66723d
commit 199f356669
8 changed files with 83 additions and 29 deletions
@@ -82,30 +82,37 @@ public class DefaultConfiguration implements Configuration {
}
@Override
public PackageConfig getPackageConfig(String name) {
return packageContexts.get(name);
}
@Override
public List<UnknownHandlerConfig> getUnknownHandlerStack() {
return unknownHandlerStack;
}
@Override
public void setUnknownHandlerStack(List<UnknownHandlerConfig> unknownHandlerStack) {
this.unknownHandlerStack = unknownHandlerStack;
}
@Override
public Set<String> getPackageConfigNames() {
return packageContexts.keySet();
}
@Override
public Map<String, PackageConfig> getPackageConfigs() {
return packageContexts;
}
@Override
public Set<String> getLoadedFileNames() {
return loadedFileNames;
}
@Override
public RuntimeConfiguration getRuntimeConfiguration() {
return runtimeConfiguration;
}
@@ -113,10 +120,12 @@ public class DefaultConfiguration implements Configuration {
/**
* @return the container
*/
@Override
public Container getContainer() {
return container;
}
@Override
public void addPackageConfig(String name, PackageConfig packageContext) {
PackageConfig check = packageContexts.get(name);
if (check != null) {
@@ -134,6 +143,7 @@ public class DefaultConfiguration implements Configuration {
packageContexts.put(name, packageContext);
}
@Override
public PackageConfig removePackageConfig(String packageName) {
return packageContexts.remove(packageName);
}
@@ -141,11 +151,13 @@ public class DefaultConfiguration implements Configuration {
/**
* Allows the configuration to clean up any resources used
*/
@Override
public void destroy() {
packageContexts.clear();
loadedFileNames.clear();
}
@Override
public void rebuildRuntimeConfiguration() {
runtimeConfiguration = buildRuntimeConfiguration();
}
@@ -154,10 +166,12 @@ public class DefaultConfiguration implements Configuration {
* Calls the ConfigurationProviderFactory.getConfig() to tell it to reload the configuration and then calls
* buildRuntimeConfiguration().
*
* @param providers list of ContainerProvider
* @return list of package providers
*
* @throws ConfigurationException in case of any configuration errors
*/
@Override
public synchronized List<PackageProvider> reloadContainer(List<ContainerProvider> providers) throws ConfigurationException {
packageContexts.clear();
loadedFileNames.clear();
@@ -175,6 +189,7 @@ public class DefaultConfiguration implements Configuration {
props.setConstants(builder);
builder.factory(Configuration.class, new Factory<Configuration>() {
@Override
public Configuration create(Context context) throws Exception {
return DefaultConfiguration.this;
}
@@ -282,13 +297,12 @@ public class DefaultConfiguration implements Configuration {
builder.factory(ObjectTypeDeterminer.class, DefaultObjectTypeDeterminer.class, Scope.SINGLETON);
builder.factory(PropertyAccessor.class, CompoundRoot.class.getName(), CompoundRootAccessor.class, Scope.SINGLETON);
builder.factory(OgnlCacheFactory.class, "ognlExpressionCacheFactory", DefaultOgnlExpressionCacheFactory.class, Scope.SINGLETON);
builder.factory(OgnlCacheFactory.class, "ognlBeanInfoCacheFactory", DefaultOgnlBeanInfoCacheFactory.class, Scope.SINGLETON);
builder.factory(OgnlUtil.class, Scope.SINGLETON);
builder.factory(ValueSubstitutor.class, EnvsValueSubstitutor.class, Scope.SINGLETON);
builder.factory(OgnlCacheFactory.class, StrutsConstants.STRUTS_OGNL_EXPRESSIONCACHE_FACTORY, DefaultOgnlExpressionCacheFactory.class, Scope.SINGLETON);
builder.factory(OgnlCacheFactory.class, StrutsConstants.STRUTS_OGNL_BEANINFOCACHE_FACTORY, DefaultOgnlBeanInfoCacheFactory.class, Scope.SINGLETON);
builder.constant(StrutsConstants.STRUTS_DEVMODE, "false");
builder.constant(StrutsConstants.STRUTS_OGNL_LOG_MISSING_PROPERTIES, "false");
builder.constant(StrutsConstants.STRUTS_OGNL_ENABLE_EVAL_EXPRESSION, "false");
@@ -423,10 +437,10 @@ public class DefaultConfiguration implements Configuration {
private static class RuntimeConfigurationImpl implements RuntimeConfiguration {
private Map<String, Map<String, ActionConfig>> namespaceActionConfigs;
private Map<String, ActionConfigMatcher> namespaceActionConfigMatchers;
private NamespaceMatcher namespaceMatcher;
private Map<String, String> namespaceConfigs;
private final Map<String, Map<String, ActionConfig>> namespaceActionConfigs;
private final Map<String, ActionConfigMatcher> namespaceActionConfigMatchers;
private final NamespaceMatcher namespaceMatcher;
private final Map<String, String> namespaceConfigs;
public RuntimeConfigurationImpl(Map<String, Map<String, ActionConfig>> namespaceActionConfigs,
Map<String, String> namespaceConfigs,
@@ -454,6 +468,7 @@ public class DefaultConfiguration implements Configuration {
* @param namespace the namespace for the action or null for the empty namespace, ""
* @return the configuration information for action requested
*/
@Override
public ActionConfig getActionConfig(String namespace, String name) {
ActionConfig config = findActionConfigInNamespace(namespace, name);
@@ -509,6 +524,7 @@ public class DefaultConfiguration implements Configuration {
*
* @return a Map of namespace - > Map of ActionConfig objects, with the key being the action name
*/
@Override
public Map<String, Map<String, ActionConfig>> getActionConfigs() {
return namespaceActionConfigs;
}
@@ -216,6 +216,8 @@ public class StrutsDefaultConfigurationProvider implements ConfigurationProvider
.factory(TextProviderFactory.class, StrutsTextProviderFactory.class, Scope.SINGLETON)
.factory(LocaleProviderFactory.class, DefaultLocaleProviderFactory.class, Scope.SINGLETON)
.factory(OgnlCacheFactory.class, "ognlExpressionCacheFactory", DefaultOgnlExpressionCacheFactory.class, Scope.SINGLETON)
.factory(OgnlCacheFactory.class, "ognlBeanInfoCacheFactory", DefaultOgnlBeanInfoCacheFactory.class, Scope.SINGLETON)
.factory(OgnlUtil.class, Scope.SINGLETON)
.factory(CollectionConverter.class, Scope.SINGLETON)
.factory(ArrayConverter.class, Scope.SINGLETON)
@@ -232,9 +234,6 @@ public class StrutsDefaultConfigurationProvider implements ConfigurationProvider
.factory(DateFormatter.class, "simpleDateFormatter", SimpleDateFormatAdapter.class, Scope.SINGLETON)
.factory(DateFormatter.class, "dateTimeFormatter", DateTimeFormatterAdapter.class, Scope.SINGLETON)
.factory(OgnlCacheFactory.class, StrutsConstants.STRUTS_OGNL_EXPRESSIONCACHE_FACTORY, DefaultOgnlExpressionCacheFactory.class, Scope.SINGLETON)
.factory(OgnlCacheFactory.class, StrutsConstants.STRUTS_OGNL_BEANINFOCACHE_FACTORY, DefaultOgnlBeanInfoCacheFactory.class, Scope.SINGLETON)
;
props.setProperty(StrutsConstants.STRUTS_ENABLE_DYNAMIC_METHOD_INVOCATION, Boolean.FALSE.toString());
@@ -90,15 +90,19 @@ public class OgnlUtil {
/**
* Construct a new OgnlUtil instance for use with the framework, with optional
* cache factories for Ognl Expression and BeanInfo caches.
* cache factories for OGNL Expression and BeanInfo caches.
*
* @param ognlExpressionCacheFactory factory for Expression cache instance. If null, use default
* @param ognlBeanInfoCacheFactory for BeanInfo cache instance. If null, use default
* NOTE: Although the extension points are defined for the optional cache factories, developer-defined overrides do
* do not appear to function at this time (it always appears to instantiate the default factories).
* Construction injectors do not allow the optional flag, so the definitions must be defined.
*
* @param ognlExpressionCacheFactory factory for Expression cache instance. If null, it uses a default
* @param ognlBeanInfoCacheFactory factory for BeanInfo cache instance. If null, it uses a default
*/
@Inject
public OgnlUtil(
@Inject(value = StrutsConstants.STRUTS_OGNL_EXPRESSIONCACHE_FACTORY, required = false) OgnlCacheFactory<String, Object> ognlExpressionCacheFactory,
@Inject(value = StrutsConstants.STRUTS_OGNL_BEANINFOCACHE_FACTORY, required = false) OgnlCacheFactory<Class<?>, BeanInfo> ognlBeanInfoCacheFactory
@Inject(value = "ognlExpressionCacheFactory") OgnlCacheFactory<String, Object> ognlExpressionCacheFactory,
@Inject(value = "ognlBeanInfoCacheFactory") OgnlCacheFactory<Class<?>, BeanInfo> ognlBeanInfoCacheFactory
) {
excludedClasses = Collections.unmodifiableSet(new HashSet<>());
excludedPackageNamePatterns = Collections.unmodifiableSet(new HashSet<>());
@@ -107,19 +111,12 @@ public class OgnlUtil {
devModeExcludedClasses = Collections.unmodifiableSet(new HashSet<>());
devModeExcludedPackageNamePatterns = Collections.unmodifiableSet(new HashSet<>());
devModeExcludedPackageNames = Collections.unmodifiableSet(new HashSet<>());
this.ognlExpressionCacheFactory = ognlExpressionCacheFactory;
this.ognlBeanInfoCacheFactory = ognlBeanInfoCacheFactory;
if (ognlExpressionCacheFactory != null) {
this.expressionCache = ognlExpressionCacheFactory.buildOgnlCache();
} else {
this.expressionCache = new OgnlDefaultCache<>(25000, 16, 0.75f);
}
if (ognlBeanInfoCacheFactory != null) {
this.beanInfoCache = ognlBeanInfoCacheFactory.buildOgnlCache();
} else {
this.beanInfoCache = new OgnlDefaultCache<>(25000, 16, 0.75f);
}
this.ognlExpressionCacheFactory = (ognlExpressionCacheFactory != null ? ognlExpressionCacheFactory : new DefaultOgnlExpressionCacheFactory<>());
this.ognlBeanInfoCacheFactory = (ognlBeanInfoCacheFactory != null ? ognlBeanInfoCacheFactory : new DefaultOgnlBeanInfoCacheFactory<>());
this.expressionCache = this.ognlExpressionCacheFactory.buildOgnlCache();
this.beanInfoCache = this.ognlBeanInfoCacheFactory.buildOgnlCache();
}
@Inject
@@ -256,12 +256,16 @@ public final class StrutsConstants {
/**
* Specifies an OGNL expression cache factory implementation. A default implementation is provided, but
* could be replaced by a custom one if desired.
*
* @since 2.6
*/
public static final String STRUTS_OGNL_EXPRESSIONCACHE_FACTORY = "struts.ognl.expressionCacheFactory";
/**
* Specifies an OGNL BeanInfo cache factory implementation. A default implementation is provided, but
* could be replaced by a custom one if desired.
*
* @since 2.6
*/
public static final String STRUTS_OGNL_BEANINFOCACHE_FACTORY = "struts.ognl.beanInfoCacheFactory";
@@ -49,6 +49,7 @@ import com.opensymphony.xwork2.factory.ResultFactory;
import com.opensymphony.xwork2.factory.ValidatorFactory;
import com.opensymphony.xwork2.inject.ContainerBuilder;
import com.opensymphony.xwork2.inject.Scope;
import com.opensymphony.xwork2.ognl.OgnlCacheFactory;
import com.opensymphony.xwork2.security.NotExcludedAcceptedPatternsChecker;
import com.opensymphony.xwork2.util.PatternMatcher;
import com.opensymphony.xwork2.util.TextParser;
@@ -366,6 +367,7 @@ import org.apache.struts2.views.util.UrlHelper;
*/
public class StrutsBeanSelectionProvider extends AbstractBeanSelectionProvider {
@Override
public void register(ContainerBuilder builder, LocatableProperties props) {
alias(ObjectFactory.class, StrutsConstants.STRUTS_OBJECTFACTORY, builder, props);
alias(ActionFactory.class, StrutsConstants.STRUTS_OBJECTFACTORY_ACTIONFACTORY, builder, props);
@@ -423,6 +425,9 @@ public class StrutsBeanSelectionProvider extends AbstractBeanSelectionProvider {
alias(DateFormatter.class, StrutsConstants.STRUTS_DATE_FORMATTER, builder, props, Scope.SINGLETON);
alias(OgnlCacheFactory.class, StrutsConstants.STRUTS_OGNL_EXPRESSIONCACHE_FACTORY, builder, props, Scope.SINGLETON);
alias(OgnlCacheFactory.class, StrutsConstants.STRUTS_OGNL_BEANINFOCACHE_FACTORY, builder, props, Scope.SINGLETON);
switchDevMode(props);
}
@@ -144,6 +144,8 @@ public class ConstantConfig {
private Boolean disallowProxyMemberAccess;
private Integer ognlAutoGrowthCollectionLimit;
private String staticContentPath;
private BeanConfig expressionCacheFactory;
private BeanConfig beaninfoCacheFactory;
protected String beanConfToString(BeanConfig beanConf) {
return beanConf == null ? null : beanConf.getName();
@@ -274,6 +276,8 @@ public class ConstantConfig {
map.put(StrutsConstants.STRUTS_DISALLOW_PROXY_MEMBER_ACCESS, Objects.toString(disallowProxyMemberAccess, null));
map.put(StrutsConstants.STRUTS_OGNL_AUTO_GROWTH_COLLECTION_LIMIT, Objects.toString(ognlAutoGrowthCollectionLimit, null));
map.put(StrutsConstants.STRUTS_UI_STATIC_CONTENT_PATH, Objects.toString(staticContentPath, StaticContentLoader.DEFAULT_STATIC_CONTENT_PATH));
map.put(StrutsConstants.STRUTS_OGNL_EXPRESSIONCACHE_FACTORY, beanConfToString(expressionCacheFactory));
map.put(StrutsConstants.STRUTS_OGNL_BEANINFOCACHE_FACTORY, beanConfToString(beaninfoCacheFactory));
return map;
}
@@ -1341,4 +1345,28 @@ public class ConstantConfig {
public void setStaticContentPath(String staticContentPath) {
this.staticContentPath = StaticContentLoader.Validator.validateStaticContentPath(staticContentPath);
}
public BeanConfig getExpressionCacheFactory() {
return expressionCacheFactory;
}
public void setExpressionCacheFactory(BeanConfig expressionCacheFactory) {
this.expressionCacheFactory = expressionCacheFactory;
}
public void setExpressionCacheFactory(Class<?> clazz) {
this.expressionCacheFactory = new BeanConfig(clazz, clazz.getName());
}
public BeanConfig getBeaninfoCacheFactory() {
return beaninfoCacheFactory;
}
public void setBeaninfoCacheFactory(BeanConfig beaninfoCacheFactory) {
this.beaninfoCacheFactory = beaninfoCacheFactory;
}
public void setBeaninfoCacheFactory(Class<?> clazz) {
this.beaninfoCacheFactory = new BeanConfig(clazz, clazz.getName());
}
}
@@ -229,6 +229,11 @@ struts.ognl.logMissingProperties=false
### if the application generates a lot of different expressions
struts.ognl.enableExpressionCache=true
### Specify the OGNL expression cache factory and BeanInfo cache factory to use.
### Currently the default implementations are used, but can be replaced with custom ones if desired.
struts.ognl.expressionCacheFactory=ognlExpressionCacheFactory
struts.ognl.beanInfoCacheFactory=ognlBeanInfoCacheFactory
### Specify a limit to the number of entries in the OGNL expressionCache.
### For the standard expressionCache mode, when the limit is exceeded the entire cache's
### content will be cleared (can help prevent memory leaks).
+2 -2
View File
@@ -231,8 +231,8 @@
<bean type="org.apache.struts2.components.date.DateFormatter" name="simpleDateFormatter" class="org.apache.struts2.components.date.SimpleDateFormatAdapter" scope="singleton"/>
<bean type="org.apache.struts2.components.date.DateFormatter" name="dateTimeFormatter" class="org.apache.struts2.components.date.DateTimeFormatterAdapter" scope="singleton"/>
<bean type="com.opensymphony.xwork2.ognl.OgnlCacheFactory" name="struts.ognl.expressionCacheFactory" class="com.opensymphony.xwork2.ognl.DefaultOgnlExpressionCacheFactory" scope="singleton"/>
<bean type="com.opensymphony.xwork2.ognl.OgnlCacheFactory" name="struts.ognl.beanInfoCacheFactory" class="com.opensymphony.xwork2.ognl.DefaultOgnlBeanInfoCacheFactory" scope="singleton"/>
<bean type="com.opensymphony.xwork2.ognl.OgnlCacheFactory" name="ognlExpressionCacheFactory" class="com.opensymphony.xwork2.ognl.DefaultOgnlExpressionCacheFactory" scope="singleton"/>
<bean type="com.opensymphony.xwork2.ognl.OgnlCacheFactory" name="ognlBeanInfoCacheFactory" class="com.opensymphony.xwork2.ognl.DefaultOgnlBeanInfoCacheFactory" scope="singleton"/>
<package name="struts-default" abstract="true">
<result-types>