diff --git a/apps/showcase/src/main/java/org/apache/struts2/showcase/application/TestDataProvider.java b/apps/showcase/src/main/java/org/apache/struts2/showcase/application/TestDataProvider.java index 25cfa32986..ba16c9a613 100644 --- a/apps/showcase/src/main/java/org/apache/struts2/showcase/application/TestDataProvider.java +++ b/apps/showcase/src/main/java/org/apache/struts2/showcase/application/TestDataProvider.java @@ -33,8 +33,8 @@ import java.io.Serial; import java.io.Serializable; -import java.util.Arrays; import java.util.Date; +import java.util.List; /** * TestDataProvider. @@ -42,76 +42,76 @@ @Service public class TestDataProvider implements Serializable, InitializingBean { - @Serial - private static final long serialVersionUID = 1L; - private static final Logger log = LogManager.getLogger(TestDataProvider.class); + @Serial + private static final long serialVersionUID = 1L; + private static final Logger log = LogManager.getLogger(TestDataProvider.class); - public static final String[] POSITIONS = { - "Developer", - "System Architect", - "Sales Manager", - "CEO" - }; + public static final String[] POSITIONS = { + "Developer", + "System Architect", + "Sales Manager", + "CEO" + }; - public static final String[] LEVELS = { - "Junior", - "Senior", - "Master" - }; + public static final String[] LEVELS = { + "Junior", + "Senior", + "Master" + }; - private static final Skill[] TEST_SKILLS = { - new Skill("WW-SEN", "Struts Senior Developer"), - new Skill("WW-JUN", "Struts Junior Developer"), - new Skill("SPRING-DEV", "Spring Developer") - }; + private static final Skill[] TEST_SKILLS = { + new Skill("WW-SEN", "Struts Senior Developer"), + new Skill("WW-JUN", "Struts Junior Developer"), + new Skill("SPRING-DEV", "Spring Developer") + }; - public static final Employee[] TEST_EMPLOYEES = { - new Employee(1L, "Alan", "Smithee", new Date(), 2000f, true, POSITIONS[0], - TEST_SKILLS[0], null, "alan", LEVELS[0], "Nice guy"), - new Employee(2L, "Robert", "Robson", new Date(), 10000f, false, POSITIONS[1], - TEST_SKILLS[1], Arrays.asList(TEST_SKILLS).subList(1, TEST_SKILLS.length), "rob", LEVELS[1], "Smart guy") - }; + public static final Employee[] TEST_EMPLOYEES = { + new Employee(1L, "Alan", "Smithee", new Date(), 2000f, true, POSITIONS[0], + TEST_SKILLS[0], null, "alan", LEVELS[0], "Nice guy"), + new Employee(2L, "Robert", "Robson", new Date(), 10000f, false, POSITIONS[1], + TEST_SKILLS[1], List.of(TEST_SKILLS).subList(1, TEST_SKILLS.length), "rob", LEVELS[1], "Smart guy") + }; - @Autowired - private SkillDao skillDao; + @Autowired + private SkillDao skillDao; - @Autowired - private EmployeeDao employeeDao; + @Autowired + private EmployeeDao employeeDao; - protected void addTestSkills() { - try { + protected void addTestSkills() { + try { for (Skill testSkill : TEST_SKILLS) { skillDao.merge(testSkill); } - if (log.isInfoEnabled()) { - log.info("TestDataProvider - [addTestSkills]: Added test skill data."); - } - } catch (StorageException e) { + if (log.isInfoEnabled()) { + log.info("TestDataProvider - [addTestSkills]: Added test skill data."); + } + } catch (StorageException e) { log.error("TestDataProvider - [addTestSkills]: Exception caught: {}", e.getMessage()); - } - } + } + } - protected void addTestEmployees() { - try { + protected void addTestEmployees() { + try { for (Employee testEmployee : TEST_EMPLOYEES) { employeeDao.merge(testEmployee); } - if (log.isInfoEnabled()) { - log.info("TestDataProvider - [addTestEmployees]: Added test employee data."); - } - } catch (StorageException e) { + if (log.isInfoEnabled()) { + log.info("TestDataProvider - [addTestEmployees]: Added test employee data."); + } + } catch (StorageException e) { log.error("TestDataProvider - [addTestEmployees]: Exception caught: {}", e.getMessage()); - } - } + } + } - protected void addTestData() { - addTestSkills(); - addTestEmployees(); - } + protected void addTestData() { + addTestSkills(); + addTestEmployees(); + } - @Override - public void afterPropertiesSet() throws Exception { - addTestData(); - } + @Override + public void afterPropertiesSet() throws Exception { + addTestData(); + } } diff --git a/core/src/main/java/com/opensymphony/xwork2/Action.java b/core/src/main/java/com/opensymphony/xwork2/Action.java index 4c96617c49..768ca26787 100644 --- a/core/src/main/java/com/opensymphony/xwork2/Action.java +++ b/core/src/main/java/com/opensymphony/xwork2/Action.java @@ -31,21 +31,21 @@ public interface Action { * The action execution was successful. Show result * view to the end user. */ - public static final String SUCCESS = "success"; + String SUCCESS = "success"; /** * The action execution was successful but do not * show a view. This is useful for actions that are * handling the view in another fashion like redirect. */ - public static final String NONE = "none"; + String NONE = "none"; /** * The action execution was a failure. * Show an error view, possibly asking the * user to retry entering data. */ - public static final String ERROR = "error"; + String ERROR = "error"; /** *

@@ -64,14 +64,14 @@ public interface Action { * should try providing input again. *

*/ - public static final String INPUT = "input"; + String INPUT = "input"; /** * The action could not execute, since the * user most was not logged in. The login view * should be shown. */ - public static final String LOGIN = "login"; + String LOGIN = "login"; /** @@ -83,6 +83,6 @@ public interface Action { * Note: Application level exceptions should be handled by returning * an error value, such as Action.ERROR. */ - public String execute() throws Exception; + String execute() throws Exception; } diff --git a/core/src/main/java/com/opensymphony/xwork2/ActionChainResult.java b/core/src/main/java/com/opensymphony/xwork2/ActionChainResult.java index 4f7233046e..6b6c2813e8 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ActionChainResult.java +++ b/core/src/main/java/com/opensymphony/xwork2/ActionChainResult.java @@ -24,7 +24,6 @@ import org.apache.logging.log4j.Logger; import org.apache.struts2.StrutsException; -import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; @@ -259,7 +258,7 @@ public int hashCode() { private boolean isInChainHistory(String namespace, String actionName, String methodName) { LinkedList chainHistory = ActionChainResult.getChainHistory(); Set skipActionsList = new HashSet<>(); - if (skipActions != null && skipActions.length() > 0) { + if (skipActions != null && !skipActions.isEmpty()) { String finalSkipActions = translateVariables(skipActions); skipActionsList.addAll(TextParseUtil.commaDelimitedStringToSet(finalSkipActions)); } diff --git a/core/src/main/java/com/opensymphony/xwork2/ActionEventListener.java b/core/src/main/java/com/opensymphony/xwork2/ActionEventListener.java index 00690a7f44..d125a683b6 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ActionEventListener.java +++ b/core/src/main/java/com/opensymphony/xwork2/ActionEventListener.java @@ -25,20 +25,20 @@ */ public interface ActionEventListener { /** - * Called after an action has been created. - * + * Called after an action has been created. + * * @param action The action * @param stack The current value stack * @return The action to use */ - public Object prepare(Object action, ValueStack stack); - + Object prepare(Object action, ValueStack stack); + /** * Called when an exception is thrown by the action - * + * * @param t The exception/error that was thrown * @param stack The current value stack * @return A result code to execute, can be null */ - public String handleException(Throwable t, ValueStack stack); + String handleException(Throwable t, ValueStack stack); } diff --git a/core/src/main/java/com/opensymphony/xwork2/CompositeTextProvider.java b/core/src/main/java/com/opensymphony/xwork2/CompositeTextProvider.java index f1eb68d99f..4ab017c111 100644 --- a/core/src/main/java/com/opensymphony/xwork2/CompositeTextProvider.java +++ b/core/src/main/java/com/opensymphony/xwork2/CompositeTextProvider.java @@ -22,7 +22,11 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.ResourceBundle; /** * This is a composite {@link TextProvider} that takes in an array or {@link java.util.List} of {@link TextProvider}s, it will @@ -35,7 +39,7 @@ public class CompositeTextProvider implements TextProvider { private static final Logger LOG = LogManager.getLogger(CompositeTextProvider.class); - private List textProviders = new ArrayList<>(); + private final List textProviders = new ArrayList<>(); /** * Instantiates a {@link CompositeTextProvider} with some predefined textProviders. @@ -64,6 +68,7 @@ public CompositeTextProvider(TextProvider[] textProviders) { * @see com.opensymphony.xwork2.TextProvider#hasKey(String) * */ + @Override public boolean hasKey(String key) { // if there's a key in either text providers we are ok, else try the next text provider for (TextProvider tp : textProviders) { @@ -82,6 +87,7 @@ public boolean hasKey(String key) { * @return The i18n text for the requested key. * @see com.opensymphony.xwork2.TextProvider#getText(String) */ + @Override public String getText(String key) { return getText(key, key, Collections.emptyList()); } @@ -95,6 +101,7 @@ public String getText(String key) { * @return the first valid message for the key or default value * @see com.opensymphony.xwork2.TextProvider#getText(String, String) */ + @Override public String getText(String key, String defaultValue) { return getText(key, defaultValue, Collections.emptyList()); } @@ -110,12 +117,9 @@ public String getText(String key, String defaultValue) { * @return the first valid message for the key or default value * @see com.opensymphony.xwork2.TextProvider#getText(String, String, String) */ + @Override public String getText(String key, String defaultValue, final String obj) { - return getText(key, defaultValue, new ArrayList() { - { - add(obj); - } - }); + return getText(key, defaultValue, List.of(obj)); } /** @@ -127,6 +131,7 @@ public String getText(String key, String defaultValue, final String obj) { * @return the first valid message for the key * @see com.opensymphony.xwork2.TextProvider#getText(String, java.util.List) */ + @Override public String getText(String key, List args) { return getText(key, key, args); } @@ -140,6 +145,7 @@ public String getText(String key, List args) { * @return the first valid message for the key or default value * @see com.opensymphony.xwork2.TextProvider#getText(String, String[]) */ + @Override public String getText(String key, String[] args) { return getText(key, key, args); } @@ -155,6 +161,7 @@ public String getText(String key, String[] args) { * @return the first valid message for the key or default value * @see com.opensymphony.xwork2.TextProvider#getText(String, String, java.util.List) */ + @Override public String getText(String key, String defaultValue, List args) { // if there's one text provider that gives us a msg not the same as defaultValue // for this key, we are ok, else try the next @@ -179,6 +186,7 @@ public String getText(String key, String defaultValue, List args) { * @return the first valid message for the key or default value * @see com.opensymphony.xwork2.TextProvider#getText(String, String, String[]) */ + @Override public String getText(String key, String defaultValue, String[] args) { // if there's one text provider that gives us a msg not the same as defaultValue // for this key, we are ok, else try the next @@ -204,6 +212,7 @@ public String getText(String key, String defaultValue, String[] args) { * @return the first valid message for the key or default value * @see com.opensymphony.xwork2.TextProvider#getText(String, String, java.util.List, com.opensymphony.xwork2.util.ValueStack) */ + @Override public String getText(String key, String defaultValue, List args, ValueStack stack) { // if there's one text provider that gives us a msg not the same as defaultValue // for this key, we are ok, else try the next @@ -228,6 +237,7 @@ public String getText(String key, String defaultValue, List args, ValueStack * @return the first valid message for the key or default value * @see com.opensymphony.xwork2.TextProvider#getText(String, String, String[], com.opensymphony.xwork2.util.ValueStack) */ + @Override public String getText(String key, String defaultValue, String[] args, ValueStack stack) { // if there's one text provider that gives us a msg not the same as defaultValue // for this key, we are ok, else try the next @@ -249,6 +259,7 @@ public String getText(String key, String defaultValue, String[] args, ValueStack * @return the resource bundle found for bundle name * @see TextProvider#getTexts(String) */ + @Override public ResourceBundle getTexts(String bundleName) { // if there's one text provider that gives us a non-null resource bundle for this bundleName, we are ok, else try the next // text provider @@ -267,6 +278,7 @@ public ResourceBundle getTexts(String bundleName) { * @return the resource bundle * @see TextProvider#getTexts() */ + @Override public ResourceBundle getTexts() { // if there's one text provider that gives us a non-null resource bundle, we are ok, else try the next // text provider diff --git a/core/src/main/java/com/opensymphony/xwork2/DefaultActionInvocation.java b/core/src/main/java/com/opensymphony/xwork2/DefaultActionInvocation.java index 772e0adb07..fe32bde351 100644 --- a/core/src/main/java/com/opensymphony/xwork2/DefaultActionInvocation.java +++ b/core/src/main/java/com/opensymphony/xwork2/DefaultActionInvocation.java @@ -103,6 +103,7 @@ public void setContainer(Container cont) { } @Inject(required = false) + @Override public void setActionEventListener(ActionEventListener listener) { this.actionEventListener = listener; } @@ -117,18 +118,22 @@ public void setAsyncManager(AsyncManager asyncManager) { this.asyncManager = asyncManager; } + @Override public Object getAction() { return action; } + @Override public boolean isExecuted() { return executed; } + @Override public ActionContext getInvocationContext() { return invocationContext; } + @Override public ActionProxy getProxy() { return proxy; } @@ -142,6 +147,7 @@ public ActionProxy getProxy() { * @return a Result instance * @throws Exception in case of any error */ + @Override public Result getResult() throws Exception { Result returnResult = result; @@ -165,10 +171,12 @@ public Result getResult() throws Exception { return returnResult; } + @Override public String getResultCode() { return resultCode; } + @Override public void setResultCode(String resultCode) { if (isExecuted()) { throw new IllegalStateException("Result has already been executed."); @@ -176,7 +184,7 @@ public void setResultCode(String resultCode) { this.resultCode = resultCode; } - + @Override public ValueStack getStack() { return stack; } @@ -188,6 +196,7 @@ public ValueStack getStack() { * * @param listener to register */ + @Override public void addPreResultListener(PreResultListener listener) { if (preResultListeners == null) { preResultListeners = new ArrayList<>(1); @@ -237,6 +246,7 @@ public Result createResult() throws Exception { /** * @throws ConfigurationException If no result can be found with the returned code */ + @Override public String invoke() throws Exception { if (executed) { throw new IllegalStateException("Action has already executed"); @@ -303,6 +313,7 @@ protected String executeConditional(ConditionalInterceptor conditionalIntercepto } } + @Override public String invokeActionOnly() throws Exception { return invokeAction(getAction(), proxy.getConfig()); } @@ -348,15 +359,14 @@ protected Map createContextMap() { throw new IllegalStateException("There was a null Stack set into the extra params."); } - actionContext = stack.getActionContext(); } else { // create the value stack // this also adds the ValueStack to its context stack = valueStackFactory.createValueStack(); // create the action context - actionContext = stack.getActionContext(); } + actionContext = stack.getActionContext(); return actionContext .withExtraContext(extraContext) @@ -385,6 +395,7 @@ private void executeResult() throws Exception { } } + @Override public void init(ActionProxy proxy) { this.proxy = proxy; Map contextMap = createContextMap(); @@ -457,7 +468,7 @@ protected String invokeAction(Object action, ActionConfig actionConfig) throws E } return saveResult(actionConfig, methodResult); } catch (NoSuchPropertyException e) { - throw new IllegalArgumentException("The " + methodName + "() is not defined in action " + getAction().getClass() + ""); + throw new IllegalArgumentException("The " + methodName + "() is not defined in action " + getAction().getClass()); } catch (MethodFailedException e) { // We try to return the source exception. Throwable t = e.getCause(); diff --git a/core/src/main/java/com/opensymphony/xwork2/DefaultActionProxy.java b/core/src/main/java/com/opensymphony/xwork2/DefaultActionProxy.java index 4d73813eeb..da8a9dbca6 100644 --- a/core/src/main/java/com/opensymphony/xwork2/DefaultActionProxy.java +++ b/core/src/main/java/com/opensymphony/xwork2/DefaultActionProxy.java @@ -22,11 +22,12 @@ import com.opensymphony.xwork2.config.ConfigurationException; import com.opensymphony.xwork2.config.entities.ActionConfig; import com.opensymphony.xwork2.inject.Inject; -import org.apache.commons.text.StringEscapeUtils; 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 java.io.Serial; import java.io.Serializable; import java.util.Locale; @@ -40,6 +41,7 @@ */ public class DefaultActionProxy implements ActionProxy, Serializable { + @Serial private static final long serialVersionUID = 3293074152487468527L; private static final Logger LOG = LogManager.getLogger(DefaultActionProxy.class); @@ -201,7 +203,7 @@ protected String prepareNotAllowedErrorMessage() { } protected String getErrorMessage() { - if ((namespace != null) && (namespace.trim().length() > 0)) { + if (namespace != null && !namespace.trim().isEmpty()) { return localizedTextProvider.findDefaultText( "xwork.exception.missing-package-action", Locale.getDefault(), diff --git a/core/src/main/java/com/opensymphony/xwork2/DefaultActionProxyFactory.java b/core/src/main/java/com/opensymphony/xwork2/DefaultActionProxyFactory.java index ea7f1dc590..988c5099b3 100644 --- a/core/src/main/java/com/opensymphony/xwork2/DefaultActionProxyFactory.java +++ b/core/src/main/java/com/opensymphony/xwork2/DefaultActionProxyFactory.java @@ -31,16 +31,16 @@ public class DefaultActionProxyFactory implements ActionProxyFactory { protected Container container; - + public DefaultActionProxyFactory() { super(); } - + @Inject public void setContainer(Container container) { this.container = container; } - + public ActionProxy createActionProxy(String namespace, String actionName, Map extraContext) { return createActionProxy(namespace, actionName, null, extraContext, true, true); } @@ -53,22 +53,24 @@ public ActionProxy createActionProxy(String namespace, String actionName, Map extraContext, boolean executeResult, boolean cleanupContext) { - + ActionInvocation inv = createActionInvocation(extraContext, true); container.inject(inv); return createActionProxy(inv, namespace, actionName, methodName, executeResult, cleanupContext); } - + protected ActionInvocation createActionInvocation(Map extraContext, boolean pushAction) { return new DefaultActionInvocation(extraContext, pushAction); } - + public ActionProxy createActionProxy(ActionInvocation inv, String namespace, String actionName, boolean executeResult, boolean cleanupContext) { - + return createActionProxy(inv, namespace, actionName, null, executeResult, cleanupContext); } + @Override public ActionProxy createActionProxy(ActionInvocation inv, String namespace, String actionName, String methodName, boolean executeResult, boolean cleanupContext) { DefaultActionProxy proxy = new DefaultActionProxy(inv, namespace, actionName, methodName, executeResult, cleanupContext); diff --git a/core/src/main/java/com/opensymphony/xwork2/DefaultTextProvider.java b/core/src/main/java/com/opensymphony/xwork2/DefaultTextProvider.java index a4b514c7d9..6d7315a650 100644 --- a/core/src/main/java/com/opensymphony/xwork2/DefaultTextProvider.java +++ b/core/src/main/java/com/opensymphony/xwork2/DefaultTextProvider.java @@ -28,6 +28,8 @@ import java.util.List; import java.util.ResourceBundle; +import static java.util.Objects.requireNonNullElse; + /** * DefaultTextProvider gets texts from only the default resource bundles associated with the default bundles. */ @@ -45,14 +47,17 @@ public void setLocalizedTextProvider(LocalizedTextProvider localizedTextProvider this.localizedTextProvider = localizedTextProvider; } + @Override public boolean hasKey(String key) { return getText(key) != null; } + @Override public String getText(String key) { return localizedTextProvider.findDefaultText(key, ActionContext.getContext().getLocale()); } + @Override public String getText(String key, String defaultValue) { String text = getText(key); if (text == null) { @@ -61,6 +66,7 @@ public String getText(String key, String defaultValue) { return text; } + @Override public String getText(String key, List args) { Object[] params; if (args != null) { @@ -72,17 +78,15 @@ public String getText(String key, List args) { return localizedTextProvider.findDefaultText(key, ActionContext.getContext().getLocale(), params); } + @Override public String getText(String key, String[] args) { Object[] params; - if (args != null) { - params = args; - } else { - params = EMPTY_ARGS; - } + params = requireNonNullElse(args, EMPTY_ARGS); return localizedTextProvider.findDefaultText(key, ActionContext.getContext().getLocale(), params); } + @Override public String getText(String key, String defaultValue, List args) { String text = getText(key, args); if(text == null && defaultValue == null) { @@ -106,6 +110,7 @@ public String getText(String key, String defaultValue, List args) { return text; } + @Override public String getText(String key, String defaultValue, String[] args) { String text = getText(key, args); if (text == null) { @@ -113,37 +118,38 @@ public String getText(String key, String defaultValue, String[] args) { format.setLocale(ActionContext.getContext().getLocale()); format.applyPattern(defaultValue); - if (args == null) { - return format.format(EMPTY_ARGS); - } + return format.format(requireNonNullElse(args, EMPTY_ARGS)); - return format.format(args); } return text; } - + @Override public String getText(String key, String defaultValue, String obj) { List args = new ArrayList<>(1); args.add(obj); return getText(key, defaultValue, args); } + @Override public String getText(String key, String defaultValue, List args, ValueStack stack) { //we're not using the value stack here return getText(key, defaultValue, args); } + @Override public String getText(String key, String defaultValue, String[] args, ValueStack stack) { //we're not using the value stack here List values = new ArrayList<>(Arrays.asList(args)); return getText(key, defaultValue, values); } + @Override public ResourceBundle getTexts(String bundleName) { return localizedTextProvider.findResourceBundle(bundleName, ActionContext.getContext().getLocale()); } + @Override public ResourceBundle getTexts() { return null; } diff --git a/core/src/main/java/com/opensymphony/xwork2/DefaultUnknownHandlerManager.java b/core/src/main/java/com/opensymphony/xwork2/DefaultUnknownHandlerManager.java index f538dd9877..42f4a17cb2 100644 --- a/core/src/main/java/com/opensymphony/xwork2/DefaultUnknownHandlerManager.java +++ b/core/src/main/java/com/opensymphony/xwork2/DefaultUnknownHandlerManager.java @@ -68,7 +68,7 @@ protected void build() throws Exception { if (unkownHandlerStack != null && !unkownHandlerStack.isEmpty()) { //get UnknownHandlers in the specified order for (UnknownHandlerConfig unknownHandlerConfig : unkownHandlerStack) { - UnknownHandler uh = factory.buildUnknownHandler(unknownHandlerConfig.getName(), new HashMap()); + UnknownHandler uh = factory.buildUnknownHandler(unknownHandlerConfig.getName(), new HashMap<>()); unknownHandlers.add(uh); } } else { diff --git a/core/src/main/java/com/opensymphony/xwork2/StrutsTextProviderFactory.java b/core/src/main/java/com/opensymphony/xwork2/StrutsTextProviderFactory.java index a2d2fa3a99..5961d01e38 100644 --- a/core/src/main/java/com/opensymphony/xwork2/StrutsTextProviderFactory.java +++ b/core/src/main/java/com/opensymphony/xwork2/StrutsTextProviderFactory.java @@ -22,6 +22,8 @@ import java.util.ResourceBundle; +import static java.util.Objects.requireNonNullElseGet; + /** * This factory enables users to provide and correctly initialize a custom TextProvider. */ @@ -67,19 +69,19 @@ public TextProvider createInstance(ResourceBundle bundle) { } protected TextProvider getTextProvider(Class clazz) { - if (defaultTextProvider != null) { - return defaultTextProvider; - } + return requireNonNullElseGet(defaultTextProvider, + () -> new TextProviderSupport(clazz, + localeProviderFactory.createLocaleProvider(), + localizedTextProvider)); - return new TextProviderSupport(clazz, localeProviderFactory.createLocaleProvider(), localizedTextProvider); } protected TextProvider getTextProvider(ResourceBundle bundle) { - if (defaultTextProvider != null) { - return defaultTextProvider; - } + return requireNonNullElseGet(defaultTextProvider, + () -> new TextProviderSupport(bundle, + localeProviderFactory.createLocaleProvider(), + localizedTextProvider)); - return new TextProviderSupport(bundle, localeProviderFactory.createLocaleProvider(), localizedTextProvider); } } diff --git a/core/src/main/java/com/opensymphony/xwork2/XWorkTestCase.java b/core/src/main/java/com/opensymphony/xwork2/XWorkTestCase.java index 8a4695e576..56056703ef 100644 --- a/core/src/main/java/com/opensymphony/xwork2/XWorkTestCase.java +++ b/core/src/main/java/com/opensymphony/xwork2/XWorkTestCase.java @@ -98,7 +98,8 @@ public void register(ContainerBuilder builder, LocatableProperties props) throws if (impl instanceof String || ClassUtils.isPrimitiveOrWrapper(impl.getClass())) { props.setProperty(name, "" + impl); } else { - builder.factory(type, name, new Factory() { + builder.factory(type, name, new Factory<>() { + @Override public T create(Context context) throws Exception { return impl; } diff --git a/core/src/main/java/com/opensymphony/xwork2/config/FileManagerFactoryProvider.java b/core/src/main/java/com/opensymphony/xwork2/config/FileManagerFactoryProvider.java index 42ef09b47b..d572b4c7a8 100644 --- a/core/src/main/java/com/opensymphony/xwork2/config/FileManagerFactoryProvider.java +++ b/core/src/main/java/com/opensymphony/xwork2/config/FileManagerFactoryProvider.java @@ -28,22 +28,26 @@ */ public class FileManagerFactoryProvider implements ContainerProvider { - private Class factoryClass; + private final Class factoryClass; public FileManagerFactoryProvider(Class factoryClass) { this.factoryClass = factoryClass; } + @Override public void destroy() { } + @Override public void init(Configuration configuration) throws ConfigurationException { } + @Override public boolean needsReload() { return false; } + @Override public void register(ContainerBuilder builder, LocatableProperties props) throws ConfigurationException { builder.factory(FileManagerFactory.class, factoryClass.getSimpleName(), factoryClass, Scope.SINGLETON); } diff --git a/core/src/main/java/com/opensymphony/xwork2/config/FileManagerProvider.java b/core/src/main/java/com/opensymphony/xwork2/config/FileManagerProvider.java index 09c786f4ae..632882b942 100644 --- a/core/src/main/java/com/opensymphony/xwork2/config/FileManagerProvider.java +++ b/core/src/main/java/com/opensymphony/xwork2/config/FileManagerProvider.java @@ -28,24 +28,28 @@ */ public class FileManagerProvider implements ContainerProvider { - private Class fileManagerClass; - private String name; + private final Class fileManagerClass; + private final String name; public FileManagerProvider(Class fileManagerClass, String name) { this.fileManagerClass = fileManagerClass; this.name = name; } + @Override public void destroy() { } + @Override public void init(Configuration configuration) throws ConfigurationException { } + @Override public boolean needsReload() { return false; } + @Override public void register(ContainerBuilder builder, LocatableProperties props) throws ConfigurationException { builder.factory(FileManager.class, name, fileManagerClass, Scope.SINGLETON); } diff --git a/core/src/main/java/com/opensymphony/xwork2/config/entities/ActionConfig.java b/core/src/main/java/com/opensymphony/xwork2/config/entities/ActionConfig.java index 069bae1862..f259400d54 100644 --- a/core/src/main/java/com/opensymphony/xwork2/config/entities/ActionConfig.java +++ b/core/src/main/java/com/opensymphony/xwork2/config/entities/ActionConfig.java @@ -23,7 +23,15 @@ import org.apache.commons.lang3.StringUtils; import java.io.Serializable; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; /** @@ -85,6 +93,7 @@ protected ActionConfig(ActionConfig orig) { this.exceptionMappings = new ArrayList<>(orig.exceptionMappings); this.allowedMethods = orig.allowedMethods; this.location = orig.location; + this.strictMethodInvocation = orig.strictMethodInvocation; } public String getName() { @@ -139,50 +148,49 @@ public boolean isStrictMethodInvocation() { return strictMethodInvocation; } - @Override public boolean equals(Object o) { + @Override + public boolean equals(Object o) { if (this == o) { return true; } - if (!(o instanceof ActionConfig)) { + if (!(o instanceof ActionConfig actionConfig)) { return false; } - final ActionConfig actionConfig = (ActionConfig) o; - - if ((className != null) ? (!className.equals(actionConfig.className)) : (actionConfig.className != null)) { + if (!Objects.equals(className, actionConfig.className)) { return false; } - if ((name != null) ? (!name.equals(actionConfig.name)) : (actionConfig.name != null)) { + if (!Objects.equals(name, actionConfig.name)) { return false; } - if ((interceptors != null) ? (!interceptors.equals(actionConfig.interceptors)) : (actionConfig.interceptors != null)) - { + if (!Objects.equals(interceptors, actionConfig.interceptors)) { return false; } - if ((methodName != null) ? (!methodName.equals(actionConfig.methodName)) : (actionConfig.methodName != null)) { + if (!Objects.equals(methodName, actionConfig.methodName)) { return false; } - if ((params != null) ? (!params.equals(actionConfig.params)) : (actionConfig.params != null)) { + if (!Objects.equals(params, actionConfig.params)) { return false; } - if ((results != null) ? (!results.equals(actionConfig.results)) : (actionConfig.results != null)) { + if (!Objects.equals(results, actionConfig.results)) { return false; } - if ((allowedMethods != null) ? (!allowedMethods.equals(actionConfig.allowedMethods)) : (actionConfig.allowedMethods != null)) { + if (!Objects.equals(allowedMethods, actionConfig.allowedMethods)) { return false; } return true; } - @Override public int hashCode() { + @Override + public int hashCode() { int result; result = (interceptors != null ? interceptors.hashCode() : 0); result = 31 * result + (params != null ? params.hashCode() : 0); @@ -196,7 +204,8 @@ public boolean isStrictMethodInvocation() { return result; } - @Override public String toString() { + @Override + public String toString() { StringBuilder sb = new StringBuilder(); sb.append("{ActionConfig "); sb.append(name).append(" ("); @@ -276,11 +285,13 @@ public Builder exceptionMappings(Collection ma return this; } + @Override public Builder addInterceptor(InterceptorMapping interceptor) { target.interceptors.add(interceptor); return this; } + @Override public Builder addInterceptors(List interceptors) { target.interceptors.addAll(interceptors); return this; diff --git a/core/src/main/java/com/opensymphony/xwork2/config/entities/AllowedMethods.java b/core/src/main/java/com/opensymphony/xwork2/config/entities/AllowedMethods.java index fa645883e0..1967dd7db8 100644 --- a/core/src/main/java/com/opensymphony/xwork2/config/entities/AllowedMethods.java +++ b/core/src/main/java/com/opensymphony/xwork2/config/entities/AllowedMethods.java @@ -30,9 +30,9 @@ public class AllowedMethods { private static final Logger LOG = LogManager.getLogger(AllowedMethods.class); - private Set allowedMethods; + private final Set allowedMethods; private final boolean strictMethodInvocation; - private String defaultRegex; + private final String defaultRegex; public static AllowedMethods build(boolean strictMethodInvocation, Set methods, String defaultRegex) { @@ -133,7 +133,7 @@ public String toString() { private static class PatternAllowedMethod implements AllowedMethod { private final Pattern allowedMethodPattern; - private String original; + private final String original; public PatternAllowedMethod(String pattern, String original) { this.original = original; @@ -177,7 +177,7 @@ public String toString() { private static class LiteralAllowedMethod implements AllowedMethod { - private String allowedMethod; + private final String allowedMethod; public LiteralAllowedMethod(String allowedMethod) { this.allowedMethod = allowedMethod; diff --git a/core/src/main/java/com/opensymphony/xwork2/config/entities/ExceptionMappingConfig.java b/core/src/main/java/com/opensymphony/xwork2/config/entities/ExceptionMappingConfig.java index d2a6e735a6..0b43670066 100644 --- a/core/src/main/java/com/opensymphony/xwork2/config/entities/ExceptionMappingConfig.java +++ b/core/src/main/java/com/opensymphony/xwork2/config/entities/ExceptionMappingConfig.java @@ -25,6 +25,7 @@ import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; +import java.util.Objects; /** * Configuration for exception mapping. @@ -76,28 +77,23 @@ public boolean equals(Object o) { return true; } - if (!(o instanceof ExceptionMappingConfig)) { + if (!(o instanceof ExceptionMappingConfig exceptionMappingConfig)) { return false; } - final ExceptionMappingConfig exceptionMappingConfig = (ExceptionMappingConfig) o; - - if ((name != null) ? (!name.equals(exceptionMappingConfig.name)) : (exceptionMappingConfig.name != null)) { + if (!Objects.equals(name, exceptionMappingConfig.name)) { return false; } - if ((exceptionClassName != null) ? (!exceptionClassName.equals(exceptionMappingConfig.exceptionClassName)) : (exceptionMappingConfig.exceptionClassName != null)) - { + if (!Objects.equals(exceptionClassName, exceptionMappingConfig.exceptionClassName)) { return false; } - if ((result != null) ? (!result.equals(exceptionMappingConfig.result)) : (exceptionMappingConfig.result != null)) - { + if (!Objects.equals(result, exceptionMappingConfig.result)) { return false; } - if ((params != null) ? (!params.equals(exceptionMappingConfig.params)) : (exceptionMappingConfig.params != null)) - { + if (!Objects.equals(params, exceptionMappingConfig.params)) { return false; } diff --git a/core/src/main/java/com/opensymphony/xwork2/config/entities/InterceptorConfig.java b/core/src/main/java/com/opensymphony/xwork2/config/entities/InterceptorConfig.java index 10b7691d08..69974a1340 100644 --- a/core/src/main/java/com/opensymphony/xwork2/config/entities/InterceptorConfig.java +++ b/core/src/main/java/com/opensymphony/xwork2/config/entities/InterceptorConfig.java @@ -25,6 +25,7 @@ import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; +import java.util.Objects; /** * Configuration for Interceptors. @@ -72,21 +73,19 @@ public boolean equals(Object o) { return true; } - if (!(o instanceof InterceptorConfig)) { + if (!(o instanceof InterceptorConfig interceptorConfig)) { return false; } - final InterceptorConfig interceptorConfig = (InterceptorConfig) o; - - if ((className != null) ? (!className.equals(interceptorConfig.className)) : (interceptorConfig.className != null)) { + if (!Objects.equals(className, interceptorConfig.className)) { return false; } - if ((name != null) ? (!name.equals(interceptorConfig.name)) : (interceptorConfig.name != null)) { + if (!Objects.equals(name, interceptorConfig.name)) { return false; } - if ((params != null) ? (!params.equals(interceptorConfig.params)) : (interceptorConfig.params != null)) { + if (!Objects.equals(params, interceptorConfig.params)) { return false; } @@ -114,7 +113,7 @@ public String toString() { * After setting any values you need, call the {@link #build()} method to create the object. */ public static final class Builder { - protected InterceptorConfig target; + private InterceptorConfig target; public Builder(String name, String className) { target = new InterceptorConfig(name, className); @@ -156,7 +155,7 @@ public InterceptorConfig build() { return result; } - protected void embalmTarget() { + private void embalmTarget() { target.params = Collections.unmodifiableMap(target.params); } } diff --git a/core/src/main/java/com/opensymphony/xwork2/config/entities/InterceptorMapping.java b/core/src/main/java/com/opensymphony/xwork2/config/entities/InterceptorMapping.java index 260ae325b1..e90cd10147 100644 --- a/core/src/main/java/com/opensymphony/xwork2/config/entities/InterceptorMapping.java +++ b/core/src/main/java/com/opensymphony/xwork2/config/entities/InterceptorMapping.java @@ -23,6 +23,7 @@ import java.io.Serializable; import java.util.HashMap; import java.util.Map; +import java.util.Objects; /** * InterceptorMapping @@ -32,8 +33,8 @@ */ public class InterceptorMapping implements Serializable { - private String name; - private Interceptor interceptor; + private final String name; + private final Interceptor interceptor; private final Map params; public InterceptorMapping(String name, Interceptor interceptor) { @@ -65,9 +66,7 @@ public boolean equals(Object o) { final InterceptorMapping that = (InterceptorMapping) o; - if (name != null ? !name.equals(that.name) : that.name != null) return false; - - return true; + return Objects.equals(name, that.name); } @Override diff --git a/core/src/main/java/com/opensymphony/xwork2/config/entities/InterceptorStackConfig.java b/core/src/main/java/com/opensymphony/xwork2/config/entities/InterceptorStackConfig.java index f5445de647..bcd9a3da0d 100644 --- a/core/src/main/java/com/opensymphony/xwork2/config/entities/InterceptorStackConfig.java +++ b/core/src/main/java/com/opensymphony/xwork2/config/entities/InterceptorStackConfig.java @@ -21,11 +21,13 @@ import com.opensymphony.xwork2.util.location.Located; import com.opensymphony.xwork2.util.location.Location; +import java.io.Serial; import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Objects; /** @@ -40,6 +42,7 @@ */ public class InterceptorStackConfig extends Located implements Serializable { + @Serial private static final long serialVersionUID = 2897260918170270343L; /** @@ -102,17 +105,15 @@ public boolean equals(Object o) { return true; } - if (!(o instanceof InterceptorStackConfig)) { + if (!(o instanceof InterceptorStackConfig interceptorStackConfig)) { return false; } - final InterceptorStackConfig interceptorStackConfig = (InterceptorStackConfig) o; - - if ((interceptors != null) ? (!interceptors.equals(interceptorStackConfig.interceptors)) : (interceptorStackConfig.interceptors != null)) { + if (!Objects.equals(interceptors, interceptorStackConfig.interceptors)) { return false; } - if ((name != null) ? (!name.equals(interceptorStackConfig.name)) : (interceptorStackConfig.name != null)) { + if (!Objects.equals(name, interceptorStackConfig.name)) { return false; } @@ -162,6 +163,7 @@ public Builder name(String name) { * * @return this builder */ + @Override public Builder addInterceptor(InterceptorMapping interceptor) { target.interceptors.add(interceptor); return this; @@ -174,6 +176,7 @@ public Builder addInterceptor(InterceptorMapping interceptor) { * * @return this builder */ + @Override public Builder addInterceptors(List interceptors) { target.interceptors.addAll(interceptors); return this; diff --git a/core/src/main/java/com/opensymphony/xwork2/config/entities/PackageConfig.java b/core/src/main/java/com/opensymphony/xwork2/config/entities/PackageConfig.java index eafff831da..753cc64ff5 100644 --- a/core/src/main/java/com/opensymphony/xwork2/config/entities/PackageConfig.java +++ b/core/src/main/java/com/opensymphony/xwork2/config/entities/PackageConfig.java @@ -22,7 +22,15 @@ import com.opensymphony.xwork2.util.location.Location; import java.io.Serializable; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; /** * Configuration for Package. @@ -369,30 +377,29 @@ public boolean equals(Object o) { if (isFinal != that.isFinal) return false; if (needsRefresh != that.needsRefresh) return false; if (strictMethodInvocation != that.strictMethodInvocation) return false; - if (actionConfigs != null ? !actionConfigs.equals(that.actionConfigs) : that.actionConfigs != null) + if (!Objects.equals(actionConfigs, that.actionConfigs)) return false; - if (globalResultConfigs != null ? !globalResultConfigs.equals(that.globalResultConfigs) : that.globalResultConfigs != null) + if (!Objects.equals(globalResultConfigs, that.globalResultConfigs)) return false; - if (globalAllowedMethods != null ? !globalAllowedMethods.equals(that.globalAllowedMethods) : that.globalAllowedMethods != null) + if (!Objects.equals(globalAllowedMethods, that.globalAllowedMethods)) return false; - if (interceptorConfigs != null ? !interceptorConfigs.equals(that.interceptorConfigs) : that.interceptorConfigs != null) + if (!Objects.equals(interceptorConfigs, that.interceptorConfigs)) return false; - if (resultTypeConfigs != null ? !resultTypeConfigs.equals(that.resultTypeConfigs) : that.resultTypeConfigs != null) + if (!Objects.equals(resultTypeConfigs, that.resultTypeConfigs)) return false; - if (globalExceptionMappingConfigs != null ? !globalExceptionMappingConfigs.equals(that.globalExceptionMappingConfigs) : that.globalExceptionMappingConfigs != null) + if (!Objects.equals(globalExceptionMappingConfigs, that.globalExceptionMappingConfigs)) return false; - if (parents != null ? !parents.equals(that.parents) : that.parents != null) return false; - if (defaultInterceptorRef != null ? !defaultInterceptorRef.equals(that.defaultInterceptorRef) : that.defaultInterceptorRef != null) + if (!Objects.equals(parents, that.parents)) return false; + if (!Objects.equals(defaultInterceptorRef, that.defaultInterceptorRef)) return false; - if (defaultActionRef != null ? !defaultActionRef.equals(that.defaultActionRef) : that.defaultActionRef != null) + if (!Objects.equals(defaultActionRef, that.defaultActionRef)) return false; - if (defaultResultType != null ? !defaultResultType.equals(that.defaultResultType) : that.defaultResultType != null) + if (!Objects.equals(defaultResultType, that.defaultResultType)) return false; - if (defaultClassRef != null ? !defaultClassRef.equals(that.defaultClassRef) : that.defaultClassRef != null) + if (!Objects.equals(defaultClassRef, that.defaultClassRef)) return false; if (!name.equals(that.name)) return false; - return !(namespace != null ? !namespace.equals(that.namespace) : that.namespace != null); - + return Objects.equals(namespace, that.namespace); } @Override @@ -422,6 +429,7 @@ public String toString() { return "PackageConfig: [" + name + "] for namespace [" + namespace + "] with parents [" + parents + "]"; } + @Override public int compareTo(PackageConfig other) { String full = namespace + "!" + name; String otherFull = other.namespace + "!" + other.name; @@ -430,6 +438,7 @@ public int compareTo(PackageConfig other) { return full.compareTo(otherFull); } + @Override public Object getInterceptorConfig(String name) { return getAllInterceptorConfigs().get(name); } @@ -494,11 +503,7 @@ public Builder defaultResultType(String defaultResultType) { } public Builder namespace(String namespace) { - if (namespace == null) { - target.namespace = ""; - } else { - target.namespace = namespace; - } + target.namespace = Objects.requireNonNullElse(namespace, ""); return this; } @@ -608,6 +613,7 @@ public ResultTypeConfig getResultType(String type) { return target.getAllResultTypeConfigs().get(type); } + @Override public Object getInterceptorConfig(String name) { return target.getAllInterceptorConfigs().get(name); } diff --git a/core/src/main/java/com/opensymphony/xwork2/config/entities/Parameterizable.java b/core/src/main/java/com/opensymphony/xwork2/config/entities/Parameterizable.java index eab975d70d..cae046e78a 100644 --- a/core/src/main/java/com/opensymphony/xwork2/config/entities/Parameterizable.java +++ b/core/src/main/java/com/opensymphony/xwork2/config/entities/Parameterizable.java @@ -37,7 +37,7 @@ */ public interface Parameterizable { - public void addParam(String name, String value); + void addParam(String name, String value); void setParams(Map params); diff --git a/core/src/main/java/com/opensymphony/xwork2/config/entities/ResultConfig.java b/core/src/main/java/com/opensymphony/xwork2/config/entities/ResultConfig.java index 50602636b9..f0d7752aa5 100644 --- a/core/src/main/java/com/opensymphony/xwork2/config/entities/ResultConfig.java +++ b/core/src/main/java/com/opensymphony/xwork2/config/entities/ResultConfig.java @@ -25,6 +25,7 @@ import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; +import java.util.Objects; /** @@ -73,21 +74,19 @@ public boolean equals(Object o) { return true; } - if (!(o instanceof ResultConfig)) { + if (!(o instanceof ResultConfig resultConfig)) { return false; } - final ResultConfig resultConfig = (ResultConfig) o; - - if ((className != null) ? (!className.equals(resultConfig.className)) : (resultConfig.className != null)) { + if (!Objects.equals(className, resultConfig.className)) { return false; } - if ((name != null) ? (!name.equals(resultConfig.name)) : (resultConfig.name != null)) { + if (!Objects.equals(name, resultConfig.name)) { return false; } - if ((params != null) ? (!params.equals(resultConfig.params)) : (resultConfig.params != null)) { + if (!Objects.equals(params, resultConfig.params)) { return false; } @@ -115,7 +114,7 @@ public String toString() { * After setting any values you need, call the {@link #build()} method to create the object. */ public static final class Builder { - protected ResultConfig target; + private ResultConfig target; public Builder(String name, String className) { target = new ResultConfig(name, className); @@ -157,7 +156,7 @@ public ResultConfig build() { return result; } - protected void embalmTarget() { + private void embalmTarget() { target.params = Collections.unmodifiableMap(target.params); } } diff --git a/core/src/main/java/com/opensymphony/xwork2/config/entities/ResultTypeConfig.java b/core/src/main/java/com/opensymphony/xwork2/config/entities/ResultTypeConfig.java index 944c34b89f..723319ed84 100644 --- a/core/src/main/java/com/opensymphony/xwork2/config/entities/ResultTypeConfig.java +++ b/core/src/main/java/com/opensymphony/xwork2/config/entities/ResultTypeConfig.java @@ -25,6 +25,7 @@ import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; +import java.util.Objects; /** @@ -82,9 +83,9 @@ public boolean equals(Object o) { final ResultTypeConfig that = (ResultTypeConfig) o; - if (className != null ? !className.equals(that.className) : that.className != null) return false; - if (name != null ? !name.equals(that.name) : that.name != null) return false; - if (params != null ? !params.equals(that.params) : that.params != null) return false; + if (!Objects.equals(className, that.className)) return false; + if (!Objects.equals(name, that.name)) return false; + if (!Objects.equals(params, that.params)) return false; return true; } @@ -110,7 +111,7 @@ public String toString() { * After setting any values you need, call the {@link #build()} method to create the object. */ public static final class Builder { - protected ResultTypeConfig target; + private ResultTypeConfig target; public Builder(String name, String className) { target = new ResultTypeConfig(name, className); diff --git a/core/src/main/java/com/opensymphony/xwork2/config/impl/ActionConfigMatcher.java b/core/src/main/java/com/opensymphony/xwork2/config/impl/ActionConfigMatcher.java index 344339e041..2bf4c6c726 100644 --- a/core/src/main/java/com/opensymphony/xwork2/config/impl/ActionConfigMatcher.java +++ b/core/src/main/java/com/opensymphony/xwork2/config/impl/ActionConfigMatcher.java @@ -33,23 +33,23 @@ /** *

Matches paths against pre-compiled wildcard expressions pulled from * action configs. It uses the wildcard matcher from the Apache Cocoon - * project. Patterns will be matched in the order they exist in the + * project. Patterns will be matched in the order they exist in the * config file. The first match wins, so more specific patterns should be * defined before less specific patterns. */ public class ActionConfigMatcher extends AbstractMatcher implements Serializable { - + /** *

Finds and precompiles the wildcard patterns from the ActionConfig * "path" attributes. ActionConfig's will be evaluated in the order they * exist in the config file. Only paths that actually contain a * wildcard will be compiled.

- * + * *

Patterns can optionally be matched "loosely". When * the end of the pattern matches \*[^*]\*$ (wildcard, no wildcard, - * wildcard), if the pattern fails, it is also matched as if the - * last two characters didn't exist. The goal is to support the - * legacy "*!*" syntax, where the "!*" is optional.

+ * wildcard), if the pattern fails, it is also matched as if the + * last two characters didn't exist. The goal is to support the + * legacy "*!*" syntax, where the "!*" is optional.

* * @param patternMatcher pattern matcher * @param configs An array of ActionConfig's to process @@ -100,7 +100,8 @@ public ActionConfigMatcher(PatternMatcher patternMatcher, * @return A cloned ActionConfig with appropriate properties replaced with * wildcard-matched values */ - @Override public ActionConfig convert(String path, ActionConfig orig, + @Override + public ActionConfig convert(String path, ActionConfig orig, Map vars) { String methodName = convertParam(orig.getMethodName(), vars); diff --git a/core/src/main/java/com/opensymphony/xwork2/config/impl/DefaultConfiguration.java b/core/src/main/java/com/opensymphony/xwork2/config/impl/DefaultConfiguration.java index 7c725e15b0..de3af59874 100644 --- a/core/src/main/java/com/opensymphony/xwork2/config/impl/DefaultConfiguration.java +++ b/core/src/main/java/com/opensymphony/xwork2/config/impl/DefaultConfiguration.java @@ -114,6 +114,7 @@ import org.apache.struts2.ognl.StrutsOgnlGuard; import org.apache.struts2.ognl.ThreadAllowlist; +import java.io.Serial; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -651,6 +652,7 @@ public String toString() { } class ContainerProperties extends LocatableProperties { + @Serial private static final long serialVersionUID = -7320625750836896089L; @Override diff --git a/core/src/main/java/com/opensymphony/xwork2/config/impl/LocatableConstantFactory.java b/core/src/main/java/com/opensymphony/xwork2/config/impl/LocatableConstantFactory.java index 1d36e6245d..319448060e 100644 --- a/core/src/main/java/com/opensymphony/xwork2/config/impl/LocatableConstantFactory.java +++ b/core/src/main/java/com/opensymphony/xwork2/config/impl/LocatableConstantFactory.java @@ -32,7 +32,7 @@ public LocatableConstantFactory(T constant, Object location) { this.constant = constant; setLocation(LocationUtils.getLocation(location)); } - + public T create(Context ignored) { return constant; } @@ -44,11 +44,7 @@ public Class type() { @Override public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(super.toString()); - sb.append(" defined at "); - sb.append(getLocation().toString()); - return sb.toString(); + return super.toString() + " defined at " + getLocation().toString(); } -} \ No newline at end of file +} diff --git a/core/src/main/java/com/opensymphony/xwork2/config/impl/LocatableFactory.java b/core/src/main/java/com/opensymphony/xwork2/config/impl/LocatableFactory.java index 712809487d..fdc282b349 100644 --- a/core/src/main/java/com/opensymphony/xwork2/config/impl/LocatableFactory.java +++ b/core/src/main/java/com/opensymphony/xwork2/config/impl/LocatableFactory.java @@ -24,7 +24,7 @@ import com.opensymphony.xwork2.util.location.Located; import com.opensymphony.xwork2.util.location.LocationUtils; -import java.util.LinkedHashMap; +import java.util.Map; /** * Attaches location information to the factory. @@ -32,10 +32,10 @@ public class LocatableFactory extends Located implements Factory { - private Class implementation; - private Class type; - private String name; - private Scope scope; + private final Class implementation; + private final Class type; + private final String name; + private final Scope scope; public LocatableFactory(String name, Class type, Class implementation, Scope scope, Object location) { this.implementation = implementation; @@ -58,18 +58,7 @@ public Class type() { @Override public String toString() { - String fields = new LinkedHashMap() { - { - put("type", type); - put("name", name); - put("implementation", implementation); - put("scope", scope); - } - }.toString(); - StringBuilder sb = new StringBuilder(fields); - sb.append(super.toString()); - sb.append(" defined at "); - sb.append(getLocation().toString()); - return sb.toString(); + var fields = Map.of("type", type,"name", name,"implementation", implementation,"scope", scope); + return fields + super.toString() + " defined at " + getLocation().toString(); } -} \ No newline at end of file +} diff --git a/core/src/main/java/com/opensymphony/xwork2/config/impl/MockConfiguration.java b/core/src/main/java/com/opensymphony/xwork2/config/impl/MockConfiguration.java index 30eee9566e..fd59b4bd74 100644 --- a/core/src/main/java/com/opensymphony/xwork2/config/impl/MockConfiguration.java +++ b/core/src/main/java/com/opensymphony/xwork2/config/impl/MockConfiguration.java @@ -43,11 +43,11 @@ */ public class MockConfiguration implements Configuration { - private Map packages = new HashMap<>(); - private Set loadedFiles = new HashSet<>(); + private final Map packages = new HashMap<>(); + private final Set loadedFiles = new HashSet<>(); private Container container; protected List unknownHandlerStack; - private ContainerBuilder builder; + private final ContainerBuilder builder; public MockConfiguration() { builder = new ContainerBuilder(); @@ -64,60 +64,67 @@ public void selfRegister() { container = builder.create(true); } + @Override public PackageConfig getPackageConfig(String name) { return packages.get(name); } + @Override public Set getPackageConfigNames() { return packages.keySet(); } + @Override public Map getPackageConfigs() { return packages; } + @Override public RuntimeConfiguration getRuntimeConfiguration() { throw new UnsupportedOperationException(); } + @Override public void addPackageConfig(String name, PackageConfig packageContext) { packages.put(name, packageContext); } - public void buildRuntimeConfiguration() { - throw new UnsupportedOperationException(); - } - + @Override public void destroy() { throw new UnsupportedOperationException(); } + @Override public void rebuildRuntimeConfiguration() { throw new UnsupportedOperationException(); } + @Override public PackageConfig removePackageConfig(String name) { return packages.remove(name); } + @Override public Container getContainer() { return container; } + @Override public Set getLoadedFileNames() { return loadedFiles; } - public List reloadContainer( - List containerProviders) - throws ConfigurationException { + @Override + public List reloadContainer(List containerProviders) throws ConfigurationException { throw new UnsupportedOperationException(); } + @Override public List getUnknownHandlerStack() { return unknownHandlerStack; } + @Override public void setUnknownHandlerStack(List unknownHandlerStack) { this.unknownHandlerStack = unknownHandlerStack; } diff --git a/core/src/main/java/com/opensymphony/xwork2/config/impl/NamespaceMatch.java b/core/src/main/java/com/opensymphony/xwork2/config/impl/NamespaceMatch.java index ce1c738f4c..376ade0f5b 100644 --- a/core/src/main/java/com/opensymphony/xwork2/config/impl/NamespaceMatch.java +++ b/core/src/main/java/com/opensymphony/xwork2/config/impl/NamespaceMatch.java @@ -26,8 +26,8 @@ * @since 2.1 */ public class NamespaceMatch { - private String pattern; - private Map variables; + private final String pattern; + private final Map variables; public NamespaceMatch(String pattern, Map variables) { this.pattern = pattern; diff --git a/core/src/main/java/com/opensymphony/xwork2/config/providers/CycleDetector.java b/core/src/main/java/com/opensymphony/xwork2/config/providers/CycleDetector.java index ac91f6de6b..b6365411de 100644 --- a/core/src/main/java/com/opensymphony/xwork2/config/providers/CycleDetector.java +++ b/core/src/main/java/com/opensymphony/xwork2/config/providers/CycleDetector.java @@ -24,10 +24,10 @@ import java.util.Map; public class CycleDetector { - private DirectedGraph graph; - private Map marks; - private List verticesInCycles; - + private final DirectedGraph graph; + private final Map marks; + private final List verticesInCycles; + private enum Status { MARKED, COMPLETE }; public CycleDetector(DirectedGraph graph) { diff --git a/core/src/main/java/com/opensymphony/xwork2/config/providers/DirectedGraph.java b/core/src/main/java/com/opensymphony/xwork2/config/providers/DirectedGraph.java index 455838ce3e..6caacc40e7 100644 --- a/core/src/main/java/com/opensymphony/xwork2/config/providers/DirectedGraph.java +++ b/core/src/main/java/com/opensymphony/xwork2/config/providers/DirectedGraph.java @@ -31,7 +31,7 @@ public final class DirectedGraph implements Iterable { /** * Adds a new node to the graph. If the node already exists, this function is a no-op. - * + * * @param node * The node to add. * @return Whether or not the node was added. @@ -49,7 +49,7 @@ public boolean addNode(T node) { /** * Given a start node, and a destination, adds an arc from the start node to the destination. If an arc already exists, this operation is a no-op. * If either endpoint does not exist in the graph, throws a NoSuchElementException. - * + * * @param start * The start node. * @param dest @@ -72,7 +72,7 @@ public void addEdge(T start, T dest) { /** * Removes the edge from start to dest from the graph. If the edge does not exist, this operation is a no-op. If either endpoint does not exist, * this throws a NoSuchElementException. - * + * * @param start * The start node. * @param dest @@ -94,7 +94,7 @@ public void removeEdge(T start, T dest) { /** * Given two nodes in the graph, returns whether there is an edge from the first node to the second node. If either node does not exist in the * graph, throws a NoSuchElementException. - * + * * @param start * The start node. * @param end @@ -116,7 +116,7 @@ public boolean edgeExists(T start, T end) { /** * Given a node in the graph, returns an immutable view of the edges leaving that node as a set of endpoints. - * + * * @param node * The node whose edges should be queried. * @return An immutable view of the edges leaving that node. @@ -134,16 +134,17 @@ public Set edgesFrom(T node) { /** * Returns an iterator that can traverse the nodes in the graph. - * + * * @return An iterator that traverses the nodes in the graph. */ + @Override public Iterator iterator() { return mGraph.keySet().iterator(); } /** * Returns the number of nodes in the graph. - * + * * @return The number of nodes in the graph. */ public int size() { @@ -152,7 +153,7 @@ public int size() { /** * Returns whether the graph is empty. - * + * * @return Whether the graph is empty. */ public boolean isEmpty() { diff --git a/core/src/main/java/com/opensymphony/xwork2/config/providers/InterceptorBuilder.java b/core/src/main/java/com/opensymphony/xwork2/config/providers/InterceptorBuilder.java index bf84cf366c..170e94fc13 100644 --- a/core/src/main/java/com/opensymphony/xwork2/config/providers/InterceptorBuilder.java +++ b/core/src/main/java/com/opensymphony/xwork2/config/providers/InterceptorBuilder.java @@ -59,28 +59,28 @@ public class InterceptorBuilder { * @throws ConfigurationException in case of any configuration errors */ public static List constructInterceptorReference(InterceptorLocator interceptorLocator, - String refName, Map refParams, Location location, ObjectFactory objectFactory) throws ConfigurationException { + String refName, + Map refParams, + Location location, + ObjectFactory objectFactory) throws ConfigurationException { Object referencedConfig = interceptorLocator.getInterceptorConfig(refName); List result = new ArrayList<>(); if (referencedConfig == null) { throw new ConfigurationException("Unable to find interceptor class referenced by ref-name " + refName, location); } else { - if (referencedConfig instanceof InterceptorConfig) { - InterceptorConfig config = (InterceptorConfig) referencedConfig; - Interceptor inter; + if (referencedConfig instanceof InterceptorConfig config) { try { - inter = objectFactory.buildInterceptor(config, refParams); + Interceptor inter = objectFactory.buildInterceptor(config, refParams); result.add(new InterceptorMapping(refName, inter, refParams)); } catch (ConfigurationException ex) { LOG.warn(new ParameterizedMessage("Unable to load config class {} at {} probably due to a missing jar, which might be fine if you never plan to use the {} interceptor", config.getClassName(), ex.getLocation(), config.getName()), ex); } - } else if (referencedConfig instanceof InterceptorStackConfig) { - InterceptorStackConfig stackConfig = (InterceptorStackConfig) referencedConfig; + } else if (referencedConfig instanceof InterceptorStackConfig stackConfig) { - if ((refParams != null) && (refParams.size() > 0)) { + if (refParams != null && !refParams.isEmpty()) { result = constructParameterizedInterceptorReferences(interceptorLocator, stackConfig, refParams, objectFactory); } else { result.addAll(stackConfig.getInterceptors()); @@ -104,7 +104,9 @@ public static List constructInterceptorReference(Interceptor * @return list of interceptors referenced by the refName in the supplied PackageConfig overridden with refParams. */ private static List constructParameterizedInterceptorReferences( - InterceptorLocator interceptorLocator, InterceptorStackConfig stackConfig, Map refParams, + InterceptorLocator interceptorLocator, + InterceptorStackConfig stackConfig, + Map refParams, ObjectFactory objectFactory) { List result; Map> params = new LinkedHashMap<>(); @@ -177,8 +179,7 @@ private static List constructParameterizedInterceptorReferen * ... * */ - if (interceptorCfgObj instanceof InterceptorConfig) { // interceptor-ref param refer to an interceptor - InterceptorConfig cfg = (InterceptorConfig) interceptorCfgObj; + if (interceptorCfgObj instanceof InterceptorConfig cfg) { // interceptor-ref param refer to an interceptor Interceptor interceptor = objectFactory.buildInterceptor(cfg, map); InterceptorMapping mapping = new InterceptorMapping(key, interceptor); @@ -194,13 +195,12 @@ private static List constructParameterizedInterceptorReferen result.add(mapping); } } else - if (interceptorCfgObj instanceof InterceptorStackConfig) { // interceptor-ref param refer to an interceptor stack + if (interceptorCfgObj instanceof InterceptorStackConfig stackCfg) { // interceptor-ref param refer to an interceptor stack // If its an interceptor-stack, we call this method recursively until, // all the params (eg. interceptorStack1.interceptor1.param etc.) // are resolved down to a specific interceptor. - InterceptorStackConfig stackCfg = (InterceptorStackConfig) interceptorCfgObj; List tmpResult = constructParameterizedInterceptorReferences(interceptorLocator, stackCfg, map, objectFactory); for (InterceptorMapping tmpInterceptorMapping : tmpResult) { if (result.contains(tmpInterceptorMapping)) { diff --git a/core/src/main/java/com/opensymphony/xwork2/config/providers/XmlConfigurationProvider.java b/core/src/main/java/com/opensymphony/xwork2/config/providers/XmlConfigurationProvider.java index 088cf24dda..c3c8049c2f 100644 --- a/core/src/main/java/com/opensymphony/xwork2/config/providers/XmlConfigurationProvider.java +++ b/core/src/main/java/com/opensymphony/xwork2/config/providers/XmlConfigurationProvider.java @@ -228,10 +228,9 @@ public boolean equals(Object o) { if (this == o) { return true; } - if (!(o instanceof XmlConfigurationProvider)) { + if (!(o instanceof XmlConfigurationProvider xmlConfigurationProvider)) { return false; } - XmlConfigurationProvider xmlConfigurationProvider = (XmlConfigurationProvider) o; return Objects.equals(configFileName, xmlConfigurationProvider.configFileName); } diff --git a/core/src/main/java/com/opensymphony/xwork2/config/providers/XmlDocConfigurationProvider.java b/core/src/main/java/com/opensymphony/xwork2/config/providers/XmlDocConfigurationProvider.java index 53baf52dba..87eb2a84aa 100644 --- a/core/src/main/java/com/opensymphony/xwork2/config/providers/XmlDocConfigurationProvider.java +++ b/core/src/main/java/com/opensymphony/xwork2/config/providers/XmlDocConfigurationProvider.java @@ -218,12 +218,12 @@ protected void registerBeanSelection(Element child, ContainerBuilder containerBu try { Class classImpl = ClassLoaderUtil.loadClass(impl, getClass()); if (BeanSelectionProvider.class.isAssignableFrom(classImpl)) { - BeanSelectionProvider provider = (BeanSelectionProvider) classImpl.newInstance(); + BeanSelectionProvider provider = (BeanSelectionProvider) classImpl.getDeclaredConstructor().newInstance(); provider.register(containerBuilder, props); } else { throw new ConfigurationException(format("The bean-provider: name:%s class:%s does not implement %s", name, impl, BeanSelectionProvider.class.getName()), child); } - } catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) { + } catch (ReflectiveOperationException e) { throw new ConfigurationException(format("Unable to load bean-provider: name:%s class:%s", name, impl), e, child); } } @@ -525,8 +525,8 @@ protected void verifyAction(String className, Location loc) { if (objectFactory.isNoArgConstructorRequired()) { throw new ConfigurationException("Action class [" + className + "] not found", e, loc); } - LOG.warn("Action class [" + className + "] not found"); - LOG.debug("Action class [" + className + "] not found", e); + LOG.warn("Action class [{}] not found", className); + LOG.debug("Action class [{}] not found", className, e); } catch (NoSuchMethodException e) { throw new ConfigurationException("Action class [" + className + "] does not have a public no-arg constructor", e, loc); } catch (RuntimeException ex) { @@ -732,7 +732,7 @@ protected Map buildResultParams(Element resultElement, ResultTyp } }); String val = paramValue.toString().trim(); - if (val.length() > 0) { + if (!val.isEmpty()) { resultParams.put(paramName, val); } } else { @@ -876,12 +876,12 @@ protected static void addAllowedMethodsToSet(Node allowedMethodsNode, Set 0) { + if (!childNodeValue.isEmpty()) { allowedMethodsSB.append(childNodeValue); } } }); - if (allowedMethodsSB.length() > 0) { + if (!allowedMethodsSB.isEmpty()) { allowedMethodsSet.addAll(commaDelimitedStringToSet(allowedMethodsSB.toString())); } } @@ -949,8 +949,8 @@ protected void verifyInterceptor(String className, Location loc) { try { allowAndLoadClass(className); } catch (ClassNotFoundException | NoClassDefFoundError e) { - LOG.warn("Interceptor class [" + className + "] at location " + loc + " not found"); - LOG.debug("Interceptor class [" + className + "] not found", e); + LOG.warn("Interceptor class [{}] at location {} not found", className, loc); + LOG.debug("Interceptor class [{}] not found", className, e); } } diff --git a/core/src/main/java/com/opensymphony/xwork2/config/providers/XmlHelper.java b/core/src/main/java/com/opensymphony/xwork2/config/providers/XmlHelper.java index 953aa7c557..8f6977f854 100644 --- a/core/src/main/java/com/opensymphony/xwork2/config/providers/XmlHelper.java +++ b/core/src/main/java/com/opensymphony/xwork2/config/providers/XmlHelper.java @@ -80,7 +80,7 @@ public static Map getParams(Element paramsElement) { String paramName = paramElement.getAttribute("name"); String val = getContent(paramElement); - if (val.length() > 0) { + if (!val.isEmpty()) { params.put(paramName, val); } } diff --git a/core/src/main/java/com/opensymphony/xwork2/conversion/ObjectTypeDeterminer.java b/core/src/main/java/com/opensymphony/xwork2/conversion/ObjectTypeDeterminer.java index 220009ef2a..852b33043a 100644 --- a/core/src/main/java/com/opensymphony/xwork2/conversion/ObjectTypeDeterminer.java +++ b/core/src/main/java/com/opensymphony/xwork2/conversion/ObjectTypeDeterminer.java @@ -29,12 +29,16 @@ */ public interface ObjectTypeDeterminer { - public Class getKeyClass(Class parentClass, String property); + Class getKeyClass(Class parentClass, String property); - public Class getElementClass(Class parentClass, String property, Object key); + Class getElementClass(Class parentClass, String property, Object key); - public String getKeyProperty(Class parentClass, String property); - - public boolean shouldCreateIfNew(Class parentClass, String property, Object target, String keyProperty, boolean isIndexAccessed); + String getKeyProperty(Class parentClass, String property); + + boolean shouldCreateIfNew(Class parentClass, + String property, + Object target, + String keyProperty, + boolean isIndexAccessed); } diff --git a/core/src/main/java/com/opensymphony/xwork2/conversion/impl/DateConverter.java b/core/src/main/java/com/opensymphony/xwork2/conversion/impl/DateConverter.java index 87a0f06cc8..298381b162 100644 --- a/core/src/main/java/com/opensymphony/xwork2/conversion/impl/DateConverter.java +++ b/core/src/main/java/com/opensymphony/xwork2/conversion/impl/DateConverter.java @@ -18,6 +18,13 @@ */ package com.opensymphony.xwork2.conversion.impl; +import com.opensymphony.xwork2.ActionContext; +import com.opensymphony.xwork2.TextProvider; +import com.opensymphony.xwork2.util.ValueStack; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.struts2.conversion.TypeConversionException; + import java.lang.reflect.Constructor; import java.lang.reflect.Member; import java.text.DateFormat; @@ -33,14 +40,6 @@ import java.util.Locale; import java.util.Map; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.apache.struts2.conversion.TypeConversionException; - -import com.opensymphony.xwork2.ActionContext; -import com.opensymphony.xwork2.TextProvider; -import com.opensymphony.xwork2.util.ValueStack; - public class DateConverter extends DefaultTypeConverter { private final static Logger LOG = LogManager.getLogger(DateConverter.class); @@ -50,15 +49,14 @@ public Object convertValue(Map context, Object target, Member me Object value, Class toType) { Date result = null; - if (value instanceof String && ((String) value).length() > 0) { - String sa = (String) value; + if (value instanceof String sa && !sa.isEmpty()) { Locale locale = getLocale(context); DateFormat df = null; if (java.sql.Time.class == toType) { df = DateFormat.getTimeInstance(DateFormat.MEDIUM, locale); } else if (java.sql.Timestamp.class == toType) { - Date check = null; + Date check; SimpleDateFormat dtfmt = (SimpleDateFormat) DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM, locale); SimpleDateFormat fullfmt = new SimpleDateFormat(dtfmt.toPattern() + MILLISECOND_FORMAT, locale); @@ -100,9 +98,7 @@ public Object convertValue(Map context, Object target, Member me try { check = df1.parseBest(sa, LocalDateTime::from, LocalDate::from, LocalTime::from); dtf = df1; - if (check != null) { - break; - } + break; } catch (DateTimeParseException ignore) { } } @@ -131,8 +127,8 @@ public Object convertValue(Map context, Object target, Member me result = df.parse(sa); if (!(Date.class == toType)) { try { - Constructor constructor = toType.getConstructor(new Class[] { long.class }); - return constructor.newInstance(new Object[] { Long.valueOf(result.getTime()) }); + Constructor constructor = toType.getConstructor(long.class); + return constructor.newInstance(result.getTime()); } catch (Exception e) { throw new TypeConversionException( "Couldn't create class " + toType + " using default (long) constructor", e); @@ -153,7 +149,7 @@ public Object convertValue(Map context, Object target, Member me * {@link org.apache.struts2.components.Date#DATETAG_PROPERTY} * * @param context current ActionContext - * + * * @return defined global date string format */ protected String getGlobalDateString(ActionContext context) { @@ -179,7 +175,7 @@ protected String getGlobalDateString(ActionContext context) { /** * Retrieves the list of date formats to be used when converting dates - * + * * @param context the current ActionContext * @param locale the current locale of the action * @return a list of DateFormat to be used for date conversion @@ -215,10 +211,10 @@ private DateFormat[] getDateFormats(ActionContext context, Locale locale) { /** * Retrieves the list of date time formats to be used when converting dates - * + * * @param context the current ActionContext * @param locale the current locale of the action - * + * * @return a list of DateTimeFormatter to be used for date conversion */ protected DateTimeFormatter[] getDateTimeFormats(ActionContext context, Locale locale) { diff --git a/core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultObjectTypeDeterminer.java b/core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultObjectTypeDeterminer.java index 2ef75e88cb..62d902355a 100644 --- a/core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultObjectTypeDeterminer.java +++ b/core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultObjectTypeDeterminer.java @@ -64,8 +64,8 @@ public class DefaultObjectTypeDeterminer implements ObjectTypeDeterminer { public static final String CREATE_IF_NULL_PREFIX = "CreateIfNull_"; public static final String DEPRECATED_ELEMENT_PREFIX = "Collection_"; - private ReflectionProvider reflectionProvider; - private XWorkConverter xworkConverter; + private final ReflectionProvider reflectionProvider; + private final XWorkConverter xworkConverter; @Inject public DefaultObjectTypeDeterminer(@Inject XWorkConverter converter, @Inject ReflectionProvider provider) { @@ -261,7 +261,7 @@ private Class getClass(Class parentClass, String property, boolean element) { genericType = field.getGenericType(); } // Try to get ParameterType from setter method - if (genericType == null || !(genericType instanceof ParameterizedType)) { + if (!(genericType instanceof ParameterizedType)) { try { Method setter = reflectionProvider.getSetMethod(parentClass, property); genericType = setter != null ? setter.getGenericParameterTypes()[0] : null; @@ -271,7 +271,7 @@ private Class getClass(Class parentClass, String property, boolean element) { } // Try to get ReturnType from getter method - if (genericType == null || !(genericType instanceof ParameterizedType)) { + if (!(genericType instanceof ParameterizedType)) { try { Method getter = reflectionProvider.getGetMethod(parentClass, property); genericType = getter.getGenericReturnType(); @@ -280,8 +280,7 @@ private Class getClass(Class parentClass, String property, boolean element) { } } - if (genericType instanceof ParameterizedType) { - ParameterizedType type = (ParameterizedType) genericType; + if (genericType instanceof ParameterizedType type) { int index = (element && type.getRawType().toString().contains(Map.class.getName())) ? 1 : 0; Type resultType = type.getActualTypeArguments()[index]; if (resultType instanceof ParameterizedType) { diff --git a/core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultTypeConverter.java b/core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultTypeConverter.java index 66656548f6..fb9d91cd60 100644 --- a/core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultTypeConverter.java +++ b/core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultTypeConverter.java @@ -30,15 +30,13 @@ import java.lang.reflect.Member; import java.math.BigDecimal; import java.math.BigInteger; -import java.util.Collections; -import java.util.HashMap; import java.util.Locale; import java.util.Map; /** - * Default type conversion. Converts among numeric types and also strings. Contains the basic + * Default type conversion. Converts among numeric types and also strings. Contains the basic * type mapping code from OGNL. - * + * * @author Luke Blanshard (blanshlu@netscape.net) * @author Drew Davidson (drew@ognl.org) */ @@ -48,25 +46,20 @@ public abstract class DefaultTypeConverter implements TypeConverter { private static final String NULL_STRING = "null"; - private static final Map, Object> baseTypeDefaults; + private static final Map, Object> baseTypeDefaults = Map.of( + Boolean.TYPE, Boolean.FALSE, + Byte.TYPE, (byte) 0, + Short.TYPE, (short) 0, + Character.TYPE, (char) 0, + Integer.TYPE, 0, + Long.TYPE, 0L, + Float.TYPE, 0.0f, + Double.TYPE, 0.0, + BigInteger.class, BigInteger.ZERO, + BigDecimal.class, BigDecimal.ZERO); private Container container; - static { - Map, Object> map = new HashMap<>(); - map.put(Boolean.TYPE, Boolean.FALSE); - map.put(Byte.TYPE, Byte.valueOf((byte) 0)); - map.put(Short.TYPE, Short.valueOf((short) 0)); - map.put(Character.TYPE, new Character((char) 0)); - map.put(Integer.TYPE, Integer.valueOf(0)); - map.put(Long.TYPE, Long.valueOf(0L)); - map.put(Float.TYPE, new Float(0.0f)); - map.put(Double.TYPE, new Double(0.0)); - map.put(BigInteger.class, BigInteger.ZERO); - map.put(BigDecimal.class, BigDecimal.ZERO); - baseTypeDefaults = Collections.unmodifiableMap(map); - } - @Inject public void setContainer(Container container) { this.container = container; @@ -81,7 +74,7 @@ public Object convertValue(Map context, Object target, Member me String propertyName, Object value, Class toType) { return convertValue(context, value, toType); } - + public TypeConverter getTypeConverter( Map context ) { ognl.TypeConverter converter = null; @@ -102,10 +95,10 @@ public TypeConverter getTypeConverter( Map context ) { /** * Returns the value converted numerically to the given class type - * + * * This method also detects when arrays are being converted and converts the * components of one array to the type of the other. - * + * * @param value * an object to be converted to the given type * @param toType @@ -121,11 +114,9 @@ public Object convertValue(Object value, Class toType) { if (value.getClass().isArray() && toType.isArray()) { final Class componentType = toType.getComponentType(); - result = Array.newInstance(componentType, Array - .getLength(value)); + result = Array.newInstance(componentType, Array.getLength(value)); for (int i = 0, icount = Array.getLength(value); i < icount; i++) { - Array.set(result, i, convertValue(Array.get(value, i), - componentType)); + Array.set(result, i, convertValue(Array.get(value, i), componentType)); } } else { if ((toType == Integer.class) || (toType == Integer.TYPE)) @@ -143,7 +134,7 @@ public Object convertValue(Object value, Class toType) { if ((toType == Long.class) || (toType == Long.TYPE)) result = longValue(value); if ((toType == Float.class) || (toType == Float.TYPE)) - result = new Float(doubleValue(value)); + result = (float) doubleValue(value); if (toType == BigInteger.class) result = bigIntValue(value); if (toType == BigDecimal.class) @@ -163,7 +154,7 @@ public Object convertValue(Object value, Class toType) { * Evaluates the given object as a boolean: if it is a Boolean object, it's * easy; if it's a Number or a Character, returns true for non-zero objects; * and otherwise returns true for non-null objects. - * + * * @param value * an object to interpret as a boolean * @return the boolean value implied by the given object @@ -182,12 +173,10 @@ public static boolean booleanValue(Object value) { return ((Number) value).doubleValue() != 0; return true; // non-null } - + public Enum enumValue(Class toClass, Object o) { Enum result = null; - if (o == null) { - result = null; - } else if (o instanceof String[]) { + if (o instanceof String[]) { result = Enum.valueOf(toClass, ((String[]) o)[0]); } else if (o instanceof String) { result = Enum.valueOf(toClass, (String) o); @@ -197,7 +186,7 @@ public Enum enumValue(Class toClass, Object o) { /** * Evaluates the given object as a long integer. - * + * * @param value * an object to interpret as a long integer * @return the long integer value implied by the given object @@ -217,7 +206,7 @@ public static long longValue(Object value) { /** * Evaluates the given object as a double-precision floating-point number. - * + * * @param value * an object to interpret as a double * @return the double value implied by the given object @@ -233,12 +222,12 @@ public static double doubleValue(Object value) { if (c == Character.class) return (Character) value; final String s = stringValue(value, true); - return (s.length() == 0) ? 0.0 : Double.parseDouble(s); + return s.isEmpty() ? 0.0 : Double.parseDouble(s); } /** * Evaluates the given object as a BigInteger. - * + * * @param value * an object to interpret as a BigInteger * @return the BigInteger value implied by the given object @@ -256,13 +245,13 @@ public static BigInteger bigIntValue(Object value) { if (c == Boolean.class) return BigInteger.valueOf((Boolean) value ? 1 : 0); if (c == Character.class) - return BigInteger.valueOf(((Character) value).charValue()); + return BigInteger.valueOf((Character) value); return new BigInteger(stringValue(value, true)); } /** * Evaluates the given object as a BigDecimal. - * + * * @param value * an object to interpret as a BigDecimal * @return the BigDecimal value implied by the given object @@ -280,14 +269,14 @@ public static BigDecimal bigDecValue(Object value) { if (c == Boolean.class) return BigDecimal.valueOf((Boolean) value ? 1 : 0); if (c == Character.class) - return BigDecimal.valueOf(((Character) value).charValue()); + return BigDecimal.valueOf((Character) value); return new BigDecimal(stringValue(value, true)); } /** * Evaluates the given object as a String and trims it if the trim flag is * true. - * + * * @param value * an object to interpret as a String * @param trim @@ -311,7 +300,7 @@ public static String stringValue(Object value, boolean trim) { /** * Evaluates the given object as a String. - * + * * @param value * an object to interpret as a String * @return the String value implied by the given object as returned by the diff --git a/core/src/main/java/com/opensymphony/xwork2/conversion/impl/NumberConverter.java b/core/src/main/java/com/opensymphony/xwork2/conversion/impl/NumberConverter.java index 3f47566291..f1b03ad5fa 100644 --- a/core/src/main/java/com/opensymphony/xwork2/conversion/impl/NumberConverter.java +++ b/core/src/main/java/com/opensymphony/xwork2/conversion/impl/NumberConverter.java @@ -18,9 +18,9 @@ */ package com.opensymphony.xwork2.conversion.impl; -import org.apache.struts2.conversion.TypeConversionException; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.apache.struts2.conversion.TypeConversionException; import java.lang.reflect.Member; import java.math.BigDecimal; @@ -55,7 +55,7 @@ public Object convertValue(Map context, Object target, Member me return convertedValue; } else { - if (!toType.isPrimitive() && stringValue.isEmpty()) { + if (stringValue.isEmpty()) { return null; } NumberFormat numFormat = NumberFormat.getInstance(getLocale(context)); @@ -76,8 +76,7 @@ public Object convertValue(Map context, Object target, Member me value = super.convertValue(context, number, toType); } } - } else if (value instanceof Object[]) { - Object[] objArray = (Object[]) value; + } else if (value instanceof Object[] objArray) { if (objArray.length == 1) { return convertValue(context, null, null, null, objArray[0], toType); @@ -180,9 +179,9 @@ protected String normalize(String strValue, char separator) { } protected boolean isInRange(Number value, String stringValue, Class toType) { - Number bigValue = null; - Number lowerBound = null; - Number upperBound = null; + Number bigValue; + Number lowerBound; + Number upperBound; try { if (double.class == toType || Double.class == toType) { @@ -227,12 +226,8 @@ protected boolean isInRange(Number value, String stringValue, Class toType) { } private boolean isIntegerType(Class type) { - if (double.class == type || float.class == type || Double.class == type || Float.class == type - || char.class == type || Character.class == type) { - return false; - } - - return true; + return double.class != type && float.class != type && Double.class != type && Float.class != type + && char.class != type && Character.class != type; } } diff --git a/core/src/main/java/com/opensymphony/xwork2/conversion/impl/StringConverter.java b/core/src/main/java/com/opensymphony/xwork2/conversion/impl/StringConverter.java index c1abc9b7c7..e0f7d4bb23 100644 --- a/core/src/main/java/com/opensymphony/xwork2/conversion/impl/StringConverter.java +++ b/core/src/main/java/com/opensymphony/xwork2/conversion/impl/StringConverter.java @@ -80,14 +80,14 @@ public Object convertValue(Map context, Object target, Member me } protected String convertToString(Locale locale, Object value) { - if (Number.class.isInstance(value)) { + if (value instanceof Number) { NumberFormat format = NumberFormat.getNumberInstance(locale); format.setGroupingUsed(false); // TODO: delete this variable and corresponding if statement when jdk fixed java.text.NumberFormat.format's behavior with Float Object fixedValue = value; - if (BigDecimal.class.isInstance(value) || Double.class.isInstance(value) || Float.class.isInstance(value)) { + if (value instanceof BigDecimal || value instanceof Double || value instanceof Float) { format.setMaximumFractionDigits(Integer.MAX_VALUE); - if (Float.class.isInstance(value)) { + if (value instanceof Float) { fixedValue = Double.valueOf(value.toString()); } } diff --git a/core/src/main/java/com/opensymphony/xwork2/conversion/impl/XWorkBasicConverter.java b/core/src/main/java/com/opensymphony/xwork2/conversion/impl/XWorkBasicConverter.java index 3c9eb3ad1d..c02b5ce61a 100644 --- a/core/src/main/java/com/opensymphony/xwork2/conversion/impl/XWorkBasicConverter.java +++ b/core/src/main/java/com/opensymphony/xwork2/conversion/impl/XWorkBasicConverter.java @@ -18,11 +18,11 @@ */ package com.opensymphony.xwork2.conversion.impl; -import org.apache.struts2.conversion.TypeConversionException; import com.opensymphony.xwork2.conversion.TypeConverter; import com.opensymphony.xwork2.inject.Container; import com.opensymphony.xwork2.inject.Inject; import org.apache.struts2.StrutsConstants; +import org.apache.struts2.conversion.TypeConversionException; import java.lang.reflect.Member; import java.time.LocalDateTime; @@ -117,8 +117,7 @@ public Object convertValue(Map context, Object o, Member member, } if (result == null) { - if (value instanceof Object[]) { - Object[] array = (Object[]) value; + if (value instanceof Object[] array) { if (array.length >= 1) { value = array[0]; @@ -152,16 +151,14 @@ private Object doConvertToCalendar(Map context, Object value) { } private Object doConvertToCharacter(Object value) { - if (value instanceof String) { - String cStr = (String) value; - return (cStr.length() > 0) ? cStr.charAt(0) : null; + if (value instanceof String cStr) { + return !cStr.isEmpty() ? cStr.charAt(0) : null; } return null; } private Object doConvertToBoolean(Object value) { - if (value instanceof String) { - String bStr = (String) value; + if (value instanceof String bStr) { return Boolean.valueOf(bStr); } return null; @@ -169,9 +166,9 @@ private Object doConvertToBoolean(Object value) { private Class doConvertToClass(Object value) { Class clazz = null; - if (value != null && value instanceof String && ((String) value).length() > 0) { + if (value instanceof String st && !st.isEmpty()) { try { - clazz = Class.forName((String) value); + clazz = Class.forName(st); } catch (ClassNotFoundException e) { throw new TypeConversionException(e.getLocalizedMessage(), e); } diff --git a/core/src/main/java/com/opensymphony/xwork2/conversion/impl/XWorkConverter.java b/core/src/main/java/com/opensymphony/xwork2/conversion/impl/XWorkConverter.java index 3cda3e34dd..cdad25991a 100644 --- a/core/src/main/java/com/opensymphony/xwork2/conversion/impl/XWorkConverter.java +++ b/core/src/main/java/com/opensymphony/xwork2/conversion/impl/XWorkConverter.java @@ -18,12 +18,21 @@ */ package com.opensymphony.xwork2.conversion.impl; -import com.opensymphony.xwork2.*; -import com.opensymphony.xwork2.conversion.*; +import com.opensymphony.xwork2.ActionContext; +import com.opensymphony.xwork2.FileManager; +import com.opensymphony.xwork2.FileManagerFactory; +import com.opensymphony.xwork2.LocalizedTextProvider; +import com.opensymphony.xwork2.conversion.ConversionAnnotationProcessor; +import com.opensymphony.xwork2.conversion.ConversionFileProcessor; +import com.opensymphony.xwork2.conversion.TypeConverter; +import com.opensymphony.xwork2.conversion.TypeConverterHolder; import com.opensymphony.xwork2.conversion.annotations.Conversion; import com.opensymphony.xwork2.conversion.annotations.TypeConversion; import com.opensymphony.xwork2.inject.Inject; -import com.opensymphony.xwork2.util.*; +import com.opensymphony.xwork2.util.AnnotationUtils; +import com.opensymphony.xwork2.util.ClassLoaderUtil; +import com.opensymphony.xwork2.util.CompoundRoot; +import com.opensymphony.xwork2.util.ValueStack; import com.opensymphony.xwork2.util.reflection.ReflectionContextState; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; @@ -143,8 +152,8 @@ public class XWorkConverter extends DefaultTypeConverter { public static final String LAST_BEAN_CLASS_ACCESSED = "last.bean.accessed"; public static final String LAST_BEAN_PROPERTY_ACCESSED = "last.property.accessed"; - public static final String MESSAGE_INDEX_PATTERN = "\\[\\d+\\]\\."; - public static final String MESSAGE_INDEX_BRACKET_PATTERN = "[\\[\\]\\.]"; + public static final String MESSAGE_INDEX_PATTERN = "\\[\\d+]\\."; + public static final String MESSAGE_INDEX_BRACKET_PATTERN = "[\\[\\].]"; public static final String PERIOD = "."; public static final Pattern messageIndexPattern = Pattern.compile(MESSAGE_INDEX_PATTERN); @@ -228,7 +237,7 @@ private static List getIndexValues(String propertyName) { Matcher matcher = messageIndexPattern.matcher(propertyName); List indexes = new ArrayList<>(); while (matcher.find()) { - Integer index = new Integer(matcher.group().replaceAll(MESSAGE_INDEX_BRACKET_PATTERN, "")) + 1; + int index = Integer.parseInt(matcher.group().replaceAll(MESSAGE_INDEX_BRACKET_PATTERN, "")) + 1; indexes.add(Integer.toString(index)); } return indexes; @@ -297,7 +306,7 @@ public Object convertValue(Map context, Object target, Member me } if (tc == null) { - if (toClass.equals(String.class) && (value != null) && !(value.getClass().equals(String.class) || value.getClass().equals(String[].class))) { + if (toClass.equals(String.class) && value != null && !value.getClass().equals(String[].class)) { // when converting to a string, use the source target's class's converter tc = lookup(value.getClass()); } else { @@ -484,8 +493,7 @@ protected void addConverterMapping(Map mapping, Class clazz) { Annotation[] annotations = clazz.getAnnotations(); for (Annotation annotation : annotations) { - if (annotation instanceof Conversion) { - Conversion conversion = (Conversion) annotation; + if (annotation instanceof Conversion conversion) { for (TypeConversion tc : conversion.conversions()) { if (mapping.containsKey(tc.key())) { break; @@ -506,29 +514,19 @@ protected void addConverterMapping(Map mapping, Class clazz) { for (Method method : clazz.getMethods()) { annotations = method.getAnnotations(); for (Annotation annotation : annotations) { - if (annotation instanceof TypeConversion) { - TypeConversion tc = (TypeConversion) annotation; + if (annotation instanceof TypeConversion tc) { String key = tc.key(); // Default to the property name with prefix if (StringUtils.isEmpty(key)) { key = AnnotationUtils.resolvePropertyName(method); - switch (tc.rule()) { - case COLLECTION: - key = DefaultObjectTypeDeterminer.DEPRECATED_ELEMENT_PREFIX + key; - break; - case CREATE_IF_NULL: - key = DefaultObjectTypeDeterminer.CREATE_IF_NULL_PREFIX + key; - break; - case ELEMENT: - key = DefaultObjectTypeDeterminer.ELEMENT_PREFIX + key; - break; - case KEY: - key = DefaultObjectTypeDeterminer.KEY_PREFIX + key; - break; - case KEY_PROPERTY: - key = DefaultObjectTypeDeterminer.KEY_PROPERTY_PREFIX + key; - break; - } + key = switch (tc.rule()) { + case COLLECTION -> DefaultObjectTypeDeterminer.DEPRECATED_ELEMENT_PREFIX + key; + case CREATE_IF_NULL -> DefaultObjectTypeDeterminer.CREATE_IF_NULL_PREFIX + key; + case ELEMENT -> DefaultObjectTypeDeterminer.ELEMENT_PREFIX + key; + case KEY -> DefaultObjectTypeDeterminer.KEY_PREFIX + key; + case KEY_PROPERTY -> DefaultObjectTypeDeterminer.KEY_PROPERTY_PREFIX + key; + default -> key; + }; LOG.debug("Retrieved key [{}] from method name [{}]", key, method.getName()); } if (mapping.containsKey(key)) { @@ -570,7 +568,7 @@ protected Map buildConverterMapping(Class clazz) throws Exceptio curClazz = curClazz.getSuperclass(); } - if (mapping.size() > 0) { + if (!mapping.isEmpty()) { converterHolder.addMapping(clazz, mapping); } else { converterHolder.addNoMapping(clazz); diff --git a/core/src/main/java/com/opensymphony/xwork2/conversion/impl/XWorkList.java b/core/src/main/java/com/opensymphony/xwork2/conversion/impl/XWorkList.java index 6243c10975..ee5093ed47 100644 --- a/core/src/main/java/com/opensymphony/xwork2/conversion/impl/XWorkList.java +++ b/core/src/main/java/com/opensymphony/xwork2/conversion/impl/XWorkList.java @@ -41,7 +41,7 @@ public class XWorkList extends ArrayList { private static final Logger LOG = LogManager.getLogger(XWorkConverter.class); - private Class clazz; + private final Class clazz; public XWorkList(Class clazz) { this.clazz = clazz; @@ -152,11 +152,7 @@ public boolean addAll(int index, Collection collection) { throw new NullPointerException("Collection to add is null"); } - boolean trim = false; - - if (index >= this.size()) { - trim = true; - } + boolean trim = index >= this.size(); for (Iterator it = collection.iterator(); it.hasNext(); index++) { add(index, it.next()); diff --git a/core/src/main/java/com/opensymphony/xwork2/factory/DefaultInterceptorFactory.java b/core/src/main/java/com/opensymphony/xwork2/factory/DefaultInterceptorFactory.java index a1d9ee2ce7..745b26efb4 100644 --- a/core/src/main/java/com/opensymphony/xwork2/factory/DefaultInterceptorFactory.java +++ b/core/src/main/java/com/opensymphony/xwork2/factory/DefaultInterceptorFactory.java @@ -54,7 +54,7 @@ public void setReflectionProvider(ReflectionProvider reflectionProvider) { public Interceptor buildInterceptor(InterceptorConfig interceptorConfig, Map interceptorRefParams) throws ConfigurationException { String interceptorClassName = interceptorConfig.getClassName(); Map thisInterceptorClassParams = interceptorConfig.getParams(); - Map params = (thisInterceptorClassParams == null) ? new HashMap() : new HashMap<>(thisInterceptorClassParams); + Map params = (thisInterceptorClassParams == null) ? new HashMap<>() : new HashMap<>(thisInterceptorClassParams); params.putAll(interceptorRefParams); String message; @@ -70,8 +70,7 @@ public Interceptor buildInterceptor(InterceptorConfig interceptorConfig, Map extraContext) throws Exception { return container.getInstance(UnknownHandler.class, unknownHandlerName); } diff --git a/core/src/main/java/com/opensymphony/xwork2/inject/ConstructionContext.java b/core/src/main/java/com/opensymphony/xwork2/inject/ConstructionContext.java index fcd84e4f80..3e62416bdf 100644 --- a/core/src/main/java/com/opensymphony/xwork2/inject/ConstructionContext.java +++ b/core/src/main/java/com/opensymphony/xwork2/inject/ConstructionContext.java @@ -70,7 +70,7 @@ Object createProxy(Class expectedType) { } if (invocationHandlers == null) { - invocationHandlers = new ArrayList>(); + invocationHandlers = new ArrayList<>(); } DelegatingInvocationHandler invocationHandler = new DelegatingInvocationHandler<>(); diff --git a/core/src/main/java/com/opensymphony/xwork2/inject/ContainerBuilder.java b/core/src/main/java/com/opensymphony/xwork2/inject/ContainerBuilder.java index 77c21cee10..ee523d2c15 100644 --- a/core/src/main/java/com/opensymphony/xwork2/inject/ContainerBuilder.java +++ b/core/src/main/java/com/opensymphony/xwork2/inject/ContainerBuilder.java @@ -53,7 +53,7 @@ public final class ContainerBuilder { boolean allowDuplicates = false; private static final InternalFactory CONTAINER_FACTORY = - new InternalFactory() { + new InternalFactory<>() { public Container create(InternalContext context) { return context.getContainer(); } @@ -65,7 +65,7 @@ public Class type() { }; private static final InternalFactory LOGGER_FACTORY = - new InternalFactory() { + new InternalFactory<>() { public Logger create(InternalContext context) { Member member = context.getExternalContext().getMember(); return member == null ? Logger.getAnonymousLogger() @@ -537,7 +537,7 @@ public > ContainerBuilder constant(String name, E value) { * @return this builder */ private ContainerBuilder constant(final Class type, final String name, final T value) { - InternalFactory factory = new InternalFactory() { + InternalFactory factory = new InternalFactory<>() { public T create(InternalContext ignored) { return value; } @@ -610,23 +610,19 @@ public Container create(boolean loadSingletons) { created = true; final ContainerImpl container = new ContainerImpl(new HashMap<>(factories)); if (loadSingletons) { - container.callInContext(new ContainerImpl.ContextualCallable() { - public Void call(InternalContext context) { - for (InternalFactory factory : singletonFactories) { - factory.create(context); - } - return null; + container.callInContext((ContainerImpl.ContextualCallable) context -> { + for (InternalFactory factory : singletonFactories) { + factory.create(context); } + return null; }); } - container.callInContext(new ContainerImpl.ContextualCallable() { - public Void call(InternalContext context) { - for (InternalFactory factory : earlyInitializableFactories) { - factory.create(context); - } - return null; + container.callInContext((ContainerImpl.ContextualCallable) context -> { + for (InternalFactory factory : earlyInitializableFactories) { + factory.create(context); } + return null; }); container.injectStatics(staticInjections); diff --git a/core/src/main/java/com/opensymphony/xwork2/inject/ContainerImpl.java b/core/src/main/java/com/opensymphony/xwork2/inject/ContainerImpl.java index b11bb4e3a0..c587b441ca 100644 --- a/core/src/main/java/com/opensymphony/xwork2/inject/ContainerImpl.java +++ b/core/src/main/java/com/opensymphony/xwork2/inject/ContainerImpl.java @@ -75,14 +75,14 @@ InternalFactory getFactory(Key key) { * Field and method injectors. */ final Map, List> injectors = - new ReferenceCache, List>() { - @Override - protected List create(Class key) { - List injectors = new ArrayList<>(); - addInjectors(key, injectors); - return injectors; - } - }; + new ReferenceCache<>() { + @Override + protected List create(Class key) { + List injectors = new ArrayList<>(); + addInjectors(key, injectors); + return injectors; + } + }; /** * Recursively adds injectors for fields and methods from the given class to the given list. Injects parent classes @@ -306,7 +306,7 @@ public void inject(InternalContext context, Object o) { } } - Map, ConstructorInjector> constructors = new ReferenceCache, ConstructorInjector>() { + Map, ConstructorInjector> constructors = new ReferenceCache<>() { @Override protected ConstructorInjector create(Class implementation) { return new ConstructorInjector<>(ContainerImpl.this, implementation); diff --git a/core/src/main/java/com/opensymphony/xwork2/inject/ExternalContext.java b/core/src/main/java/com/opensymphony/xwork2/inject/ExternalContext.java index 70c1e99525..07c549f2f6 100644 --- a/core/src/main/java/com/opensymphony/xwork2/inject/ExternalContext.java +++ b/core/src/main/java/com/opensymphony/xwork2/inject/ExternalContext.java @@ -21,7 +21,7 @@ package com.opensymphony.xwork2.inject; import java.lang.reflect.Member; -import java.util.LinkedHashMap; +import java.util.Map; /** * An immutable snapshot of the current context which is safe to @@ -41,34 +41,34 @@ public ExternalContext(Member member, Key key, ContainerImpl container) { this.container = container; } + @Override public Class getType() { return key.getType(); } + @Override public Scope.Strategy getScopeStrategy() { return (Scope.Strategy) container.localScopeStrategy.get(); } + @Override public Container getContainer() { return container; } + @Override public Member getMember() { return member; } + @Override public String getName() { return key.getName(); } @Override public String toString() { - return "Context" + new LinkedHashMap() {{ - put("member", member); - put("type", getType()); - put("name", getName()); - put("container", container); - }}.toString(); + return "Context" + Map.of("member", member,"type", getType(),"name", getName(),"container", container); } static ExternalContext newInstance(Member member, Key key, ContainerImpl container) { diff --git a/core/src/main/java/com/opensymphony/xwork2/inject/InitializableFactory.java b/core/src/main/java/com/opensymphony/xwork2/inject/InitializableFactory.java index 9859937bd6..26191b3d93 100644 --- a/core/src/main/java/com/opensymphony/xwork2/inject/InitializableFactory.java +++ b/core/src/main/java/com/opensymphony/xwork2/inject/InitializableFactory.java @@ -25,7 +25,7 @@ class InitializableFactory implements InternalFactory { private static final Logger LOG = LogManager.getLogger(InitializableFactory.class); - private InternalFactory internalFactory; + private final InternalFactory internalFactory; private InitializableFactory(InternalFactory internalFactory) { this.internalFactory = internalFactory; @@ -42,7 +42,7 @@ public static InternalFactory wrapIfNeeded(InternalFactory internalFac public T create(InternalContext context) { T instance = internalFactory.create(context); if (Initializable.class.isAssignableFrom(instance.getClass())) { - Initializable.class.cast(instance).init(); + ((Initializable) instance).init(); } else { LOG.error("Class {} is not marked as {}!", internalFactory.getClass().getName(), Initializable.class.getName()); } diff --git a/core/src/main/java/com/opensymphony/xwork2/inject/Inject.java b/core/src/main/java/com/opensymphony/xwork2/inject/Inject.java index e97cb48def..c661882c70 100644 --- a/core/src/main/java/com/opensymphony/xwork2/inject/Inject.java +++ b/core/src/main/java/com/opensymphony/xwork2/inject/Inject.java @@ -1,12 +1,12 @@ /** * Copyright (C) 2006 Google Inc. - * + *

* Licensed 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 - * + *

+ * 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. @@ -16,13 +16,16 @@ package com.opensymphony.xwork2.inject; -import static com.opensymphony.xwork2.inject.Container.DEFAULT_NAME; - -import static java.lang.annotation.ElementType.*; import java.lang.annotation.Retention; -import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Target; +import static com.opensymphony.xwork2.inject.Container.DEFAULT_NAME; +import static java.lang.annotation.ElementType.CONSTRUCTOR; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + /** *

Annotates members and parameters which should have their value[s] * injected. @@ -34,14 +37,14 @@ @Retention(RUNTIME) public @interface Inject { - /** - * @return Dependency name. Defaults to {@link Container#DEFAULT_NAME}. - */ - String value() default DEFAULT_NAME; + /** + * @return Dependency name. Defaults to {@link Container#DEFAULT_NAME}. + */ + String value() default DEFAULT_NAME; - /** - * @return Whether or not injection is required. Applicable only to methods and - * fields (not constructors or parameters). - */ - boolean required() default true; + /** + * @return Whether or not injection is required. Applicable only to methods and + * fields (not constructors or parameters). + */ + boolean required() default true; } diff --git a/core/src/main/java/com/opensymphony/xwork2/inject/InternalContext.java b/core/src/main/java/com/opensymphony/xwork2/inject/InternalContext.java index a383721364..8a85f5705e 100644 --- a/core/src/main/java/com/opensymphony/xwork2/inject/InternalContext.java +++ b/core/src/main/java/com/opensymphony/xwork2/inject/InternalContext.java @@ -1,12 +1,12 @@ /** * Copyright (C) 2006 Google Inc. - * + *

* Licensed 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 - * + *

+ * 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. @@ -27,51 +27,51 @@ */ class InternalContext { - final ContainerImpl container; - final Map> constructionContexts = new HashMap>(); - Scope.Strategy scopeStrategy; - ExternalContext externalContext; + final ContainerImpl container; + final Map> constructionContexts = new HashMap<>(); + Scope.Strategy scopeStrategy; + ExternalContext externalContext; + + InternalContext(ContainerImpl container) { + this.container = container; + } - InternalContext(ContainerImpl container) { - this.container = container; - } + public Container getContainer() { + return container; + } - public Container getContainer() { - return container; - } + ContainerImpl getContainerImpl() { + return container; + } - ContainerImpl getContainerImpl() { - return container; - } + Scope.Strategy getScopeStrategy() { + if (scopeStrategy == null) { + scopeStrategy = (Scope.Strategy) container.localScopeStrategy.get(); - Scope.Strategy getScopeStrategy() { - if (scopeStrategy == null) { - scopeStrategy = (Scope.Strategy) container.localScopeStrategy.get(); + if (scopeStrategy == null) { + throw new IllegalStateException("Scope strategy not set. Please call Container.setScopeStrategy()."); + } + } - if (scopeStrategy == null) { - throw new IllegalStateException("Scope strategy not set. Please call Container.setScopeStrategy()."); - } + return scopeStrategy; } - return scopeStrategy; - } - - @SuppressWarnings("unchecked") - ConstructionContext getConstructionContext(Object key) { - ConstructionContext constructionContext = (ConstructionContext) constructionContexts.get(key); - if (constructionContext == null) { - constructionContext = new ConstructionContext(); - constructionContexts.put(key, constructionContext); + @SuppressWarnings("unchecked") + ConstructionContext getConstructionContext(Object key) { + ConstructionContext constructionContext = (ConstructionContext) constructionContexts.get(key); + if (constructionContext == null) { + constructionContext = new ConstructionContext<>(); + constructionContexts.put(key, constructionContext); + } + return constructionContext; } - return constructionContext; - } - @SuppressWarnings("unchecked") - ExternalContext getExternalContext() { - return (ExternalContext) externalContext; - } + @SuppressWarnings("unchecked") + ExternalContext getExternalContext() { + return (ExternalContext) externalContext; + } - void setExternalContext(ExternalContext externalContext) { - this.externalContext = externalContext; - } + void setExternalContext(ExternalContext externalContext) { + this.externalContext = externalContext; + } } diff --git a/core/src/main/java/com/opensymphony/xwork2/inject/Key.java b/core/src/main/java/com/opensymphony/xwork2/inject/Key.java index 1789b23bf4..6aff2a5bdb 100644 --- a/core/src/main/java/com/opensymphony/xwork2/inject/Key.java +++ b/core/src/main/java/com/opensymphony/xwork2/inject/Key.java @@ -60,13 +60,12 @@ public int hashCode() { @Override public boolean equals(Object o) { - if (!(o instanceof Key)) { + if (!(o instanceof Key other)) { return false; } if (o == this) { return true; } - Key other = (Key) o; return name.equals(other.name) && type.equals(other.type); } @@ -76,6 +75,6 @@ public String toString() { } static Key newInstance(Class type, String name) { - return new Key(type, name); + return new Key<>(type, name); } } diff --git a/core/src/main/java/com/opensymphony/xwork2/inject/Scope.java b/core/src/main/java/com/opensymphony/xwork2/inject/Scope.java index 8f74b3a766..3b354cb986 100644 --- a/core/src/main/java/com/opensymphony/xwork2/inject/Scope.java +++ b/core/src/main/java/com/opensymphony/xwork2/inject/Scope.java @@ -43,7 +43,7 @@ InternalFactory scopeFactory(Class type, String name, SINGLETON { @Override InternalFactory scopeFactory(Class type, String name, final InternalFactory factory) { - return new InternalFactory() { + return new InternalFactory<>() { volatile T instance; public T create(InternalContext context) { @@ -84,7 +84,7 @@ public String toString() { THREAD { @Override InternalFactory scopeFactory(Class type, String name, final InternalFactory factory) { - return new InternalFactory() { + return new InternalFactory<>() { final ThreadLocal threadLocal = new ThreadLocal<>(); public T create(final InternalContext context) { @@ -115,7 +115,7 @@ public String toString() { REQUEST { @Override InternalFactory scopeFactory(final Class type, final String name, final InternalFactory factory) { - return new InternalFactory() { + return new InternalFactory<>() { public T create(InternalContext context) { Strategy strategy = context.getScopeStrategy(); try { @@ -145,7 +145,7 @@ public String toString() { SESSION { @Override InternalFactory scopeFactory(final Class type, final String name, final InternalFactory factory) { - return new InternalFactory() { + return new InternalFactory<>() { public T create(InternalContext context) { Strategy strategy = context.getScopeStrategy(); try { @@ -175,7 +175,7 @@ public String toString() { WIZARD { @Override InternalFactory scopeFactory(final Class type, final String name, final InternalFactory factory) { - return new InternalFactory() { + return new InternalFactory<>() { public T create(InternalContext context) { Strategy strategy = context.getScopeStrategy(); try { @@ -205,21 +205,14 @@ Callable toCallable(final InternalContext context, } public static Scope fromString(String scopeStr) { - switch (scopeStr) { - case "prototype": - return Scope.PROTOTYPE; - case "request": - return Scope.REQUEST; - case "session": - return Scope.SESSION; - case "thread": - return Scope.THREAD; - case "wizard": - return Scope.WIZARD; - case "singleton": - default: - return Scope.SINGLETON; - } + return switch (scopeStr) { + case "prototype" -> Scope.PROTOTYPE; + case "request" -> Scope.REQUEST; + case "session" -> Scope.SESSION; + case "thread" -> Scope.THREAD; + case "wizard" -> Scope.WIZARD; + default -> Scope.SINGLETON; + }; } /** diff --git a/core/src/main/java/com/opensymphony/xwork2/inject/Scoped.java b/core/src/main/java/com/opensymphony/xwork2/inject/Scoped.java index f5c272b705..9a72d1aa84 100644 --- a/core/src/main/java/com/opensymphony/xwork2/inject/Scoped.java +++ b/core/src/main/java/com/opensymphony/xwork2/inject/Scoped.java @@ -1,12 +1,12 @@ /** * Copyright (C) 2006 Google Inc. - * + *

* Licensed 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 - * + *

+ * 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. @@ -18,9 +18,10 @@ import java.lang.annotation.ElementType; import java.lang.annotation.Retention; -import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Target; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + /** * Annotates a scoped implementation class. * @@ -30,8 +31,8 @@ @Retention(RUNTIME) public @interface Scoped { - /** - * @return scope - */ - Scope value(); + /** + * @return scope + */ + Scope value(); } diff --git a/core/src/main/java/com/opensymphony/xwork2/inject/util/ReferenceCache.java b/core/src/main/java/com/opensymphony/xwork2/inject/util/ReferenceCache.java index d80b457010..212e735ecb 100644 --- a/core/src/main/java/com/opensymphony/xwork2/inject/util/ReferenceCache.java +++ b/core/src/main/java/com/opensymphony/xwork2/inject/util/ReferenceCache.java @@ -22,7 +22,13 @@ import java.io.IOException; import java.io.ObjectInputStream; -import java.util.concurrent.*; +import java.io.Serial; +import java.util.concurrent.Callable; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.FutureTask; import static com.opensymphony.xwork2.inject.util.ReferenceType.STRONG; @@ -34,6 +40,7 @@ */ public abstract class ReferenceCache extends ReferenceMap { + @Serial private static final long serialVersionUID = 0; transient ConcurrentMap> futures = new ConcurrentHashMap<>(); @@ -177,18 +184,19 @@ public static ReferenceCache of( ReferenceType valueReferenceType, final Function function) { ensureNotNull(function); - return new ReferenceCache(keyReferenceType, valueReferenceType) { + return new ReferenceCache<>(keyReferenceType, valueReferenceType) { @Override protected V create(K key) { return function.apply(key); } + @Serial private static final long serialVersionUID = 0; }; } - private void readObject(ObjectInputStream in) throws IOException, - ClassNotFoundException { + @Serial + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); this.futures = new ConcurrentHashMap<>(); this.localFuture = new ThreadLocal<>(); diff --git a/core/src/main/java/com/opensymphony/xwork2/inject/util/ReferenceMap.java b/core/src/main/java/com/opensymphony/xwork2/inject/util/ReferenceMap.java index 755b6fc56c..ce37624254 100644 --- a/core/src/main/java/com/opensymphony/xwork2/inject/util/ReferenceMap.java +++ b/core/src/main/java/com/opensymphony/xwork2/inject/util/ReferenceMap.java @@ -23,9 +23,15 @@ import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; +import java.io.Serial; import java.io.Serializable; import java.lang.ref.Reference; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -58,6 +64,7 @@ @SuppressWarnings("unchecked") public class ReferenceMap implements Map, Serializable { + @Serial private static final long serialVersionUID = 0; transient ConcurrentMap delegate; @@ -87,7 +94,7 @@ public ReferenceMap(ReferenceType keyReferenceType, V internalGet(K key) { Object valueReference = delegate.get(makeKeyReferenceAware(key)); - return valueReference == null ? null : (V) dereferenceValue(valueReference); + return valueReference == null ? null : dereferenceValue(valueReference); } public V get(final Object key) { @@ -99,7 +106,7 @@ V execute(Strategy strategy, K key, V value) { ensureNotNull(key, value); Object keyReference = referenceKey(key); Object valueReference = strategy.execute(this, keyReference, referenceValue(keyReference, value)); - return valueReference == null ? null : (V) dereferenceValue(valueReference); + return valueReference == null ? null : dereferenceValue(valueReference); } public V put(K key, V value) { @@ -110,7 +117,7 @@ public V remove(Object key) { ensureNotNull(key); Object referenceAwareKey = makeKeyReferenceAware(key); Object valueReference = delegate.remove(referenceAwareKey); - return valueReference == null ? null : (V) dereferenceValue(valueReference); + return valueReference == null ? null : dereferenceValue(valueReference); } public int size() { @@ -218,16 +225,12 @@ Entry dereferenceEntry(Map.Entry entry) { * Creates a reference for a key. */ Object referenceKey(K key) { - switch (keyReferenceType) { - case STRONG: - return key; - case SOFT: - return new SoftKeyReference(key); - case WEAK: - return new WeakKeyReference(key); - default: - throw new AssertionError(); - } + return switch (keyReferenceType) { + case STRONG -> key; + case SOFT -> new SoftKeyReference(key); + case WEAK -> new WeakKeyReference(key); + default -> throw new AssertionError(); + }; } /** @@ -255,16 +258,12 @@ Object dereference(ReferenceType referenceType, Object reference) { * Creates a reference for a value. */ Object referenceValue(Object keyReference, Object value) { - switch (valueReferenceType) { - case STRONG: - return value; - case SOFT: - return new SoftValueReference(keyReference, value); - case WEAK: - return new WeakValueReference(keyReference, value); - default: - throw new AssertionError(); - } + return switch (valueReferenceType) { + case STRONG -> value; + case SOFT -> new SoftValueReference(keyReference, value); + case WEAK -> new WeakValueReference(keyReference, value); + default -> throw new AssertionError(); + }; } /** @@ -476,7 +475,7 @@ public boolean equals(Object obj) { } protected interface Strategy { - public Object execute(ReferenceMap map, Object keyReference, Object valueReference); + Object execute(ReferenceMap map, Object keyReference, Object valueReference); } protected Strategy putStrategy() { @@ -508,7 +507,7 @@ public Object execute(ReferenceMap map, Object keyReference, Object valueReferen public Object execute(ReferenceMap map, Object keyReference, Object valueReference) { return map.delegate.putIfAbsent(keyReference, valueReference); } - }; + } } private static PutStrategy defaultPutStrategy; @@ -575,6 +574,7 @@ static void ensureNotNull(Object... array) { } } + @Serial private void writeObject(ObjectOutputStream out) throws IOException { out.defaultWriteObject(); out.writeInt(size()); @@ -591,11 +591,11 @@ private void writeObject(ObjectOutputStream out) throws IOException { out.writeObject(null); } - private void readObject(ObjectInputStream in) throws IOException, - ClassNotFoundException { + @Serial + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); int size = in.readInt(); - this.delegate = new ConcurrentHashMap(size); + this.delegate = new ConcurrentHashMap<>(size); while (true) { K key = (K) in.readObject(); if (key == null) { diff --git a/core/src/main/java/com/opensymphony/xwork2/inject/util/ReferenceType.java b/core/src/main/java/com/opensymphony/xwork2/inject/util/ReferenceType.java index 474b10f33c..b9662732ce 100644 --- a/core/src/main/java/com/opensymphony/xwork2/inject/util/ReferenceType.java +++ b/core/src/main/java/com/opensymphony/xwork2/inject/util/ReferenceType.java @@ -51,5 +51,5 @@ public enum ReferenceType { * * @see java.lang.ref.PhantomReference */ - PHANTOM; + PHANTOM } diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/AbstractInterceptor.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/AbstractInterceptor.java index 21e459c291..13bf646d47 100644 --- a/core/src/main/java/com/opensymphony/xwork2/interceptor/AbstractInterceptor.java +++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/AbstractInterceptor.java @@ -30,18 +30,21 @@ public abstract class AbstractInterceptor implements ConditionalInterceptor { /** * Does nothing */ + @Override public void init() { } /** * Does nothing */ + @Override public void destroy() { } /** * Override to handle interception */ + @Override public abstract String intercept(ActionInvocation invocation) throws Exception; /** diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/AliasInterceptor.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/AliasInterceptor.java index c57df3dabf..28109cbf9a 100644 --- a/core/src/main/java/com/opensymphony/xwork2/interceptor/AliasInterceptor.java +++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/AliasInterceptor.java @@ -160,7 +160,7 @@ public void setAliasesKey(String aliasesKey) { ValueStack stack = ac.getValueStack(); Object obj = stack.findValue(aliasExpression); - if (obj instanceof Map) { + if (obj instanceof Map aliases) { //get secure stack ValueStack newStack = valueStackFactory.createValueStack(stack); boolean clearableStack = newStack instanceof ClearableValueStack; @@ -178,7 +178,6 @@ public void setAliasesKey(String aliasesKey) { } // override - Map aliases = (Map) obj; for (Object o : aliases.entrySet()) { Map.Entry entry = (Map.Entry) o; String name = entry.getKey().toString(); diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/ChainingInterceptor.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/ChainingInterceptor.java index 31b0075a35..7e7d132f6e 100644 --- a/core/src/main/java/com/opensymphony/xwork2/interceptor/ChainingInterceptor.java +++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/ChainingInterceptor.java @@ -23,16 +23,21 @@ import com.opensymphony.xwork2.Result; import com.opensymphony.xwork2.Unchainable; import com.opensymphony.xwork2.inject.Inject; -import com.opensymphony.xwork2.util.ProxyUtil; import com.opensymphony.xwork2.util.CompoundRoot; +import com.opensymphony.xwork2.util.ProxyUtil; import com.opensymphony.xwork2.util.TextParseUtil; import com.opensymphony.xwork2.util.ValueStack; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; import com.opensymphony.xwork2.util.reflection.ReflectionProvider; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.apache.struts2.StrutsConstants; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; /** @@ -180,7 +185,7 @@ private Collection prepareExcludes() { Collection localExcludes = excludes; if (!copyErrors || !copyMessages ||!copyFieldErrors) { if (localExcludes == null) { - localExcludes = new HashSet(); + localExcludes = new HashSet<>(); if (!copyErrors) { localExcludes.add(ACTION_ERRORS); } diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/ConversionErrorInterceptor.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/ConversionErrorInterceptor.java index ee8e392815..a30d81a004 100644 --- a/core/src/main/java/com/opensymphony/xwork2/interceptor/ConversionErrorInterceptor.java +++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/ConversionErrorInterceptor.java @@ -41,13 +41,13 @@ * display the original string ("abc") again rather than the int value (likely 0, which would make very little sense to * the user). *

- * + * *

* Note: Since 2.5.2, this interceptor extends {@link MethodFilterInterceptor}, therefore being * able to deal with excludeMethods / includeMethods parameters. See [Workflow Interceptor] * (class {@link DefaultWorkflowInterceptor}) for documentation and examples on how to use this feature. *

- * + * * * *

Interceptor parameters:

@@ -114,8 +114,7 @@ public String doIntercept(ActionInvocation invocation) throws Exception { String message = XWorkConverter.getConversionErrorMessage(propertyName, conversionData.getToClass(), stack); Object action = invocation.getAction(); - if (action instanceof ValidationAware) { - ValidationAware va = (ValidationAware) action; + if (action instanceof ValidationAware va) { va.addFieldError(propertyName, message); } @@ -130,13 +129,11 @@ public String doIntercept(ActionInvocation invocation) throws Exception { if (fakie != null) { // if there were some errors, put the original (fake) values in place right before the result stack.getContext().put(ORIGINAL_PROPERTY_OVERRIDE, fakie); - invocation.addPreResultListener(new PreResultListener() { - public void beforeResult(ActionInvocation invocation, String resultCode) { - Map fakie = (Map) invocation.getInvocationContext().get(ORIGINAL_PROPERTY_OVERRIDE); + invocation.addPreResultListener((invocation1, resultCode) -> { + var fakie1 = (Map) invocation1.getInvocationContext().get(ORIGINAL_PROPERTY_OVERRIDE); - if (fakie != null) { - invocation.getStack().setExprOverrides(fakie); - } + if (fakie1 != null) { + invocation1.getStack().setExprOverrides(fakie1); } }); } diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/DefaultWorkflowInterceptor.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/DefaultWorkflowInterceptor.java index d2cbd0b780..118811a59a 100644 --- a/core/src/main/java/com/opensymphony/xwork2/interceptor/DefaultWorkflowInterceptor.java +++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/DefaultWorkflowInterceptor.java @@ -26,10 +26,12 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import java.io.Serial; + /** * *

- * An interceptor that makes sure there are not validation, conversion or action errors before allowing the interceptor chain to continue. + * An interceptor that makes sure there are not validation, conversion or action errors before allowing the interceptor chain to continue. * If a single FieldError or ActionError (including the ones replicated by the Message Store Interceptor in a redirection) is found, the INPUT result will be triggered. * This interceptor does not perform any validation. *

@@ -132,6 +134,7 @@ */ public class DefaultWorkflowInterceptor extends MethodFilterInterceptor { + @Serial private static final long serialVersionUID = 7563014655616490865L; private static final Logger LOG = LogManager.getLogger(DefaultWorkflowInterceptor.class); @@ -161,8 +164,7 @@ public void setInputResultName(String inputResultName) { protected String doIntercept(ActionInvocation invocation) throws Exception { Object action = invocation.getAction(); - if (action instanceof ValidationAware) { - ValidationAware validationAwareAction = (ValidationAware) action; + if (action instanceof ValidationAware validationAwareAction) { if (validationAwareAction.hasErrors()) { LOG.debug("Errors on action [{}], returning result name [{}]", validationAwareAction, inputResultName); diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/ExceptionHolder.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/ExceptionHolder.java index 9ba05ea0cf..ff813dbca5 100644 --- a/core/src/main/java/com/opensymphony/xwork2/interceptor/ExceptionHolder.java +++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/ExceptionHolder.java @@ -20,8 +20,9 @@ import java.io.IOException; import java.io.PrintWriter; -import java.io.StringWriter; +import java.io.Serial; import java.io.Serializable; +import java.io.StringWriter; /** * @@ -35,8 +36,9 @@ */ public class ExceptionHolder implements Serializable { + @Serial private static final long serialVersionUID = 1L; - private Exception exception; + private final Exception exception; /** * Holds the given exception @@ -76,5 +78,5 @@ public String getExceptionStack() { return exceptionStack; } - + } diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/ExceptionMappingInterceptor.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/ExceptionMappingInterceptor.java index e60550ca69..db6dadec93 100644 --- a/core/src/main/java/com/opensymphony/xwork2/interceptor/ExceptionMappingInterceptor.java +++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/ExceptionMappingInterceptor.java @@ -20,8 +20,8 @@ import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.config.entities.ExceptionMappingConfig; -import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.apache.struts2.dispatcher.HttpParameters; import java.util.List; @@ -273,12 +273,11 @@ protected ExceptionMappingConfig findMappingFromExceptions(List= 0 && depth < deepest) { deepest = depth; - config = exceptionMappingConfig; + config = exceptionMapping; } } } diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/LoggingInterceptor.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/LoggingInterceptor.java index 6ba498b3cb..271ed05bed 100644 --- a/core/src/main/java/com/opensymphony/xwork2/interceptor/LoggingInterceptor.java +++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/LoggingInterceptor.java @@ -78,7 +78,7 @@ private void logMessage(ActionInvocation invocation, String baseMessage) { StringBuilder message = new StringBuilder(baseMessage); String namespace = invocation.getProxy().getNamespace(); - if ((namespace != null) && (namespace.trim().length() > 0)) { + if (namespace != null && !namespace.trim().isEmpty()) { message.append(namespace).append("/"); } diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/MethodFilterInterceptorUtil.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/MethodFilterInterceptorUtil.java index beacb87844..ac5acee652 100644 --- a/core/src/main/java/com/opensymphony/xwork2/interceptor/MethodFilterInterceptorUtil.java +++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/MethodFilterInterceptorUtil.java @@ -24,18 +24,20 @@ import java.util.HashMap; import java.util.Set; +import static java.util.Objects.requireNonNullElse; + /** - * Utility class contains common methods used by + * Utility class contains common methods used by * {@link com.opensymphony.xwork2.interceptor.MethodFilterInterceptor}. - * + * * @author tm_jee */ public class MethodFilterInterceptorUtil { /** * Static method to decide if the specified method should be - * apply (not filtered) depending on the set of excludeMethods and - * includeMethods. + * apply (not filtered) depending on the set of excludeMethods and + * includeMethods. * *
    *
  • @@ -50,7 +52,7 @@ public class MethodFilterInterceptorUtil { * @return true if the method should be applied. */ public static boolean applyMethod(Set excludeMethods, Set includeMethods, String method) { - + // quick check to see if any actual pattern matching is needed boolean needsPatternMatch = false; for (String includeMethod : includeMethods) { @@ -59,7 +61,7 @@ public static boolean applyMethod(Set excludeMethods, Set includ break; } } - + for (String excludeMethod : excludeMethods) { if (!"*".equals(excludeMethod) && excludeMethod.contains("*")) { needsPatternMatch = true; @@ -67,25 +69,19 @@ public static boolean applyMethod(Set excludeMethods, Set includ } } - // this section will try to honor the original logic, while + // this section will try to honor the original logic, while // still allowing for wildcards later - if (!needsPatternMatch && (includeMethods.contains("*") || includeMethods.size() == 0) ) { - if (excludeMethods != null - && excludeMethods.contains(method) - && !includeMethods.contains(method) ) { + if (!needsPatternMatch && (includeMethods.contains("*") || includeMethods.isEmpty()) ) { + if (excludeMethods.contains(method) && !includeMethods.contains(method)) { return false; } } - + // test the methods using pattern matching WildcardHelper wildcard = new WildcardHelper(); String methodCopy ; - if (method == null ) { // no method specified - methodCopy = ""; - } - else { - methodCopy = new String(method); - } + // no method specified + methodCopy = requireNonNullElse(method, ""); for (String pattern : includeMethods) { if (pattern.contains("*")) { int[] compiledPattern = wildcard.compilePattern(pattern); @@ -105,7 +101,7 @@ public static boolean applyMethod(Set excludeMethods, Set includ return false; } - // CHECK ME: Previous implementation used include method + // CHECK ME: Previous implementation used include method for ( String pattern : excludeMethods) { if (pattern.contains("*")) { int[] compiledPattern = wildcard.compilePattern(pattern); @@ -113,26 +109,26 @@ public static boolean applyMethod(Set excludeMethods, Set includ boolean matches = wildcard.match(matchedPatterns, methodCopy, compiledPattern); if (matches) { // if found, and wasn't included earlier, don't run it - return false; + return false; } } else { if (pattern.equals(methodCopy)) { // if found, and wasn't included earlier, don't run it - return false; + return false; } } } - + // default fall-back from before changes - return includeMethods.size() == 0 || includeMethods.contains(method) || includeMethods.contains("*"); + return includeMethods.isEmpty() || includeMethods.contains(method) || includeMethods.contains("*"); } - + /** * Same as {@link #applyMethod(Set, Set, String)}, except that excludeMethods * and includeMethods are supplied as comma separated string. - * + * * @param excludeMethods comma seperated string of methods to exclude. * @param includeMethods comma seperated string of methods to include. * @param method the specified method to check @@ -141,7 +137,7 @@ public static boolean applyMethod(Set excludeMethods, Set includ public static boolean applyMethod(String excludeMethods, String includeMethods, String method) { Set includeMethodsSet = TextParseUtil.commaDelimitedStringToSet(includeMethods == null? "" : includeMethods); Set excludeMethodsSet = TextParseUtil.commaDelimitedStringToSet(excludeMethods == null? "" : excludeMethods); - + return applyMethod(excludeMethodsSet, includeMethodsSet, method); } diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/ModelDrivenInterceptor.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/ModelDrivenInterceptor.java index f1919a8c9e..d8c4a31439 100644 --- a/core/src/main/java/com/opensymphony/xwork2/interceptor/ModelDrivenInterceptor.java +++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/ModelDrivenInterceptor.java @@ -88,8 +88,7 @@ public void setRefreshModelBeforeResult(boolean val) { public String intercept(ActionInvocation invocation) throws Exception { Object action = invocation.getAction(); - if (action instanceof ModelDriven) { - ModelDriven modelDriven = (ModelDriven) action; + if (action instanceof ModelDriven modelDriven) { ValueStack stack = invocation.getStack(); Object model = modelDriven.getModel(); if (model != null) { @@ -106,7 +105,7 @@ public String intercept(ActionInvocation invocation) throws Exception { * Refreshes the model instance on the value stack, if it has changed */ protected static class RefreshModelBeforeResult implements PreResultListener { - private Object originalModel; + private final Object originalModel; protected ModelDriven action; diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/PrefixMethodInvocationUtil.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/PrefixMethodInvocationUtil.java index 040080824e..bd0609370e 100644 --- a/core/src/main/java/com/opensymphony/xwork2/interceptor/PrefixMethodInvocationUtil.java +++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/PrefixMethodInvocationUtil.java @@ -19,8 +19,8 @@ package com.opensymphony.xwork2.interceptor; import com.opensymphony.xwork2.ActionInvocation; -import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -28,7 +28,7 @@ /** *

    * A utility class for invoking prefixed methods in action class. - * + * * Interceptors that made use of this class are: *

    *
      @@ -37,7 +37,7 @@ *
    * * * - * + * * In DefaultWorkflowInterceptor *

    applies only when action implements {@link com.opensymphony.xwork2.Validateable}

    *
      @@ -45,12 +45,12 @@ *
    1. else if the action class have validateDo{MethodName}(), it will be invoked
    2. *
    3. no matter if 1] or 2] is performed, if alwaysInvokeValidate property of the interceptor is "true" (which is by default "true"), validate() will be invoked.
    4. *
    - * + * * - * - * + * + * * - * + * * In PrepareInterceptor *

    Applies only when action implements Preparable

    *
      @@ -58,14 +58,14 @@ *
    1. else if the action class have prepareDo(MethodName()}(), it will be invoked
    2. *
    3. no matter if 1] or 2] is performed, if alwaysinvokePrepare property of the interceptor is "true" (which is by default "true"), prepare() will be invoked.
    4. *
    - * + * * - * + * * @author Philip Luppens * @author tm_jee */ public class PrefixMethodInvocationUtil { - + private static final Logger LOG = LogManager.getLogger(PrefixMethodInvocationUtil.class); private static final String DEFAULT_INVOCATION_METHODNAME = "execute"; @@ -76,7 +76,7 @@ public class PrefixMethodInvocationUtil { *

    * This method will prefix actionInvocation's ActionProxy's * method with prefixes before invoking the prefixed method. - * Order of the prefixes is important, as this method will return once + * Order of the prefixes is important, as this method will return once * a prefixed method is found in the action class. *

    * @@ -89,7 +89,7 @@ public class PrefixMethodInvocationUtil { * * *

    - * Assuming actionInvocation.getProxy(),getMethod() returns "submit", + * Assuming actionInvocation.getProxy(),getMethod() returns "submit", * the order of invocation would be as follows:- *

    * @@ -99,12 +99,12 @@ public class PrefixMethodInvocationUtil { * * *

    - * If prepareSubmit() exists, it will be invoked and this method - * will return, prepareDoSubmit() will NOT be invoked. + * If prepareSubmit() exists, it will be invoked and this method + * will return, prepareDoSubmit() will NOT be invoked. *

    * *

    - * On the other hand, if prepareDoSubmit() does not exists, and + * On the other hand, if prepareDoSubmit() does not exists, and * prepareDoSubmit() exists, it will be invoked. *

    * @@ -119,29 +119,29 @@ public class PrefixMethodInvocationUtil { */ public static void invokePrefixMethod(ActionInvocation actionInvocation, String[] prefixes) throws InvocationTargetException, IllegalAccessException { Object action = actionInvocation.getAction(); - + String methodName = actionInvocation.getProxy().getMethod(); - + if (methodName == null) { - // if null returns (possible according to the docs), use the default execute + // if null returns (possible according to the docs), use the default execute methodName = DEFAULT_INVOCATION_METHODNAME; } - + Method method = getPrefixedMethod(prefixes, methodName, action); if (method != null) { - method.invoke(action, new Object[0]); + method.invoke(action); } } - - + + /** - * This method returns a {@link Method} in action. The method + * This method returns a {@link Method} in action. The method * returned is found by searching for method in action whose method name * is equals to the result of appending each prefixes * to methodName. Only the first method found will be returned, hence * the order of prefixes is important. If none is found this method * will return null. - * + * * @param prefixes the prefixes to prefix the methodName * @param methodName the method name to be prefixed with prefixes * @param action the action class of which the prefixed method is to be search for. @@ -162,7 +162,7 @@ public static Method getPrefixedMethod(String[] prefixes, String methodName, Obj } return null; } - + /** *

    * This method capitalized the first character of methodName. diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/PrepareInterceptor.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/PrepareInterceptor.java index 4516d760c6..78b3b9c952 100644 --- a/core/src/main/java/com/opensymphony/xwork2/interceptor/PrepareInterceptor.java +++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/PrepareInterceptor.java @@ -20,9 +20,8 @@ import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.Preparable; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; +import java.io.Serial; import java.lang.reflect.InvocationTargetException; /** @@ -101,6 +100,7 @@ */ public class PrepareInterceptor extends MethodFilterInterceptor { + @Serial private static final long serialVersionUID = -5216969014510719786L; private final static String PREPARE_PREFIX = "prepare"; diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/ScopedModelDrivenInterceptor.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/ScopedModelDrivenInterceptor.java index 22da179d46..c6daee0281 100644 --- a/core/src/main/java/com/opensymphony/xwork2/interceptor/ScopedModelDrivenInterceptor.java +++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/ScopedModelDrivenInterceptor.java @@ -35,7 +35,7 @@ * *

    This interceptor only activates on actions that implement the {@link ScopedModelDriven} interface. If * detected, it will retrieve the model class from the configured scope, then provide it to the Action.

    - * + * * * *

    Interceptor parameters:

    @@ -45,7 +45,7 @@ *
      * *
    • className - The model class name. Defaults to the class name of the object returned by the getModel() method.
    • - * + * *
    • name - The key to use when storing or retrieving the instance in a scope. Defaults to the model * class name.
    • * @@ -66,42 +66,42 @@ * *
        * 
      - * 
      + *
        * <-- Basic usage -->
        * <interceptor name="scopedModelDriven" class="com.opensymphony.interceptor.ScopedModelDrivenInterceptor" />
      - * 
      + *
        * <-- Using all available parameters -->
        * <interceptor name="gangsterForm" class="com.opensymphony.interceptor.ScopedModelDrivenInterceptor">
        *      <param name="scope">session</param>
        *      <param name="name">gangsterForm</param>
        *      <param name="className">com.opensymphony.example.GangsterForm</param>
        *  </interceptor>
      - * 
      + *
        * 
        * 
      */ public class ScopedModelDrivenInterceptor extends AbstractInterceptor { private static final Class[] EMPTY_CLASS_ARRAY = new Class[0]; - + private static final String GET_MODEL = "getModel"; private String scope; private String name; private String className; private ObjectFactory objectFactory; - + @Inject public void setObjectFactory(ObjectFactory factory) { this.objectFactory = factory; } - + protected Object resolveModel(ObjectFactory factory, ActionContext actionContext, String modelClassName, String modelScope, String modelName) throws Exception { Object model; Map scopeMap = actionContext.getContextMap(); if ("session".equals(modelScope)) { scopeMap = actionContext.getSession(); } - + model = scopeMap.get(modelName); if (model == null) { model = factory.buildBean(modelClassName, null); @@ -114,12 +114,11 @@ protected Object resolveModel(ObjectFactory factory, ActionContext actionContext public String intercept(ActionInvocation invocation) throws Exception { Object action = invocation.getAction(); - if (action instanceof ScopedModelDriven) { - ScopedModelDriven modelDriven = (ScopedModelDriven) action; + if (action instanceof ScopedModelDriven modelDriven) { if (modelDriven.getModel() == null) { ActionContext ctx = ActionContext.getContext(); ActionConfig config = invocation.getProxy().getConfig(); - + String cName = className; if (cName == null) { try { @@ -127,7 +126,7 @@ public String intercept(ActionInvocation invocation) throws Exception { Class cls = method.getReturnType(); cName = cls.getName(); } catch (NoSuchMethodException e) { - throw new StrutsException("The " + GET_MODEL + "() is not defined in action " + action.getClass() + "", config); + throw new StrutsException("The " + GET_MODEL + "() is not defined in action " + action.getClass(), config); } } String modelName = name; @@ -161,5 +160,5 @@ public void setName(String name) { */ public void setScope(String scope) { this.scope = scope; - } + } } diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/WithLazyParams.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/WithLazyParams.java index 3e111d69c8..750d23af1d 100644 --- a/core/src/main/java/com/opensymphony/xwork2/interceptor/WithLazyParams.java +++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/WithLazyParams.java @@ -47,11 +47,8 @@ class LazyParamInjector { private final TextParseUtil.ParsedValueEvaluator valueEvaluator; public LazyParamInjector(final ValueStack valueStack) { - valueEvaluator = new TextParseUtil.ParsedValueEvaluator() { - public Object evaluate(String parsedValue) { - return valueStack.findValue(parsedValue); // no asType !!! - } - }; + // no asType !!! + valueEvaluator = valueStack::findValue; } @Inject diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/annotations/AnnotationWorkflowInterceptor.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/annotations/AnnotationWorkflowInterceptor.java index 39b1252362..6f0a936999 100644 --- a/core/src/main/java/com/opensymphony/xwork2/interceptor/annotations/AnnotationWorkflowInterceptor.java +++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/annotations/AnnotationWorkflowInterceptor.java @@ -26,8 +26,6 @@ import java.lang.reflect.Method; import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; import java.util.List; /** @@ -117,15 +115,11 @@ public String intercept(ActionInvocation invocation) throws Exception { invocation.addPreResultListener(this); List methods = new ArrayList<>(MethodUtils.getMethodsListWithAnnotation(action.getClass(), Before.class, true, true)); - if (methods.size() > 0) { + if (!methods.isEmpty()) { // methods are only sorted by priority - Collections.sort(methods, new Comparator() { - public int compare(Method method1, Method method2) { - return comparePriorities(MethodUtils.getAnnotation(method1, Before.class, true, - true).priority(), MethodUtils.getAnnotation(method2, Before.class, true, - true).priority()); - } - }); + methods.sort((method1, method2) -> comparePriorities( + MethodUtils.getAnnotation(method1, Before.class, true, true).priority(), + MethodUtils.getAnnotation(method2, Before.class, true, true).priority())); for (Method m : methods) { final String resultCode = (String) MethodUtils.invokeMethod(action, true, m.getName()); if (resultCode != null) { @@ -138,18 +132,13 @@ public int compare(Method method1, Method method2) { String invocationResult = invocation.invoke(); // invoke any @After methods - methods = new ArrayList(MethodUtils.getMethodsListWithAnnotation(action.getClass(), After.class, - true, true)); + methods = new ArrayList<>(MethodUtils.getMethodsListWithAnnotation(action.getClass(), After.class, true, true)); - if (methods.size() > 0) { + if (!methods.isEmpty()) { // methods are only sorted by priority - Collections.sort(methods, new Comparator() { - public int compare(Method method1, Method method2) { - return comparePriorities(MethodUtils.getAnnotation(method1, After.class, true, - true).priority(), MethodUtils.getAnnotation(method2, After.class, true, - true).priority()); - } - }); + methods.sort((method1, method2) -> comparePriorities( + MethodUtils.getAnnotation(method1, After.class, true, true).priority(), + MethodUtils.getAnnotation(method2, After.class, true, true).priority())); for (Method m : methods) { MethodUtils.invokeMethod(action, true, m.getName()); } @@ -159,13 +148,7 @@ public int compare(Method method1, Method method2) { } protected static int comparePriorities(int val1, int val2) { - if (val2 < val1) { - return -1; - } else if (val2 > val1) { - return 1; - } else { - return 0; - } + return Integer.compare(val2, val1); } /** @@ -175,18 +158,14 @@ protected static int comparePriorities(int val1, int val2) { */ public void beforeResult(ActionInvocation invocation, String resultCode) { Object action = invocation.getAction(); - List methods = new ArrayList(MethodUtils.getMethodsListWithAnnotation(action.getClass(), + List methods = new ArrayList<>(MethodUtils.getMethodsListWithAnnotation(action.getClass(), BeforeResult.class, true, true)); - if (methods.size() > 0) { + if (!methods.isEmpty()) { // methods are only sorted by priority - Collections.sort(methods, new Comparator() { - public int compare(Method method1, Method method2) { - return comparePriorities(MethodUtils.getAnnotation(method1, BeforeResult.class, true, - true).priority(), MethodUtils.getAnnotation(method2, BeforeResult.class, - true, true).priority()); - } - }); + methods.sort((method1, method2) -> comparePriorities( + MethodUtils.getAnnotation(method1, BeforeResult.class, true, true).priority(), + MethodUtils.getAnnotation(method2, BeforeResult.class, true, true).priority())); for (Method m : methods) { try { MethodUtils.invokeMethod(action, true, m.getName()); diff --git a/core/src/main/java/com/opensymphony/xwork2/ognl/BeanInfoCacheFactory.java b/core/src/main/java/com/opensymphony/xwork2/ognl/BeanInfoCacheFactory.java index 3ea2100017..58d03f5a14 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ognl/BeanInfoCacheFactory.java +++ b/core/src/main/java/com/opensymphony/xwork2/ognl/BeanInfoCacheFactory.java @@ -18,6 +18,6 @@ /** * A proxy interface to be used with Struts DI mechanism */ -public interface BeanInfoCacheFactory extends OgnlCacheFactory { +public interface BeanInfoCacheFactory extends OgnlCacheFactory { } diff --git a/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlLRUCache.java b/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlLRUCache.java index e324418ceb..9de52f686d 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlLRUCache.java +++ b/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlLRUCache.java @@ -41,7 +41,7 @@ public class OgnlLRUCache implements OgnlCache { public OgnlLRUCache(int evictionLimit, int initialCapacity, float loadFactor) { cacheEvictionLimit = new AtomicInteger(evictionLimit); // Access-order mode selected (order mode true in LinkedHashMap constructor). - ognlLRUCache = Collections.synchronizedMap(new LinkedHashMap(initialCapacity, loadFactor, true) { + ognlLRUCache = Collections.synchronizedMap(new LinkedHashMap<>(initialCapacity, loadFactor, true) { @Override protected boolean removeEldestEntry(Map.Entry eldest) { return size() > cacheEvictionLimit.get(); diff --git a/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlNullHandlerWrapper.java b/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlNullHandlerWrapper.java index 9b24261c82..d05d4636db 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlNullHandlerWrapper.java +++ b/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlNullHandlerWrapper.java @@ -25,16 +25,18 @@ public class OgnlNullHandlerWrapper implements ognl.NullHandler { private final NullHandler wrapped; - + public OgnlNullHandlerWrapper(NullHandler target) { this.wrapped = target; } - + + @Override public Object nullMethodResult(Map context, Object target, String methodName, Object[] args) { return wrapped.nullMethodResult(context, target, methodName, args); } + @Override public Object nullPropertyValue(Map context, Object target, Object property) { return wrapped.nullPropertyValue(context, target, property); } diff --git a/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlReflectionContextFactory.java b/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlReflectionContextFactory.java index ec3db9f9af..b1821ccf5f 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlReflectionContextFactory.java +++ b/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlReflectionContextFactory.java @@ -25,6 +25,7 @@ public class OgnlReflectionContextFactory implements ReflectionContextFactory { + @Override public Map createDefaultContext(Object root) { return Ognl.createDefaultContext(root); } diff --git a/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlReflectionProvider.java b/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlReflectionProvider.java index 1dbc8c67e5..23dec6343e 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlReflectionProvider.java +++ b/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlReflectionProvider.java @@ -40,10 +40,12 @@ public void setOgnlUtil(OgnlUtil ognlUtil) { this.ognlUtil = ognlUtil; } + @Override public Field getField(Class inClass, String name) { return OgnlRuntime.getField(inClass, name); } + @Override public Method getGetMethod(Class targetClass, String propertyName) throws IntrospectionException, ReflectionException { try { @@ -53,6 +55,7 @@ public Method getGetMethod(Class targetClass, String propertyName) } } + @Override public Method getSetMethod(Class targetClass, String propertyName) throws IntrospectionException, ReflectionException { try { @@ -62,18 +65,22 @@ public Method getSetMethod(Class targetClass, String propertyName) } } + @Override public void setProperties(Map props, Object o, Map context) { ognlUtil.setProperties(props, o, context); } + @Override public void setProperties(Map props, Object o, Map context, boolean throwPropertyExceptions) throws ReflectionException{ ognlUtil.setProperties(props, o, context, throwPropertyExceptions); } + @Override public void setProperties(Map properties, Object o) { ognlUtil.setProperties(properties, o); } + @Override public PropertyDescriptor getPropertyDescriptor(Class targetClass, String propertyName) throws IntrospectionException, ReflectionException { @@ -84,16 +91,19 @@ public PropertyDescriptor getPropertyDescriptor(Class targetClass, } } + @Override public void copy(Object from, Object to, Map context, Collection exclusions, Collection inclusions) { copy(from, to, context, exclusions, inclusions, null); } + @Override public void copy(Object from, Object to, Map context, Collection exclusions, Collection inclusions, Class editable) { ognlUtil.copy(from, to, context, exclusions, inclusions, editable); } + @Override public Object getRealTarget(String property, Map context, Object root) throws ReflectionException { try { @@ -103,14 +113,17 @@ public Object getRealTarget(String property, Map context, Object } } + @Override public void setProperty(String name, Object value, Object o, Map context) { ognlUtil.setProperty(name, value, o, context); } + @Override public void setProperty(String name, Object value, Object o, Map context, boolean throwPropertyExceptions) { ognlUtil.setProperty(name, value, o, context, throwPropertyExceptions); } + @Override public Map getBeanMap(Object source) throws IntrospectionException, ReflectionException { try { @@ -120,6 +133,7 @@ public Map getBeanMap(Object source) throws IntrospectionException, } } + @Override public Object getValue(String expression, Map context, Object root) throws ReflectionException { try { @@ -129,6 +143,7 @@ public Object getValue(String expression, Map context, Object ro } } + @Override public void setValue(String expression, Map context, Object root, Object value) throws ReflectionException { try { @@ -138,8 +153,8 @@ public void setValue(String expression, Map context, Object root } } - public PropertyDescriptor[] getPropertyDescriptors(Object source) - throws IntrospectionException { + @Override + public PropertyDescriptor[] getPropertyDescriptors(Object source) throws IntrospectionException { return ognlUtil.getPropertyDescriptors(source); } diff --git a/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlTypeConverterWrapper.java b/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlTypeConverterWrapper.java index c2783b9698..65e614afe8 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlTypeConverterWrapper.java +++ b/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlTypeConverterWrapper.java @@ -36,12 +36,12 @@ public OgnlTypeConverterWrapper(TypeConverter converter) { } this.typeConverter = converter; } - - public Object convertValue(Map context, Object target, Member member, - String propertyName, Object value, Class toType) { + + @Override + public Object convertValue(Map context, Object target, Member member, String propertyName, Object value, Class toType) { return typeConverter.convertValue(context, target, member, propertyName, value, toType); } - + public TypeConverter getTarget() { return typeConverter; } diff --git a/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlValueStack.java b/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlValueStack.java index a052305d08..50de36d48d 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlValueStack.java +++ b/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlValueStack.java @@ -146,6 +146,7 @@ protected void setShouldFallbackToContext(String shouldFallbackToContext) { /** * @see com.opensymphony.xwork2.util.ValueStack#getContext() */ + @Override public Map getContext() { return context; } @@ -158,6 +159,7 @@ public ActionContext getActionContext() { /** * @see com.opensymphony.xwork2.util.ValueStack#setDefaultType(java.lang.Class) */ + @Override public void setDefaultType(Class defaultType) { this.defaultType = defaultType; } @@ -176,6 +178,7 @@ public void setExprOverrides(Map overrides) { /** * @see com.opensymphony.xwork2.util.ValueStack#getExprOverrides() */ + @Override public Map getExprOverrides() { return this.overrides; } @@ -183,6 +186,7 @@ public Map getExprOverrides() { /** * @see com.opensymphony.xwork2.util.ValueStack#getRoot() */ + @Override public CompoundRoot getRoot() { return root; } @@ -190,6 +194,7 @@ public CompoundRoot getRoot() { /** * @see com.opensymphony.xwork2.util.ValueStack#setParameter(String, Object) */ + @Override public void setParameter(String expr, Object value) { setValue(expr, value, devMode); } @@ -197,6 +202,7 @@ public void setParameter(String expr, Object value) { /** * @see com.opensymphony.xwork2.util.ValueStack#setValue(java.lang.String, java.lang.Object) */ + @Override public void setValue(String expr, Object value) { setValue(expr, value, devMode); } @@ -204,6 +210,7 @@ public void setValue(String expr, Object value) { /** * @see com.opensymphony.xwork2.util.ValueStack#setValue(java.lang.String, java.lang.Object, boolean) */ + @Override public void setValue(String expr, Object value, boolean throwExceptionOnFailure) { Map context = getContext(); try { @@ -261,10 +268,12 @@ protected void handleOgnlException(String expr, Object value, boolean throwExcep /** * @see com.opensymphony.xwork2.util.ValueStack#findString(java.lang.String) */ + @Override public String findString(String expr) { return (String) findValue(expr, String.class); } + @Override public String findString(String expr, boolean throwExceptionOnFailure) { return (String) findValue(expr, String.class, throwExceptionOnFailure); } @@ -272,6 +281,7 @@ public String findString(String expr, boolean throwExceptionOnFailure) { /** * @see com.opensymphony.xwork2.util.ValueStack#findValue(java.lang.String) */ + @Override public Object findValue(String expr, boolean throwExceptionOnFailure) { try { setupExceptionOnFailure(throwExceptionOnFailure); @@ -318,6 +328,7 @@ private String lookupForOverrides(String expr) { return expr; } + @Override public Object findValue(String expr) { return findValue(expr, false); } @@ -325,6 +336,7 @@ public Object findValue(String expr) { /** * @see com.opensymphony.xwork2.util.ValueStack#findValue(java.lang.String, java.lang.Class) */ + @Override public Object findValue(String expr, Class asType, boolean throwExceptionOnFailure) { try { setupExceptionOnFailure(throwExceptionOnFailure); @@ -394,6 +406,7 @@ protected Object findInContext(String name) { return getContext().get(name); } + @Override public Object findValue(String expr, Class asType) { return findValue(expr, asType, false); } @@ -416,6 +429,7 @@ private void logLookupFailure(String expr, Exception e) { /** * @see com.opensymphony.xwork2.util.ValueStack#peek() */ + @Override public Object peek() { return root.peek(); } @@ -423,6 +437,7 @@ public Object peek() { /** * @see com.opensymphony.xwork2.util.ValueStack#pop() */ + @Override public Object pop() { return root.pop(); } @@ -430,6 +445,7 @@ public Object pop() { /** * @see com.opensymphony.xwork2.util.ValueStack#push(java.lang.Object) */ + @Override public void push(Object o) { root.push(o); } @@ -437,6 +453,7 @@ public void push(Object o) { /** * @see com.opensymphony.xwork2.util.ValueStack#set(java.lang.String, java.lang.Object) */ + @Override public void set(String key, Object o) { //set basically is backed by a Map pushed on the stack with a key being put on the map and the Object being the value Map setMap = retrieveSetMap(); @@ -466,6 +483,7 @@ private boolean shouldUseOldMap(Object topObj) { /** * @see com.opensymphony.xwork2.util.ValueStack#size() */ + @Override public int size() { return root.size(); } @@ -487,16 +505,19 @@ private Object readResolve() { return aStack; } + @Override public void clearContextValues() { //this is an OGNL ValueStack so the context will be an OgnlContext //it would be better to make context of type OgnlContext ((OgnlContext) context).getValues().clear(); } + @Override public void useAcceptProperties(Set acceptedProperties) { securityMemberAccess.useAcceptProperties(acceptedProperties); } + @Override public void useExcludeProperties(Set excludeProperties) { securityMemberAccess.useExcludeProperties(excludeProperties); } diff --git a/core/src/main/java/com/opensymphony/xwork2/ognl/XWorkTypeConverterWrapper.java b/core/src/main/java/com/opensymphony/xwork2/ognl/XWorkTypeConverterWrapper.java index 18a2c8e44d..e3abca8013 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ognl/XWorkTypeConverterWrapper.java +++ b/core/src/main/java/com/opensymphony/xwork2/ognl/XWorkTypeConverterWrapper.java @@ -29,13 +29,13 @@ public class XWorkTypeConverterWrapper implements TypeConverter { private final ognl.TypeConverter typeConverter; - + public XWorkTypeConverterWrapper(ognl.TypeConverter conv) { this.typeConverter = conv; } - - public Object convertValue(Map context, Object target, Member member, - String propertyName, Object value, Class toType) { + + @Override + public Object convertValue(Map context, Object target, Member member, String propertyName, Object value, Class toType) { return typeConverter.convertValue(context, target, member, propertyName, value, toType); } } diff --git a/core/src/main/java/com/opensymphony/xwork2/ognl/accessor/CompoundRootAccessor.java b/core/src/main/java/com/opensymphony/xwork2/ognl/accessor/CompoundRootAccessor.java index 1157c1989a..2f9333069c 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ognl/accessor/CompoundRootAccessor.java +++ b/core/src/main/java/com/opensymphony/xwork2/ognl/accessor/CompoundRootAccessor.java @@ -147,8 +147,7 @@ public Object getProperty(Map context, Object target, Object name) throws OgnlEx CompoundRoot root = (CompoundRoot) target; OgnlContext ognlContext = (OgnlContext) context; - if (name instanceof Integer) { - Integer index = (Integer) name; + if (name instanceof Integer index) { return root.cutStack(index); } else if (name instanceof String) { if ("top".equals(name)) { diff --git a/core/src/main/java/com/opensymphony/xwork2/ognl/accessor/ObjectProxyPropertyAccessor.java b/core/src/main/java/com/opensymphony/xwork2/ognl/accessor/ObjectProxyPropertyAccessor.java index 8400bab4f1..5f5ccb7994 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ognl/accessor/ObjectProxyPropertyAccessor.java +++ b/core/src/main/java/com/opensymphony/xwork2/ognl/accessor/ObjectProxyPropertyAccessor.java @@ -20,10 +20,10 @@ import com.opensymphony.xwork2.ognl.ObjectProxy; import com.opensymphony.xwork2.util.reflection.ReflectionContextState; +import ognl.OgnlContext; import ognl.OgnlException; import ognl.OgnlRuntime; import ognl.PropertyAccessor; -import ognl.OgnlContext; import java.util.Map; @@ -40,6 +40,7 @@ public class ObjectProxyPropertyAccessor implements PropertyAccessor { /** * Used by OGNl to generate bytecode */ + @Override public String getSourceAccessor(OgnlContext context, Object target, Object index) { return null; //To change body of implemented methods use File | Settings | File Templates. } @@ -47,10 +48,12 @@ public String getSourceAccessor(OgnlContext context, Object target, Object index /** * Used by OGNl to generate bytecode */ + @Override public String getSourceSetter(OgnlContext context, Object target, Object index) { - return null; + return null; } + @Override public Object getProperty(Map context, Object target, Object name) throws OgnlException { ObjectProxy proxy = (ObjectProxy) target; setupContext(context, proxy); @@ -59,6 +62,7 @@ public Object getProperty(Map context, Object target, Object name) throws OgnlEx } + @Override public void setProperty(Map context, Object target, Object name, Object value) throws OgnlException { ObjectProxy proxy = (ObjectProxy) target; setupContext(context, proxy); diff --git a/core/src/main/java/com/opensymphony/xwork2/ognl/accessor/XWorkCollectionPropertyAccessor.java b/core/src/main/java/com/opensymphony/xwork2/ognl/accessor/XWorkCollectionPropertyAccessor.java index 837558f59c..2d3581e143 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ognl/accessor/XWorkCollectionPropertyAccessor.java +++ b/core/src/main/java/com/opensymphony/xwork2/ognl/accessor/XWorkCollectionPropertyAccessor.java @@ -49,27 +49,27 @@ public class XWorkCollectionPropertyAccessor extends SetPropertyAccessor { //to access properties of the objects in the Set //so that nothing is put in the context to screw things up private final ObjectPropertyAccessor _accessor = new ObjectPropertyAccessor(); - + private XWorkConverter xworkConverter; private ObjectFactory objectFactory; private ObjectTypeDeterminer objectTypeDeterminer; private OgnlUtil ognlUtil; - + @Inject public void setXWorkConverter(XWorkConverter conv) { this.xworkConverter = conv; } - + @Inject public void setObjectFactory(ObjectFactory fac) { this.objectFactory = fac; } - + @Inject public void setObjectTypeDeterminer(ObjectTypeDeterminer ot) { this.objectTypeDeterminer = ot; } - + @Inject public void setOgnlUtil(OgnlUtil util) { this.ognlUtil = util; @@ -145,26 +145,26 @@ public Object getProperty(Map context, Object target, Object key) throws OgnlExc && ReflectionContextState.isCreatingNullObjects(context) && objectTypeDeterminer .shouldCreateIfNew(lastBeanClass,lastPropertyClass,c,keyProperty,false)) { - //create a new element and + //create a new element and //set the value of keyProperty //to be the given value try { value=objectFactory.buildBean(collClass, context); - + //set the value of the keyProperty _accessor.setProperty(context,value,keyProperty,realKey); - - //add the new object to the collection + + //add the new object to the collection c.add(value); - + //add to the Map if accessed later collMap.put(realKey, value); - - + + } catch (Exception exc) { throw new OgnlException("Error adding new element to collection", exc); } - + } return value; } else { @@ -260,7 +260,7 @@ private Object getRealValue(Map context, Object value, Class convertToClass) { return value; } return xworkConverter.convertValue(context, value, convertToClass); - } + } } /** @@ -268,7 +268,7 @@ private Object getRealValue(Map context, Object value, Class convertToClass) { */ class SurrugateList extends ArrayList { - private Collection surrugate; + private final Collection surrugate; public SurrugateList(Collection surrugate) { this.surrugate = surrugate; diff --git a/core/src/main/java/com/opensymphony/xwork2/ognl/accessor/XWorkListPropertyAccessor.java b/core/src/main/java/com/opensymphony/xwork2/ognl/accessor/XWorkListPropertyAccessor.java index 47a6404381..9bc0df14a3 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ognl/accessor/XWorkListPropertyAccessor.java +++ b/core/src/main/java/com/opensymphony/xwork2/ognl/accessor/XWorkListPropertyAccessor.java @@ -44,7 +44,7 @@ public class XWorkListPropertyAccessor extends ListPropertyAccessor { private XWorkCollectionPropertyAccessor _sAcc = new XWorkCollectionPropertyAccessor(); - + private XWorkConverter xworkConverter; private ObjectFactory objectFactory; private ObjectTypeDeterminer objectTypeDeterminer; @@ -60,22 +60,22 @@ public void setAutoGrowCollectionLimit(String value) { public void setXWorkCollectionPropertyAccessor(PropertyAccessor acc) { this._sAcc = (XWorkCollectionPropertyAccessor) acc; } - + @Inject public void setXWorkConverter(XWorkConverter conv) { this.xworkConverter = conv; } - + @Inject public void setObjectFactory(ObjectFactory fac) { this.objectFactory = fac; } - + @Inject public void setObjectTypeDeterminer(ObjectTypeDeterminer ot) { this.objectTypeDeterminer = ot; } - + @Inject public void setOgnlUtil(OgnlUtil util) { this.ognlUtil = util; @@ -93,7 +93,7 @@ public Object getProperty(Map context, Object target, Object name) throws OgnlEx ReflectionContextState.updateCurrentPropertyPath(context, name); Class lastClass = (Class) context.get(XWorkConverter.LAST_BEAN_CLASS_ACCESSED); String lastProperty = (String) context.get(XWorkConverter.LAST_BEAN_PROPERTY_ACCESSED); - + if (name instanceof Number && ReflectionContextState.isCreatingNullObjects(context) && objectTypeDeterminer.shouldCreateIfNew(lastClass,lastProperty,target,null,true)) { @@ -168,9 +168,8 @@ public void setProperty(Map context, Object target, Object name, Object value) Object realValue = getRealValue(context, value, convertToClass); - if (target instanceof List && name instanceof Number) { + if (target instanceof List list && name instanceof Number) { //make sure there are enough spaces in the List to set - List list = (List) target; int listSize = list.size(); int count = ((Number) name).intValue(); if(count > autoGrowCollectionLimit) diff --git a/core/src/main/java/com/opensymphony/xwork2/ognl/accessor/XWorkMapPropertyAccessor.java b/core/src/main/java/com/opensymphony/xwork2/ognl/accessor/XWorkMapPropertyAccessor.java index bad7932cee..db8ec65491 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ognl/accessor/XWorkMapPropertyAccessor.java +++ b/core/src/main/java/com/opensymphony/xwork2/ognl/accessor/XWorkMapPropertyAccessor.java @@ -41,21 +41,21 @@ public class XWorkMapPropertyAccessor extends MapPropertyAccessor { private static final Logger LOG = LogManager.getLogger(XWorkMapPropertyAccessor.class); private static final String[] INDEX_ACCESS_PROPS = new String[]{"size", "isEmpty", "keys", "values"}; - + private XWorkConverter xworkConverter; private ObjectFactory objectFactory; private ObjectTypeDeterminer objectTypeDeterminer; - + @Inject public void setXWorkConverter(XWorkConverter conv) { this.xworkConverter = conv; } - + @Inject public void setObjectFactory(ObjectFactory fac) { this.objectFactory = fac; } - + @Inject public void setObjectTypeDeterminer(ObjectTypeDeterminer ot) { this.objectTypeDeterminer = ot; @@ -77,7 +77,7 @@ public Object getProperty(Map context, Object target, Object name) throws OgnlEx try{ result = super.getProperty(context, target, name); - } catch (ClassCastException ex) { + } catch (ClassCastException ignored) { } if (result == null) { @@ -100,7 +100,7 @@ public Object getProperty(Map context, Object target, Object name) throws OgnlEx try { result = objectFactory.buildBean(valueClass, context); map.put(key, result); - } catch (Exception exc) { + } catch (Exception ignored) { } } } diff --git a/core/src/main/java/com/opensymphony/xwork2/ognl/accessor/XWorkMethodAccessor.java b/core/src/main/java/com/opensymphony/xwork2/ognl/accessor/XWorkMethodAccessor.java index 180e787f1b..f6e51d4fc1 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ognl/accessor/XWorkMethodAccessor.java +++ b/core/src/main/java/com/opensymphony/xwork2/ognl/accessor/XWorkMethodAccessor.java @@ -19,7 +19,11 @@ package com.opensymphony.xwork2.ognl.accessor; import com.opensymphony.xwork2.util.reflection.ReflectionContextState; -import ognl.*; +import ognl.MethodFailedException; +import ognl.ObjectMethodAccessor; +import ognl.OgnlContext; +import ognl.OgnlRuntime; +import ognl.PropertyAccessor; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -78,13 +82,12 @@ public Object callMethod(Map context, Object object, String string, Object[] obj //HACK - we pass indexed method access i.e. setXXX(A,B) pattern if ((objects.length == 2 && string.startsWith("set")) || (objects.length == 1 && string.startsWith("get"))) { Boolean exec = (Boolean) context.get(ReflectionContextState.DENY_INDEXED_ACCESS_EXECUTION); - boolean e = ((exec == null) ? false : exec.booleanValue()); + boolean e = exec != null && exec; if (!e) { return callMethodWithDebugInfo(context, object, string, objects); } } - Boolean exec = ReflectionContextState.isDenyMethodExecution(context); - boolean e = (exec != null && exec); + boolean e = ReflectionContextState.isDenyMethodExecution(context); if (!e) { return callMethodWithDebugInfo(context, object, string, objects); @@ -101,7 +104,7 @@ private Object callMethodWithDebugInfo(Map context, Object object, String method if (LOG.isDebugEnabled()) { if (!(e.getReason() instanceof NoSuchMethodException)) { // the method exists on the target object, but something went wrong - LOG.debug("Error calling method through OGNL: object: [{}] method: [{}] args: [{}]", e.getReason(), object.toString(), methodName, Arrays.toString(objects)); + LOG.debug("Error calling method through OGNL: object: [{}] method: [{}] args: [{}] - {}", object.toString(), methodName, Arrays.toString(objects), e.getReason()); } } throw e; @@ -110,8 +113,7 @@ private Object callMethodWithDebugInfo(Map context, Object object, String method @Override public Object callStaticMethod(Map context, Class aClass, String string, Object[] objects) throws MethodFailedException { - Boolean exec = ReflectionContextState.isDenyMethodExecution(context); - boolean e = ((exec == null) ? false : exec.booleanValue()); + boolean e = ReflectionContextState.isDenyMethodExecution(context); if (!e) { return callStaticMethodWithDebugInfo(context, aClass, string, objects); @@ -129,7 +131,7 @@ private Object callStaticMethodWithDebugInfo(Map context, Class aClass, String m if (LOG.isDebugEnabled()) { if (!(e.getReason() instanceof NoSuchMethodException)) { // the method exists on the target class, but something went wrong - LOG.debug("Error calling method through OGNL, class: [{}] method: [{}] args: [{}]", e.getReason(), aClass.getName(), methodName, Arrays.toString(objects)); + LOG.debug("Error calling method through OGNL, class: [{}] method: [{}] args: [{}] - {}", aClass.getName(), methodName, Arrays.toString(objects), e.getReason()); } } throw e; diff --git a/core/src/main/java/com/opensymphony/xwork2/ognl/accessor/XWorkObjectPropertyAccessor.java b/core/src/main/java/com/opensymphony/xwork2/ognl/accessor/XWorkObjectPropertyAccessor.java index 2fb7e61655..e719b1e4e6 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ognl/accessor/XWorkObjectPropertyAccessor.java +++ b/core/src/main/java/com/opensymphony/xwork2/ognl/accessor/XWorkObjectPropertyAccessor.java @@ -30,8 +30,7 @@ */ public class XWorkObjectPropertyAccessor extends ObjectPropertyAccessor { @Override - public Object getProperty(Map context, Object target, Object oname) - throws OgnlException { + public Object getProperty(Map context, Object target, Object oname) throws OgnlException { //set the last set objects in the context //so if the next objects accessed are //Maps or Collections they can use the information diff --git a/core/src/main/java/com/opensymphony/xwork2/security/DefaultAcceptedPatternsChecker.java b/core/src/main/java/com/opensymphony/xwork2/security/DefaultAcceptedPatternsChecker.java index be803b7e84..82cc4af877 100644 --- a/core/src/main/java/com/opensymphony/xwork2/security/DefaultAcceptedPatternsChecker.java +++ b/core/src/main/java/com/opensymphony/xwork2/security/DefaultAcceptedPatternsChecker.java @@ -44,7 +44,7 @@ public class DefaultAcceptedPatternsChecker implements AcceptedPatternsChecker { /** * Must match {@link #ACCEPTED_PATTERNS} RegEx. Signifies characters which result in a nested lookup via OGNL. */ - public static final Set NESTING_CHARS = unmodifiableSet(new HashSet<>(asList('.', '[', '('))); + public static final Set NESTING_CHARS = Set.of('.', '[', '('); public static final String NESTING_CHARS_STR = NESTING_CHARS.stream().map(String::valueOf).collect(joining()); public static final String[] DMI_AWARE_ACCEPTED_PATTERNS = { diff --git a/core/src/main/java/com/opensymphony/xwork2/test/StubConfigurationProvider.java b/core/src/main/java/com/opensymphony/xwork2/test/StubConfigurationProvider.java index f05bd1e6b9..73ef890dbe 100644 --- a/core/src/main/java/com/opensymphony/xwork2/test/StubConfigurationProvider.java +++ b/core/src/main/java/com/opensymphony/xwork2/test/StubConfigurationProvider.java @@ -26,25 +26,30 @@ public class StubConfigurationProvider implements ConfigurationProvider { + @Override public void destroy() { // TODO Auto-generated method stub } + @Override public void init(Configuration configuration) throws ConfigurationException { // TODO Auto-generated method stub } + @Override public void loadPackages() throws ConfigurationException { // TODO Auto-generated method stub } + @Override public boolean needsReload() { // TODO Auto-generated method stub return false; } + @Override public void register(ContainerBuilder builder, LocatableProperties props) throws ConfigurationException { // TODO Auto-generated method stub diff --git a/core/src/main/java/com/opensymphony/xwork2/util/AbstractLocalizedTextProvider.java b/core/src/main/java/com/opensymphony/xwork2/util/AbstractLocalizedTextProvider.java index 87f65b216d..9eb978a049 100644 --- a/core/src/main/java/com/opensymphony/xwork2/util/AbstractLocalizedTextProvider.java +++ b/core/src/main/java/com/opensymphony/xwork2/util/AbstractLocalizedTextProvider.java @@ -24,7 +24,6 @@ import org.apache.commons.lang3.ObjectUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.message.ParameterizedMessage; import org.apache.struts2.StrutsConstants; import java.lang.reflect.Field; @@ -35,6 +34,7 @@ import java.util.Locale; import java.util.Map; import java.util.MissingResourceException; +import java.util.Objects; import java.util.ResourceBundle; import java.util.Set; import java.util.StringTokenizer; @@ -77,11 +77,7 @@ public void addDefaultResourceBundle(String resourceBundleName) { //make sure this doesn't get added more than once final ClassLoader ccl = getCurrentThreadContextClassLoader(); synchronized (XWORK_MESSAGES_BUNDLE) { - List bundles = classLoaderMap.get(ccl.hashCode()); - if (bundles == null) { - bundles = new CopyOnWriteArrayList<>(); - classLoaderMap.put(ccl.hashCode(), bundles); - } + List bundles = classLoaderMap.computeIfAbsent(ccl.hashCode(), k -> new CopyOnWriteArrayList<>()); bundles.remove(resourceBundleName); bundles.add(0, resourceBundleName); } @@ -101,17 +97,17 @@ protected ClassLoader getCurrentThreadContextClassLoader() { @Inject(value = StrutsConstants.STRUTS_CUSTOM_I18N_RESOURCES, required = false) public void setCustomI18NResources(String bundles) { - if (bundles != null && bundles.length() > 0) { - StringTokenizer customBundles = new StringTokenizer(bundles, ", "); - - while (customBundles.hasMoreTokens()) { - String name = customBundles.nextToken(); - try { - LOG.trace("Loading global messages from [{}]", name); - addDefaultResourceBundle(name); - } catch (Exception e) { - LOG.error(new ParameterizedMessage("Could not find messages file {}.properties. Skipping", name), e); - } + if (bundles == null || bundles.isEmpty()) { + return; + } + StringTokenizer customBundles = new StringTokenizer(bundles, ", "); + while (customBundles.hasMoreTokens()) { + String name = customBundles.nextToken(); + try { + LOG.trace("Loading global messages from [{}]", name); + addDefaultResourceBundle(name); + } catch (Exception e) { + LOG.error("Could not find messages file {}.properties. Skipping", name, e); } } } @@ -238,7 +234,7 @@ public void setDelegatedClassLoader(final ClassLoader classLoader) { protected void clearBundle(final String bundleName, Locale locale) { final String key = createMissesKey(String.valueOf(getCurrentThreadContextClassLoader().hashCode()), bundleName, locale); final ResourceBundle removedBundle = bundlesMap.remove(key); - LOG.debug("Clearing resource bundle [{}], locale [{}], result: [{}].", bundleName, locale, Boolean.valueOf(removedBundle != null)); + LOG.debug("Clearing resource bundle [{}], locale [{}], result: [{}].", bundleName, locale, removedBundle != null); } /** @@ -676,8 +672,8 @@ public boolean equals(Object o) { MessageFormatKey that = (MessageFormatKey) o; - if (pattern != null ? !pattern.equals(that.pattern) : that.pattern != null) return false; - return locale != null ? locale.equals(that.locale) : that.locale == null; + if (!Objects.equals(pattern, that.pattern)) return false; + return Objects.equals(locale, that.locale); } @Override diff --git a/core/src/main/java/com/opensymphony/xwork2/util/ClassLoaderUtil.java b/core/src/main/java/com/opensymphony/xwork2/util/ClassLoaderUtil.java index acac0b1447..b1d132fa68 100644 --- a/core/src/main/java/com/opensymphony/xwork2/util/ClassLoaderUtil.java +++ b/core/src/main/java/com/opensymphony/xwork2/util/ClassLoaderUtil.java @@ -21,7 +21,12 @@ import java.io.IOException; import java.io.InputStream; import java.net.URL; -import java.util.*; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.NoSuchElementException; +import java.util.Set; /** @@ -39,7 +44,7 @@ public class ClassLoaderUtil { /** *

      - * Load all resources with a given name, potentially aggregating all results + * Load all resources with a given name, potentially aggregating all results * from the searched classloaders. If no results are found, the resource name * is prepended by '/' and tried again. *

      @@ -80,7 +85,7 @@ public static Iterator getResources(String resourceName, Class callingClass } } - if (!iterator.hasNext() && (resourceName != null) && ((resourceName.length() == 0) || (resourceName.charAt(0) != '/'))) { + if (!iterator.hasNext() && (resourceName != null) && ((resourceName.isEmpty()) || (resourceName.charAt(0) != '/'))) { return getResources('/' + resourceName, callingClass, aggregate); } @@ -119,7 +124,7 @@ public static URL getResource(String resourceName, Class callingClass) { } } - if ((url == null) && (resourceName != null) && ((resourceName.length() == 0) || (resourceName.charAt(0) != '/'))) { + if ((url == null) && (resourceName != null) && ((resourceName.isEmpty()) || (resourceName.charAt(0) != '/'))) { return getResource('/' + resourceName, callingClass); } @@ -214,7 +219,7 @@ static class AggregateIterator implements Iterator { LinkedList> enums = new LinkedList<>(); Enumeration cur = null; E next = null; - Set loaded = new HashSet(); + Set loaded = new HashSet<>(); public AggregateIterator addEnumeration(Enumeration e) { if (e.hasMoreElements()) { @@ -245,7 +250,7 @@ public E next() { private Enumeration determineCurrentEnumeration() { if (cur != null && !cur.hasMoreElements()) { - if (enums.size() > 0) { + if (!enums.isEmpty()) { cur = enums.removeLast(); } else { cur = null; diff --git a/core/src/main/java/com/opensymphony/xwork2/util/ClassPathFinder.java b/core/src/main/java/com/opensymphony/xwork2/util/ClassPathFinder.java index ecfda3274c..7a23791105 100644 --- a/core/src/main/java/com/opensymphony/xwork2/util/ClassPathFinder.java +++ b/core/src/main/java/com/opensymphony/xwork2/util/ClassPathFinder.java @@ -53,7 +53,7 @@ public class ClassPathFinder { */ private PatternMatcher patternMatcher = new WildcardHelper(); - private Vector compared = new Vector<>(); + private final Vector compared = new Vector<>(); /** * @return the pattern in use @@ -93,14 +93,14 @@ public Vector findMatches() { // debug docker build for JDK 9+ if (entryURI.getRawQuery() != null) { - throw new StrutsException("Currently URI with query component isn't supported: " + entryURI.toString()); + throw new StrutsException("Currently URI with query component isn't supported: " + entryURI); } File entry = new File(entryURI); if (entry.isFile() && entry.toString().endsWith(".jar")) { try(ZipInputStream zip = new ZipInputStream(new FileInputStream(entry))) { for (ZipEntry zipEntry = zip.getNextEntry(); zipEntry != null; zipEntry = zip.getNextEntry()) { - boolean doesMatch = patternMatcher.match(new HashMap(), zipEntry.getName(), compiledPattern); + boolean doesMatch = patternMatcher.match(new HashMap<>(), zipEntry.getName(), compiledPattern); if (doesMatch) { matches.add(zipEntry.getName()); } @@ -154,7 +154,7 @@ private Vector checkEntries(String[] entries, File parent, String prefix compared.add(entryToCheck); } - boolean doesMatch = patternMatcher.match(new HashMap(), entryToCheck, compiledPattern); + boolean doesMatch = patternMatcher.match(new HashMap<>(), entryToCheck, compiledPattern); if (doesMatch) { matches.add(entryToCheck); } diff --git a/core/src/main/java/com/opensymphony/xwork2/util/CompoundRoot.java b/core/src/main/java/com/opensymphony/xwork2/util/CompoundRoot.java index d2317e1eb6..dbfd71fce8 100644 --- a/core/src/main/java/com/opensymphony/xwork2/util/CompoundRoot.java +++ b/core/src/main/java/com/opensymphony/xwork2/util/CompoundRoot.java @@ -18,18 +18,20 @@ */ package com.opensymphony.xwork2.util; +import java.io.Serial; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; /** * A Stack that is implemented using a List. - * + * * @author plightbo * @version $Revision$ */ public class CompoundRoot extends CopyOnWriteArrayList { + @Serial private static final long serialVersionUID = 8563229069192473995L; public CompoundRoot() { diff --git a/core/src/main/java/com/opensymphony/xwork2/util/DebugUtils.java b/core/src/main/java/com/opensymphony/xwork2/util/DebugUtils.java index 3fdf8b0a70..13dc78b388 100644 --- a/core/src/main/java/com/opensymphony/xwork2/util/DebugUtils.java +++ b/core/src/main/java/com/opensymphony/xwork2/util/DebugUtils.java @@ -28,13 +28,11 @@ public final class DebugUtils { public static void notifyDeveloperOfError(Logger log, Object action, String message) { - if (action instanceof TextProvider) { - TextProvider tp = (TextProvider) action; + if (action instanceof TextProvider tp) { message = tp.getText("devmode.notification", "Developer Notification:\n{0}", new String[]{message}); } log.error(message); - if (action instanceof ValidationAware) { - ValidationAware validationAware = (ValidationAware) action; + if (action instanceof ValidationAware validationAware) { validationAware.addActionError(message); } } diff --git a/core/src/main/java/com/opensymphony/xwork2/util/DomHelper.java b/core/src/main/java/com/opensymphony/xwork2/util/DomHelper.java index b79c3c03a3..f2d809fae5 100644 --- a/core/src/main/java/com/opensymphony/xwork2/util/DomHelper.java +++ b/core/src/main/java/com/opensymphony/xwork2/util/DomHelper.java @@ -91,7 +91,7 @@ public static Document parse(InputSource inputSource, Map dtdMap try { ObjectFactory objectFactory = ActionContext.getContext().getContainer().getInstance(ObjectFactory.class); Class clazz = objectFactory.getClassInstance(parserProp); - factory = (SAXParserFactory) clazz.newInstance(); + factory = (SAXParserFactory) clazz.getDeclaredConstructor().newInstance(); } catch (Exception e) { LOG.error("Unable to load saxParserFactory set by system property 'xwork.saxParserFactory': {}", parserProp, e); } @@ -169,7 +169,7 @@ static public class DOMBuilder implements ContentHandler { try { ObjectFactory objectFactory = ActionContext.getContext().getContainer().getInstance(ObjectFactory.class); Class clazz = objectFactory.getClassInstance(parserProp); - FACTORY = (SAXTransformerFactory) clazz.newInstance(); + FACTORY = (SAXTransformerFactory) clazz.getDeclaredConstructor().newInstance(); } catch (Exception e) { LOG.error("Unable to load SAXTransformerFactory set by system property 'xwork.saxTransformerFactory': {}", parserProp, e); } diff --git a/core/src/main/java/com/opensymphony/xwork2/util/Evaluated.java b/core/src/main/java/com/opensymphony/xwork2/util/Evaluated.java index cea76641af..8ecb657336 100644 --- a/core/src/main/java/com/opensymphony/xwork2/util/Evaluated.java +++ b/core/src/main/java/com/opensymphony/xwork2/util/Evaluated.java @@ -20,7 +20,7 @@ public class Evaluated { - private Object value; + private final Object value; public Evaluated(Object value) { this.value = value; diff --git a/core/src/main/java/com/opensymphony/xwork2/util/OgnlTextParser.java b/core/src/main/java/com/opensymphony/xwork2/util/OgnlTextParser.java index f3ad98b2df..e4708cddb6 100644 --- a/core/src/main/java/com/opensymphony/xwork2/util/OgnlTextParser.java +++ b/core/src/main/java/com/opensymphony/xwork2/util/OgnlTextParser.java @@ -87,8 +87,8 @@ public Object evaluate(char[] openChars, String expression, TextParseUtil.Parsed expression = left.concat(right); result = expression; } - pos = (left != null && left.length() > 0 ? left.length() - 1: 0) + - (middle != null && middle.length() > 0 ? middle.length() - 1: 0) + + pos = (!left.isEmpty() ? left.length() - 1: 0) + + (middle != null && !middle.isEmpty() ? middle.length() - 1: 0) + 1; pos = Math.max(pos, 1); } else { diff --git a/core/src/main/java/com/opensymphony/xwork2/util/PropertiesReader.java b/core/src/main/java/com/opensymphony/xwork2/util/PropertiesReader.java index ae527171f0..62319f0f2c 100644 --- a/core/src/main/java/com/opensymphony/xwork2/util/PropertiesReader.java +++ b/core/src/main/java/com/opensymphony/xwork2/util/PropertiesReader.java @@ -18,7 +18,11 @@ */ package com.opensymphony.xwork2.util; -import java.io.*; +import java.io.IOException; +import java.io.LineNumberReader; +import java.io.Reader; +import java.io.StringWriter; +import java.io.Writer; import java.util.ArrayList; import java.util.List; @@ -39,7 +43,7 @@ public class PropertiesReader extends LineNumberReader { /** * Stores the comment lines for the currently processed property. */ - private List commentLines; + private final List commentLines; /** * Stores the name of the last read property. @@ -54,7 +58,7 @@ public class PropertiesReader extends LineNumberReader { /** * Stores the list delimiter character. */ - private char delimiter; + private final char delimiter; /** * Constant for the supported comment characters. @@ -100,7 +104,7 @@ public PropertiesReader(Reader reader) { */ public PropertiesReader(Reader reader, char listDelimiter) { super(reader); - commentLines = new ArrayList(); + commentLines = new ArrayList<>(); delimiter = listDelimiter; } @@ -115,7 +119,7 @@ public PropertiesReader(Reader reader, char listDelimiter) { boolean isCommentLine(String line) { String s = line.trim(); // blanc lines are also treated as comment lines - return s.length() < 1 || COMMENT_CHARS.indexOf(s.charAt(0)) >= 0; + return s.isEmpty() || COMMENT_CHARS.indexOf(s.charAt(0)) >= 0; } /** @@ -335,7 +339,7 @@ protected static String unescapeJava(String str, char delimiter) { } int sz = str.length(); StringBuilder out = new StringBuilder(sz); - StringBuffer unicode = new StringBuffer(UNICODE_LEN); + StringBuilder unicode = new StringBuilder(UNICODE_LEN); boolean hadSlash = false; boolean inUnicode = false; for (int i = 0; i < sz; i++) { @@ -475,7 +479,7 @@ public static void unescapeJava(Writer out, String str) throws IOException { return; } int sz = str.length(); - StringBuffer unicode = new StringBuffer(4); + StringBuilder unicode = new StringBuilder(4); boolean hadSlash = false; boolean inUnicode = false; for (int i = 0; i < sz; i++) { diff --git a/core/src/main/java/com/opensymphony/xwork2/util/ResolverUtil.java b/core/src/main/java/com/opensymphony/xwork2/util/ResolverUtil.java index 81e5e61cc7..3b7e3716f0 100644 --- a/core/src/main/java/com/opensymphony/xwork2/util/ResolverUtil.java +++ b/core/src/main/java/com/opensymphony/xwork2/util/ResolverUtil.java @@ -18,8 +18,8 @@ */ package com.opensymphony.xwork2.util; -import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import java.io.File; import java.io.FileInputStream; @@ -27,6 +27,7 @@ import java.lang.annotation.Annotation; import java.net.URL; import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; import java.util.Enumeration; import java.util.HashSet; import java.util.Set; @@ -61,10 +62,10 @@ *resolver.find(new CustomTest(), pkg1); *resolver.find(new CustomTest(), pkg2); *Collection<ActionBean> beans = resolver.getClasses(); - * + * * *

      This class was copied from Stripes - http://stripes.mc4j.org/confluence/display/stripes/Home

      - * + * * @author Tim Fennell */ public class ResolverUtil { @@ -75,7 +76,7 @@ public class ResolverUtil { * A simple interface that specifies how to test classes to determine if they * are to be included in the results produced by the ResolverUtil. */ - public static interface Test { + public interface Test { /** * Will be called repeatedly with candidate classes. * @@ -83,13 +84,13 @@ public static interface Test { * @return True if a class is to be included in the results, false otherwise. */ boolean matches(Class type); - + boolean matches(URL resource); boolean doesMatchClass(); boolean doesMatchResource(); } - + public static abstract class ClassTest implements Test { public boolean matches(URL resource) { throw new UnsupportedOperationException(); @@ -102,7 +103,7 @@ public boolean doesMatchResource() { return false; } } - + public static abstract class ResourceTest implements Test { public boolean matches(Class cls) { throw new UnsupportedOperationException(); @@ -121,7 +122,7 @@ public boolean doesMatchResource() { * that this test will match the parent type itself if it is presented for matching. */ public static class IsA extends ClassTest { - private Class parent; + private final Class parent; /** Constructs an IsA test using the supplied Class as the parent class/interface. * @param parentType the parent type class @@ -140,12 +141,12 @@ public boolean matches(Class type) { return "is assignable to " + parent.getSimpleName(); } } - + /** * A Test that checks to see if each class name ends with the provided suffix. */ public static class NameEndsWith extends ClassTest { - private String suffix; + private final String suffix; /** * Constructs a NameEndsWith test using the supplied suffix. @@ -171,7 +172,7 @@ public boolean matches(Class type) { * is, then the test returns true, otherwise false. */ public static class AnnotatedWith extends ClassTest { - private Class annotation; + private final Class annotation; /** * Constructs an AnnotatedWith test for the specified annotation type. @@ -192,26 +193,26 @@ public boolean matches(Class type) { return "annotated with @" + annotation.getSimpleName(); } } - + public static class NameIs extends ResourceTest { - private String name; - + private final String name; + public NameIs(String name) { this.name = "/" + name; } - + public boolean matches(URL resource) { return (resource.getPath().endsWith(name)); } - + @Override public String toString() { return "named " + name; } } /** The set of matches being accumulated. */ - private Set> classMatches = new HashSet>(); - + private final Set> classMatches = new HashSet<>(); + /** The set of matches being accumulated. */ - private Set resourceMatches = new HashSet<>(); + private final Set resourceMatches = new HashSet<>(); /** * The ClassLoader to use when looking for classes. If null then the ClassLoader returned @@ -228,11 +229,11 @@ public boolean matches(URL resource) { public Set> getClasses() { return classMatches; } - + public Set getResources() { return resourceMatches; } - + /** * Returns the classloader that will be used for scanning for classes. If no explicit @@ -269,7 +270,7 @@ public void findImplementations(Class parent, String... packageNames) { findInPackage(test, pkg); } } - + /** * Attempts to discover classes who's name ends with the provided suffix. Accumulated classes can be * accessed by calling {@link #getClasses()}. @@ -301,16 +302,16 @@ public void findAnnotated(Class annotation, String... pack findInPackage(test, pkg); } } - + public void findNamedResource(String name, String... pathNames) { if (pathNames == null) return; - + Test test = new NameIs(name); for (String pkg : pathNames) { findInPackage(test, pkg); } } - + /** * Attempts to discover classes that pass the test. Accumulated * classes can be accessed by calling {@link #getClasses()}. @@ -352,35 +353,28 @@ public void findInPackage(Test test, String packageName) { } while (urls.hasMoreElements()) { - try { - String urlPath = urls.nextElement().getFile(); - urlPath = URLDecoder.decode(urlPath, "UTF-8"); + String urlPath = urls.nextElement().getFile(); + urlPath = URLDecoder.decode(urlPath, StandardCharsets.UTF_8); - // If it's a file in a directory, trim the stupid file: spec - if ( urlPath.startsWith("file:") ) { - urlPath = urlPath.substring(5); - } + // If it's a file in a directory, trim the stupid file: spec + if ( urlPath.startsWith("file:") ) { + urlPath = urlPath.substring(5); + } - // Else it's in a JAR, grab the path to the jar - if (urlPath.indexOf('!') > 0) { - urlPath = urlPath.substring(0, urlPath.indexOf('!')); - } + // Else it's in a JAR, grab the path to the jar + if (urlPath.indexOf('!') > 0) { + urlPath = urlPath.substring(0, urlPath.indexOf('!')); + } - if (LOG.isInfoEnabled()) { - LOG.info("Scanning for classes in [" + urlPath + "] matching criteria: " + test); - } - File file = new File(urlPath); - if ( file.isDirectory() ) { - loadImplementationsInDirectory(test, packageName, file); - } - else { - loadImplementationsInJar(test, packageName, file); - } + if (LOG.isInfoEnabled()) { + LOG.info("Scanning for classes in [" + urlPath + "] matching criteria: " + test); } - catch (IOException ioe) { - if (LOG.isWarnEnabled()) { - LOG.warn("could not read entries", ioe); - } + File file = new File(urlPath); + if ( file.isDirectory() ) { + loadImplementationsInDirectory(test, packageName, file); + } + else { + loadImplementationsInJar(test, packageName, file); } } } @@ -400,7 +394,7 @@ public void findInPackage(Test test, String packageName) { */ private void loadImplementationsInDirectory(Test test, String parent, File location) { File[] files = location.listFiles(); - StringBuilder builder = null; + StringBuilder builder; for (File file : files) { builder = new StringBuilder(100); @@ -459,7 +453,7 @@ protected void addIfMatching(Test test, String fqn) { if (LOG.isDebugEnabled()) { LOG.debug("Checking to see if class " + externalName + " matches criteria [" + test + "]"); } - + Class type = loader.loadClass(externalName); if (test.matches(type) ) { classMatches.add( (Class) type); @@ -482,4 +476,4 @@ protected void addIfMatching(Test test, String fqn) { } } } -} \ No newline at end of file +} diff --git a/core/src/main/java/com/opensymphony/xwork2/util/TextParseUtil.java b/core/src/main/java/com/opensymphony/xwork2/util/TextParseUtil.java index 2a2cad1bf9..ebe940e3f0 100644 --- a/core/src/main/java/com/opensymphony/xwork2/util/TextParseUtil.java +++ b/core/src/main/java/com/opensymphony/xwork2/util/TextParseUtil.java @@ -157,14 +157,12 @@ public static Object translateVariables(char open, String expression, ValueStack */ public static Object translateVariables(char[] openChars, String expression, final ValueStack stack, final Class asType, final ParsedValueEvaluator evaluator, int maxLoopCount) { - ParsedValueEvaluator ognlEval = new ParsedValueEvaluator() { - public Object evaluate(String parsedValue) { - Object o = stack.findValue(parsedValue, asType); - if (evaluator != null && o != null) { - o = evaluator.evaluate(o.toString()); - } - return o; + ParsedValueEvaluator ognlEval = parsedValue -> { + Object o = stack.findValue(parsedValue, asType); + if (evaluator != null && o != null) { + o = evaluator.evaluate(o.toString()); } + return o; }; TextParser parser = stack.getActionContext().getContainer().getInstance(TextParser.class); @@ -202,11 +200,8 @@ public static Collection translateVariablesCollection( char[] openChars, String expression, final ValueStack stack, boolean excludeEmptyElements, final ParsedValueEvaluator evaluator, int maxLoopCount) { - ParsedValueEvaluator ognlEval = new ParsedValueEvaluator() { - public Object evaluate(String parsedValue) { - return stack.findValue(parsedValue); // no asType !!! - } - }; + // no asType !!! + ParsedValueEvaluator ognlEval = stack::findValue; ActionContext actionContext = stack.getActionContext(); TextParser parser = actionContext.getContainer().getInstance(TextParser.class); diff --git a/core/src/main/java/com/opensymphony/xwork2/util/WildcardHelper.java b/core/src/main/java/com/opensymphony/xwork2/util/WildcardHelper.java index 4bf1e84cf5..8a61c63e97 100644 --- a/core/src/main/java/com/opensymphony/xwork2/util/WildcardHelper.java +++ b/core/src/main/java/com/opensymphony/xwork2/util/WildcardHelper.java @@ -231,32 +231,15 @@ public boolean match(Map map, String data, int[] expr) { } } - // Check for MATCH_BEGIN - if (matchBegin) { - if (offset != 0) { - return (false); - } - - matchBegin = false; - } - // Advance buffpos buffpos += (charpos - exprpos); // Check for END's if (exprchr == MATCH_END) { - if (rsltpos > 0) { - map.put(Integer.toString(++mcount), - new String(rslt, 0, rsltpos)); - } // Don't care about rest of input buffer return (true); } else if (exprchr == MATCH_THEEND) { - if (rsltpos > 0) { - map.put(Integer.toString(++mcount), - new String(rslt, 0, rsltpos)); - } // Check that we reach buffer's end return (buffpos == buff.length); diff --git a/core/src/main/java/com/opensymphony/xwork2/util/classloader/AbstractResourceStore.java b/core/src/main/java/com/opensymphony/xwork2/util/classloader/AbstractResourceStore.java index 75697d5330..5fcdafd485 100644 --- a/core/src/main/java/com/opensymphony/xwork2/util/classloader/AbstractResourceStore.java +++ b/core/src/main/java/com/opensymphony/xwork2/util/classloader/AbstractResourceStore.java @@ -44,9 +44,11 @@ protected void closeQuietly(InputStream is) { } } + @Override public void write(String pResourceName, byte[] pResourceData) { } + @Override public String toString() { return this.getClass().getName() + file.toString(); } diff --git a/core/src/main/java/com/opensymphony/xwork2/util/classloader/FileResourceStore.java b/core/src/main/java/com/opensymphony/xwork2/util/classloader/FileResourceStore.java index fe85249194..204ee54261 100644 --- a/core/src/main/java/com/opensymphony/xwork2/util/classloader/FileResourceStore.java +++ b/core/src/main/java/com/opensymphony/xwork2/util/classloader/FileResourceStore.java @@ -36,6 +36,7 @@ public FileResourceStore(final File file) { super(file); } + @Override public byte[] read(final String pResourceName) { FileInputStream fis = null; try { diff --git a/core/src/main/java/com/opensymphony/xwork2/util/classloader/JarResourceStore.java b/core/src/main/java/com/opensymphony/xwork2/util/classloader/JarResourceStore.java index ce3b327fca..fee136fad8 100644 --- a/core/src/main/java/com/opensymphony/xwork2/util/classloader/JarResourceStore.java +++ b/core/src/main/java/com/opensymphony/xwork2/util/classloader/JarResourceStore.java @@ -21,7 +21,11 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import java.io.*; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; @@ -35,6 +39,7 @@ public JarResourceStore(File file) { super(file); } + @Override public byte[] read(String pResourceName) { InputStream in = null; try(ZipFile jarFile = new ZipFile(file)) { diff --git a/core/src/main/java/com/opensymphony/xwork2/util/classloader/ReloadingClassLoader.java b/core/src/main/java/com/opensymphony/xwork2/util/classloader/ReloadingClassLoader.java index 159e57b20a..14003ed4af 100644 --- a/core/src/main/java/com/opensymphony/xwork2/util/classloader/ReloadingClassLoader.java +++ b/core/src/main/java/com/opensymphony/xwork2/util/classloader/ReloadingClassLoader.java @@ -136,30 +136,37 @@ public void reload() { delegate = new ResourceStoreClassLoader(parent, stores); } + @Override public void clearAssertionStatus() { delegate.clearAssertionStatus(); } + @Override public URL getResource(String name) { return delegate.getResource(name); } + @Override public InputStream getResourceAsStream(String name) { return delegate.getResourceAsStream(name); } + @Override public Class loadClass(String name) throws ClassNotFoundException { return isAccepted(name) ? delegate.loadClass(name) : parent.loadClass(name); } + @Override public void setClassAssertionStatus(String className, boolean enabled) { delegate.setClassAssertionStatus(className, enabled); } + @Override public void setDefaultAssertionStatus(boolean enabled) { delegate.setDefaultAssertionStatus(enabled); } + @Override public void setPackageAssertionStatus(String packageName, boolean enabled) { delegate.setPackageAssertionStatus(packageName, enabled); } diff --git a/core/src/main/java/com/opensymphony/xwork2/util/classloader/ResourceStoreClassLoader.java b/core/src/main/java/com/opensymphony/xwork2/util/classloader/ResourceStoreClassLoader.java index fef8b6b7a8..8a9301eed2 100644 --- a/core/src/main/java/com/opensymphony/xwork2/util/classloader/ResourceStoreClassLoader.java +++ b/core/src/main/java/com/opensymphony/xwork2/util/classloader/ResourceStoreClassLoader.java @@ -85,13 +85,13 @@ protected Class findClass(final String name) throws ClassNotFoundException { * @param className the class name of for which the package information * is to be determined. */ - protected void definePackage(String className){ + private void definePackage(String className){ int classIndex = className.lastIndexOf('.'); if (classIndex == -1) { return; } String packageName = className.substring(0, classIndex); - if (getPackage(packageName) != null) { + if (getDefinedPackage(packageName) != null) { return; } definePackage(packageName, null, null, null, null, null, null, null); diff --git a/core/src/main/java/com/opensymphony/xwork2/util/finder/ClassLoaderInterface.java b/core/src/main/java/com/opensymphony/xwork2/util/finder/ClassLoaderInterface.java index ca5a0b1049..b213e389b5 100644 --- a/core/src/main/java/com/opensymphony/xwork2/util/finder/ClassLoaderInterface.java +++ b/core/src/main/java/com/opensymphony/xwork2/util/finder/ClassLoaderInterface.java @@ -18,27 +18,27 @@ */ package com.opensymphony.xwork2.util.finder; -import java.net.URL; -import java.util.Enumeration; import java.io.IOException; import java.io.InputStream; +import java.net.URL; +import java.util.Enumeration; /** * Classes implementing this interface can find resources and load classes, usually delegating to a class - * loader + * loader */ public interface ClassLoaderInterface { //key used to add the current ClassLoaderInterface to ActionContext - public final String CLASS_LOADER_INTERFACE = "__current_class_loader_interface"; + String CLASS_LOADER_INTERFACE = "__current_class_loader_interface"; Class loadClass(String name) throws ClassNotFoundException; URL getResource(String name); - public Enumeration getResources(String name) throws IOException; + Enumeration getResources(String name) throws IOException; - public InputStream getResourceAsStream(String name) throws IOException; + InputStream getResourceAsStream(String name) throws IOException; ClassLoaderInterface getParent(); } diff --git a/core/src/main/java/com/opensymphony/xwork2/util/finder/ClassLoaderInterfaceDelegate.java b/core/src/main/java/com/opensymphony/xwork2/util/finder/ClassLoaderInterfaceDelegate.java index ca28771d8e..74ab894f31 100644 --- a/core/src/main/java/com/opensymphony/xwork2/util/finder/ClassLoaderInterfaceDelegate.java +++ b/core/src/main/java/com/opensymphony/xwork2/util/finder/ClassLoaderInterfaceDelegate.java @@ -27,28 +27,33 @@ * Default implementation of ClassLoaderInterface, which delegates to an actual ClassLoader */ public class ClassLoaderInterfaceDelegate implements ClassLoaderInterface { - private ClassLoader classLoader; + private final ClassLoader classLoader; public ClassLoaderInterfaceDelegate(ClassLoader classLoader) { this.classLoader = classLoader; } + @Override public Class loadClass(String name) throws ClassNotFoundException { return classLoader.loadClass(name); } + @Override public URL getResource(String className) { return classLoader.getResource(className); } + @Override public Enumeration getResources(String name) throws IOException { return classLoader.getResources(name); } + @Override public InputStream getResourceAsStream(String name) { return classLoader.getResourceAsStream(name); } + @Override public ClassLoaderInterface getParent() { return classLoader.getParent() != null ? new ClassLoaderInterfaceDelegate(classLoader.getParent()) : null; } diff --git a/core/src/main/java/com/opensymphony/xwork2/util/finder/ResourceFinder.java b/core/src/main/java/com/opensymphony/xwork2/util/finder/ResourceFinder.java index a83d465b98..a950f7411c 100644 --- a/core/src/main/java/com/opensymphony/xwork2/util/finder/ResourceFinder.java +++ b/core/src/main/java/com/opensymphony/xwork2/util/finder/ResourceFinder.java @@ -26,8 +26,21 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; -import java.net.*; -import java.util.*; +import java.net.HttpURLConnection; +import java.net.JarURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLDecoder; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; import java.util.jar.JarEntry; import java.util.jar.JarFile; @@ -61,11 +74,11 @@ public ResourceFinder(String path, ClassLoaderInterface classLoaderInterface) { /** * Create a ResourceFinder instance for looking up resources (via ClassLoader or via specific URLs * specifying resource locations). - * + * * This class was functional in Struts 2.3.x, but broken for Struts 2.5.x (before 2.5.24), when dealing with * JAR resources in certain circumstances. The current logic permits the base path to be "" (empty string), * which is required to also match JAR entries rooted at "" and not just file entries rooted at "/". - * + * * @param path Base path from which to look for resources (typically "xyz/abc/klm" form for file or * jar contents). * @param classLoaderInterface ClassLoader to perform the resource lookup. If null, a default Thread @@ -88,7 +101,7 @@ public ResourceFinder(String path, ClassLoaderInterface classLoaderInterface, UR continue; } try { - urls[i] = new URL("jar", "", -1, url.toString() + "!/"); + urls[i] = new URL("jar", "", -1, url + "!/"); } catch (MalformedURLException e) { // Leave original entry intact if jar URL conversion fails. } @@ -101,7 +114,7 @@ private static boolean isDirectory(URL url) { throw new IllegalArgumentException("Cannot test if a null URL is a directory"); } String file = url.getFile(); - return (file.length() > 0 && file.charAt(file.length() - 1) == '/'); + return !file.isEmpty() && file.charAt(file.length() - 1) == '/'; } /** @@ -333,9 +346,7 @@ public Map mapAvailableStrings(String uri) throws IOException { LOG.trace("Null resources URL map for [{}], should not be possible!", uri); throw new IllegalStateException("Null resources URL map produced for uri: " + uri); } - resourcesMap.entrySet().forEach(entry -> { - String name = entry.getKey(); - URL url = entry.getValue(); + resourcesMap.forEach((name, url) -> { try { String value = readContents(url); strings.put(name, value); @@ -363,7 +374,7 @@ public Map mapAvailableStrings(String uri) throws IOException { */ public Class findClass(String uri) throws IOException, ClassNotFoundException { String className = findString(uri); - return (Class) classLoaderInterface.loadClass(className); + return classLoaderInterface.loadClass(className); } /** @@ -515,9 +526,7 @@ public Map mapAvailableClasses(String uri) throws IOException { LOG.trace("Null strings map for [{}], should not be possible!", uri); throw new IllegalStateException("Null strings map produced for uri: " + uri); } - map.entrySet().forEach(entry -> { - String string = entry.getKey(); - String className = entry.getValue(); + map.forEach((string, className) -> { try { Class clazz = classLoaderInterface.loadClass(className); classes.put(string, clazz); @@ -775,9 +784,7 @@ public Map mapAvailableImplementations(Class interfase) throws IO LOG.trace("Null strings map for [{}], should not be possible!", interfase.getName()); throw new IllegalStateException("Null strings map produced for interface: " + interfase.getName()); } - map.entrySet().forEach(entry -> { - String string = entry.getKey(); - String className = entry.getValue(); + map.forEach((string, className) -> { try { Class impl = classLoaderInterface.loadClass(className); if (interfase.isAssignableFrom(impl)) { @@ -1016,9 +1023,7 @@ public Map mapAvailableProperties(String uri) throws IOExcep LOG.trace("Null resources URL map for [{}], should not be possible!", uri); throw new IllegalStateException("Null resources URL map produced for uri: " + uri); } - map.entrySet().forEach(entry -> { - String string = entry.getKey(); - URL url = entry.getValue(); + map.forEach((string, url) -> { try { Properties properties = loadProperties(url); propertiesMap.put(string, properties); @@ -1154,9 +1159,7 @@ public Map> findPackagesMap(String uri) throws IOException { private Set convertPathsToPackages(Set resources) { Set packageNames = new HashSet<>(resources.size()); - resources.forEach(resource -> { - packageNames.add(StringUtils.removeEnd(StringUtils.replace(resource, "/", "."), ".")); - }); + resources.forEach(resource -> packageNames.add(StringUtils.removeEnd(StringUtils.replace(resource, "/", "."), "."))); return packageNames; } @@ -1198,7 +1201,7 @@ private static void readJarEntries(URL location, String basePath, Map entries = jarfile.entries(); - while (entries != null && entries.hasMoreElements()) { + while (entries.hasMoreElements()) { JarEntry entry = entries.nextElement(); String name = entry.getName(); @@ -1225,19 +1228,19 @@ private static void readJarDirectoryEntries(URL location, String basePath, Set entries = jarfile.entries(); - if (entries == null || ! entries.hasMoreElements()) { + if (! entries.hasMoreElements()) { LOG.debug(" JAR entries null or empty"); } - LOG.debug(" Looking for entries matching basePath: " + basePath); + LOG.debug(" Looking for entries matching basePath: {}", basePath); - while (entries != null && entries.hasMoreElements()) { + while (entries.hasMoreElements()) { JarEntry entry = entries.nextElement(); String name = entry.getName(); if (entry.isDirectory() && StringUtils.startsWith(name, basePath)) { resources.add(name); } else if (entry.isDirectory()) { - LOG.trace(" entry: " + name + " , isDirectory: " + entry.isDirectory() + " but does not start with basepath"); + LOG.trace(" entry: {} , isDirectory: {}} but does not start with basepath", name, true); } } } @@ -1281,7 +1284,7 @@ private Enumeration getResources(String fulluri) throws IOException { LOG.debug(" urls (member) non-null, using findResource to get resources"); - ArrayList resources = new ArrayList<>(urls != null ? urls.length : 0); + ArrayList resources = new ArrayList<>(urls.length); for (URL url : urls) { URL resource = findResource(fulluri, url); @@ -1332,10 +1335,7 @@ private URL findResource(String resourceName, URL... search) { continue; } sepIdx += 2; - StringBuilder sb = new StringBuilder(file.length() - sepIdx + resourceName.length()); - sb.append(file.substring(sepIdx)); - sb.append(resourceName); - entryName = sb.toString(); + entryName = file.substring(sepIdx) + resourceName; } if ("META-INF/".equals(entryName) && jarFile.getEntry("META-INF/MANIFEST.MF") != null){ return targetURL(currentUrl, "META-INF/MANIFEST.MF"); @@ -1398,10 +1398,7 @@ private URL findResource(String resourceName, URL... search) { } private URL targetURL(URL base, String name) throws MalformedURLException { - StringBuilder sb = new StringBuilder(base.getFile().length() + name.length()); - sb.append(base.getFile()); - sb.append(name); - String file = sb.toString(); + String file = base.getFile() + name; return new URL(base.getProtocol(), base.getHost(), base.getPort(), file, null); } } diff --git a/core/src/main/java/com/opensymphony/xwork2/util/finder/Test.java b/core/src/main/java/com/opensymphony/xwork2/util/finder/Test.java index 0d3f308da2..70476f97a6 100644 --- a/core/src/main/java/com/opensymphony/xwork2/util/finder/Test.java +++ b/core/src/main/java/com/opensymphony/xwork2/util/finder/Test.java @@ -28,5 +28,5 @@ public interface Test { * @param t The resource object to test. * @return True if the resource should be accepted, false otherwise. */ - public boolean test(T t); -} \ No newline at end of file + boolean test(T t); +} diff --git a/core/src/main/java/com/opensymphony/xwork2/util/finder/UrlSet.java b/core/src/main/java/com/opensymphony/xwork2/util/finder/UrlSet.java index 299e55adeb..9d32415e77 100644 --- a/core/src/main/java/com/opensymphony/xwork2/util/finder/UrlSet.java +++ b/core/src/main/java/com/opensymphony/xwork2/util/finder/UrlSet.java @@ -27,7 +27,15 @@ import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; /** *

      @@ -281,7 +289,7 @@ private List getUrls(ClassLoaderInterface classLoader, Set protocol return list; } - public static interface FileProtocolNormalizer { + public interface FileProtocolNormalizer { URL normalizeToFileProtocol(URL url); } } diff --git a/core/src/main/java/com/opensymphony/xwork2/util/fs/DefaultFileManager.java b/core/src/main/java/com/opensymphony/xwork2/util/fs/DefaultFileManager.java index 15b882fd4a..0cc42cbeaf 100644 --- a/core/src/main/java/com/opensymphony/xwork2/util/fs/DefaultFileManager.java +++ b/core/src/main/java/com/opensymphony/xwork2/util/fs/DefaultFileManager.java @@ -35,18 +35,21 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import static java.util.Objects.requireNonNullElseGet; + /** * Default implementation of {@link FileManager} */ public class DefaultFileManager implements FileManager { - private static Logger LOG = LogManager.getLogger(DefaultFileManager.class); + private static final Logger LOG = LogManager.getLogger(DefaultFileManager.class); - private static final Pattern JAR_PATTERN = Pattern.compile("^(jar:|wsjar:|zip:|vfsfile:|code-source:)?(file:)?(.*?)(\\!/|\\.jar/)(.*)"); + private static final Pattern JAR_PATTERN = Pattern.compile( + "^(jar:|wsjar:|zip:|vfsfile:|code-source:)?(file:)?(.*?)(!/|\\.jar/)(.*)"); private static final int JAR_FILE_PATH = 3; - protected static final Map files = Collections.synchronizedMap(new HashMap()); - private static final List lazyMonitoredFilesCache = Collections.synchronizedList(new ArrayList()); + protected static final Map files = Collections.synchronizedMap(new HashMap<>()); + private static final List lazyMonitoredFilesCache = Collections.synchronizedList(new ArrayList<>()); protected boolean reloadingConfigs = false; @@ -117,11 +120,7 @@ public void monitorFile(URL fileUrl) { } else { revision = FileRevision.build(fileUrl); } - if (revision == null) { - files.put(fileName, Revision.build(fileUrl)); - } else { - files.put(fileName, revision); - } + files.put(fileName, requireNonNullElseGet(revision, () -> Revision.build(fileUrl))); } /** diff --git a/core/src/main/java/com/opensymphony/xwork2/util/fs/DefaultFileManagerFactory.java b/core/src/main/java/com/opensymphony/xwork2/util/fs/DefaultFileManagerFactory.java index ad9b676fad..d5cf1b06c2 100644 --- a/core/src/main/java/com/opensymphony/xwork2/util/fs/DefaultFileManagerFactory.java +++ b/core/src/main/java/com/opensymphony/xwork2/util/fs/DefaultFileManagerFactory.java @@ -58,7 +58,7 @@ public void setReloadingConfigs(String reloadingConfigs) { public FileManager getFileManager() { if (fileManagerHolder != null) { - return fileManagerHolder.getFileManager(); + return fileManagerHolder.fileManager(); } FileManager fileManager = lookupFileManager(); @@ -103,17 +103,7 @@ private FileManager lookupFileManager() { return null; } - private static class FileManagerHolder { - - private final FileManager fileManager; - - public FileManagerHolder(FileManager fileManager) { - this.fileManager = fileManager; - } - - public FileManager getFileManager() { - return fileManager; - } + private record FileManagerHolder(FileManager fileManager) { } } diff --git a/core/src/main/java/com/opensymphony/xwork2/util/fs/FileRevision.java b/core/src/main/java/com/opensymphony/xwork2/util/fs/FileRevision.java index 7279bcca4f..0c93724e9d 100644 --- a/core/src/main/java/com/opensymphony/xwork2/util/fs/FileRevision.java +++ b/core/src/main/java/com/opensymphony/xwork2/util/fs/FileRevision.java @@ -27,8 +27,8 @@ */ public class FileRevision extends Revision { - private File file; - private long lastModified; + private final File file; + private final long lastModified; public static Revision build(URL fileUrl) { File file; @@ -63,6 +63,7 @@ public File getFile() { return file; } + @Override public boolean needsReloading() { return this.lastModified < this.file.lastModified(); } diff --git a/core/src/main/java/com/opensymphony/xwork2/util/fs/JarEntryRevision.java b/core/src/main/java/com/opensymphony/xwork2/util/fs/JarEntryRevision.java index 9fb05348e2..130068ec57 100644 --- a/core/src/main/java/com/opensymphony/xwork2/util/fs/JarEntryRevision.java +++ b/core/src/main/java/com/opensymphony/xwork2/util/fs/JarEntryRevision.java @@ -19,11 +19,9 @@ package com.opensymphony.xwork2.util.fs; import com.opensymphony.xwork2.FileManager; -import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; -import java.io.IOException; -import java.net.JarURLConnection; import java.net.URL; /** @@ -31,10 +29,10 @@ */ public class JarEntryRevision extends Revision { - private static Logger LOG = LogManager.getLogger(JarEntryRevision.class); + private static final Logger LOG = LogManager.getLogger(JarEntryRevision.class); - private URL jarFileURL; - private long lastModified; + private final URL jarFileURL; + private final long lastModified; public static Revision build(URL fileUrl, FileManager fileManager) { try (StrutsJarURLConnection conn = StrutsJarURLConnection.openConnection(fileUrl)) { @@ -59,6 +57,7 @@ private JarEntryRevision(URL jarFileURL, long lastModified) { this.lastModified = lastModified; } + @Override public boolean needsReloading() { long lastLastModified = lastModified; try (StrutsJarURLConnection conn = StrutsJarURLConnection.openConnection(jarFileURL)) { diff --git a/core/src/main/java/com/opensymphony/xwork2/util/fs/StrutsJarURLConnection.java b/core/src/main/java/com/opensymphony/xwork2/util/fs/StrutsJarURLConnection.java index e733ac7cea..52ad48b05d 100644 --- a/core/src/main/java/com/opensymphony/xwork2/util/fs/StrutsJarURLConnection.java +++ b/core/src/main/java/com/opensymphony/xwork2/util/fs/StrutsJarURLConnection.java @@ -20,12 +20,12 @@ import java.io.IOException; import java.io.InputStream; -import java.io.UnsupportedEncodingException; import java.net.JarURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; @@ -71,7 +71,7 @@ private StrutsJarURLConnection(URL url) throws IOException { /** * A fixed copy of {@link JarURLConnection#parseSpecs(URL)} */ - private void parseSpecs(URL url) throws MalformedURLException, UnsupportedEncodingException { + private void parseSpecs(URL url) throws MalformedURLException { String spec = url.getFile(); int separator = spec.indexOf("!/"); @@ -100,8 +100,8 @@ private void parseSpecs(URL url) throws MalformedURLException, UnsupportedEncodi /* if ! is the last letter of the innerURL, entryName is null */ if (++separator != spec.length()) { - entryName = spec.substring(separator, spec.length()); - entryName = URLDecoder.decode (entryName, "UTF-8"); + entryName = spec.substring(separator); + entryName = URLDecoder.decode(entryName, StandardCharsets.UTF_8); } } @@ -118,24 +118,20 @@ public void connect() throws IOException { try (final InputStream in = jarFileURL.openConnection().getInputStream()) { jarFile = AccessController.doPrivileged( - new PrivilegedExceptionAction() { - public JarFile run() throws IOException { - Path tmpFile = Files.createTempFile("jar_cache", null); + (PrivilegedExceptionAction) () -> { + Path tmpFile = Files.createTempFile("jar_cache", null); + try { + Files.copy(in, tmpFile, StandardCopyOption.REPLACE_EXISTING); + return new JarFile(tmpFile.toFile(), true, JarFile.OPEN_READ | JarFile.OPEN_DELETE); + } catch (Throwable thr) { try { - Files.copy(in, tmpFile, StandardCopyOption.REPLACE_EXISTING); - JarFile jarFile = new JarFile(tmpFile.toFile(), true, JarFile.OPEN_READ - | JarFile.OPEN_DELETE); - return jarFile; - } catch (Throwable thr) { - try { - Files.delete(tmpFile); - } catch (IOException ioe) { - thr.addSuppressed(ioe); - } - throw thr; - } finally { - in.close(); + Files.delete(tmpFile); + } catch (IOException ioe) { + thr.addSuppressed(ioe); } + throw thr; + } finally { + in.close(); } }); connected = true; diff --git a/core/src/main/java/com/opensymphony/xwork2/util/location/Locatable.java b/core/src/main/java/com/opensymphony/xwork2/util/location/Locatable.java index 64ad92390c..8d08b11a7a 100644 --- a/core/src/main/java/com/opensymphony/xwork2/util/location/Locatable.java +++ b/core/src/main/java/com/opensymphony/xwork2/util/location/Locatable.java @@ -25,8 +25,8 @@ public interface Locatable { /** * Get the location of this object - * + * * @return the location */ - public Location getLocation(); + Location getLocation(); } diff --git a/core/src/main/java/com/opensymphony/xwork2/util/location/LocatableProperties.java b/core/src/main/java/com/opensymphony/xwork2/util/location/LocatableProperties.java index 9c79adc5f1..008451fa7b 100644 --- a/core/src/main/java/com/opensymphony/xwork2/util/location/LocatableProperties.java +++ b/core/src/main/java/com/opensymphony/xwork2/util/location/LocatableProperties.java @@ -23,7 +23,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.io.Reader; import java.util.HashMap; import java.util.List; import java.util.Map; diff --git a/core/src/main/java/com/opensymphony/xwork2/util/location/Located.java b/core/src/main/java/com/opensymphony/xwork2/util/location/Located.java index 8986933441..8e268f71e0 100644 --- a/core/src/main/java/com/opensymphony/xwork2/util/location/Located.java +++ b/core/src/main/java/com/opensymphony/xwork2/util/location/Located.java @@ -22,21 +22,22 @@ * Base class for location aware objects */ public abstract class Located implements Locatable { - + protected Location location; - + /** * Get the location of this object - * + * * @return the location */ + @Override public Location getLocation() { return location; } - + /** * Set the location of this object - * + * * @param loc the location */ public void setLocation(Location loc) { diff --git a/core/src/main/java/com/opensymphony/xwork2/util/location/Location.java b/core/src/main/java/com/opensymphony/xwork2/util/location/Location.java index 7e6fc67690..84f100f36f 100644 --- a/core/src/main/java/com/opensymphony/xwork2/util/location/Location.java +++ b/core/src/main/java/com/opensymphony/xwork2/util/location/Location.java @@ -22,46 +22,46 @@ /** - * A location in a resource. The location is composed of the URI of the resource, and + * A location in a resource. The location is composed of the URI of the resource, and * the line and column numbers within that resource (when available), along with a description. *

      * Locations are mostly provided by {@link Locatable}s objects. */ public interface Location { - + /** * Constant for unknown locations. */ - public static final Location UNKNOWN = LocationImpl.UNKNOWN; - + Location UNKNOWN = LocationImpl.UNKNOWN; + /** * Get the description of this location - * + * * @return the description (can be null) */ String getDescription(); - + /** * Get the URI of this location - * + * * @return the URI (null if unknown). */ String getURI(); /** * Get the line number of this location - * + * * @return the line number (-1 if unknown) */ int getLineNumber(); - + /** * Get the column number of this location - * + * * @return the column number (-1 if unknown) */ int getColumnNumber(); - + /** * Gets a source code snippet with the default padding * diff --git a/core/src/main/java/com/opensymphony/xwork2/util/location/LocationImpl.java b/core/src/main/java/com/opensymphony/xwork2/util/location/LocationImpl.java index 50a1809fc4..3f3fc63f1d 100644 --- a/core/src/main/java/com/opensymphony/xwork2/util/location/LocationImpl.java +++ b/core/src/main/java/com/opensymphony/xwork2/util/location/LocationImpl.java @@ -23,6 +23,7 @@ import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; +import java.io.Serial; import java.io.Serializable; import java.net.URL; import java.util.ArrayList; @@ -155,7 +156,7 @@ public List getSnippet(int padding) { List snippet = new ArrayList<>(); if (getLineNumber() > 0) { try (InputStream in = new URL(getURI()).openStream(); - BufferedReader reader = new BufferedReader(new InputStreamReader(in));) { + BufferedReader reader = new BufferedReader(new InputStreamReader(in))) { int lineno = 0; int errno = getLineNumber(); String line; @@ -178,8 +179,7 @@ public boolean equals(Object obj) { return true; } - if (obj instanceof Location) { - Location other = (Location)obj; + if (obj instanceof Location other) { return this.line == other.getLineNumber() && this.column == other.getColumnNumber() && testEquals(this.uri, other.getURI()) && testEquals(this.description, other.getDescription()); @@ -207,6 +207,7 @@ public String toString() { * * @return resolved location as object */ + @Serial private Object readResolve() { return this.equals(Location.UNKNOWN) ? Location.UNKNOWN : this; } diff --git a/core/src/main/java/com/opensymphony/xwork2/util/location/LocationUtils.java b/core/src/main/java/com/opensymphony/xwork2/util/location/LocationUtils.java index 138bd48ede..28a677f632 100644 --- a/core/src/main/java/com/opensymphony/xwork2/util/location/LocationUtils.java +++ b/core/src/main/java/com/opensymphony/xwork2/util/location/LocationUtils.java @@ -19,7 +19,6 @@ package com.opensymphony.xwork2.util.location; import com.opensymphony.xwork2.util.ClassLoaderUtil; - import org.apache.struts2.config.StrutsJavaConfiguration; import org.w3c.dom.Element; import org.xml.sax.Locator; @@ -36,14 +35,14 @@ * Location-related utility methods. */ public class LocationUtils { - + /** * The string representation of an unknown location: "[unknown location]". */ public static final String UNKNOWN_STRING = "[unknown location]"; private static List> finders = new ArrayList<>(); - + /** * An finder or object locations */ @@ -61,7 +60,7 @@ public interface LocationFinder { private LocationUtils() { // Forbid instanciation } - + /** * Builds a string representation of a location, in the * "descripton - uri:line:column" @@ -86,7 +85,7 @@ public static String toString(Location location) { } else { result.append(UNKNOWN_STRING); } - + return result.toString(); } @@ -94,12 +93,12 @@ public static String toString(Location location) { * Parse a location string of the form "uri:line:column" (e.g. * "path/to/file.xml:3:40") to a Location object. Additionally, a description may * also optionally be present, separated with an hyphen (e.g. "foo - path/to/file.xml:3.40"). - * + * * @param text the text to parse * @return the location (possibly null if text was null or in an incorrect format) */ public static LocationImpl parse(String text) throws IllegalArgumentException { - if (text == null || text.length() == 0) { + if (text == null || text.isEmpty()) { return null; } @@ -113,12 +112,12 @@ public static LocationImpl parse(String text) throws IllegalArgumentException { description = null; uriStart = 0; } - + try { int colSep = text.lastIndexOf(':'); if (colSep > -1) { int column = Integer.parseInt(text.substring(colSep + 1)); - + int lineSep = text.lastIndexOf(':', colSep - 1); if (lineSep > -1) { int line = Integer.parseInt(text.substring(lineSep + 1, colSep)); @@ -133,13 +132,13 @@ public static LocationImpl parse(String text) throws IllegalArgumentException { } catch(Exception e) { // Ignore: handled below } - + return LocationImpl.UNKNOWN; } /** * Checks if a location is known, i.e. it is not null nor equal to {@link Location#UNKNOWN}. - * + * * @param location the location to check * @return true if the location is known */ @@ -149,7 +148,7 @@ public static boolean isKnown(Location location) { /** * Checks if a location is unknown, i.e. it is either null or equal to {@link Location#UNKNOWN}. - * + * * @param location the location to check * @return true if the location is unknown */ @@ -178,7 +177,7 @@ public static boolean isUnknown(Location location) { * LocationUtils.addFinder(myFinder); * } * - * + * * @param finder the location finder to add */ public static void addFinder(LocationFinder finder) { @@ -190,26 +189,26 @@ public static void addFinder(LocationFinder finder) { // Update a clone of the current finder list to avoid breaking // any iteration occuring in another thread. List> newFinders = new ArrayList<>(finders); - newFinders.add(new WeakReference(finder)); + newFinders.add(new WeakReference<>(finder)); finders = newFinders; } } - + /** * Get the location of an object. Some well-known located classes built in the JDK are handled * by this method. Handling of other located classes can be handled by adding new location finders. - * + * * @param obj the object of which to get the location * @return the object's location, or {@link Location#UNKNOWN} if no location could be found */ public static Location getLocation(Object obj) { return getLocation(obj, null); } - + /** * Get the location of an object. Some well-known located classes built in the JDK are handled * by this method. Handling of other located classes can be handled by adding new location finders. - * + * * @param obj the object of which to get the location * @param description an optional description of the object's location, used if a Location object * has to be created. @@ -219,23 +218,21 @@ public static Location getLocation(Object obj, String description) { if (obj instanceof Location) { return (Location) obj; } - + if (obj instanceof Locatable) { return ((Locatable)obj).getLocation(); } - + // Check some well-known locatable exceptions - if (obj instanceof SAXParseException) { - SAXParseException spe = (SAXParseException)obj; + if (obj instanceof SAXParseException spe) { if (spe.getSystemId() != null) { return new LocationImpl(description, spe.getSystemId(), spe.getLineNumber(), spe.getColumnNumber()); } else { return Location.UNKNOWN; } } - - if (obj instanceof TransformerException) { - TransformerException ex = (TransformerException)obj; + + if (obj instanceof TransformerException ex) { SourceLocator locator = ex.getLocator(); if (locator != null && locator.getSystemId() != null) { return new LocationImpl(description, locator.getSystemId(), locator.getLineNumber(), locator.getColumnNumber()); @@ -243,28 +240,25 @@ public static Location getLocation(Object obj, String description) { return Location.UNKNOWN; } } - - if (obj instanceof Locator) { - Locator locator = (Locator)obj; + + if (obj instanceof Locator locator) { if (locator.getSystemId() != null) { return new LocationImpl(description, locator.getSystemId(), locator.getLineNumber(), locator.getColumnNumber()); } else { return Location.UNKNOWN; } } - + if (obj instanceof Element) { return LocationAttributes.getLocation((Element)obj); } List> currentFinders = finders; // Keep the current list - int size = currentFinders.size(); - for (int i = 0; i < size; i++) { - WeakReference ref = currentFinders.get(i); + for (WeakReference ref : currentFinders) { LocationFinder finder = ref.get(); if (finder == null) { // This finder was garbage collected: update finders - synchronized(LocationFinder.class) { + synchronized (LocationFinder.class) { // Update a clone of the current list to avoid breaking current iterations List> newFinders = new ArrayList<>(finders); newFinders.remove(ref); @@ -278,33 +272,30 @@ public static Location getLocation(Object obj, String description) { } } - if (obj instanceof Throwable) { - Throwable t = (Throwable) obj; - StackTraceElement[] stack = t.getStackTrace(); - if (stack != null && stack.length > 0) { - StackTraceElement trace = stack[0]; - if (trace.getLineNumber() >= 0) { - String uri = trace.getClassName(); - if (trace.getFileName() != null) { - uri = uri.replace('.','/'); - uri = uri.substring(0, uri.lastIndexOf('/') + 1); - uri = uri + trace.getFileName(); - URL url = ClassLoaderUtil.getResource(uri, LocationUtils.class); - if (url != null) { - uri = url.toString(); - } - } - if (description == null) { - StringBuilder sb = new StringBuilder(); - sb.append("Class: ").append(trace.getClassName()).append("\n"); - sb.append("File: ").append(trace.getFileName()).append("\n"); - sb.append("Method: ").append(trace.getMethodName()).append("\n"); - sb.append("Line: ").append(trace.getLineNumber()); - description = sb.toString(); - } - return new LocationImpl(description, uri, trace.getLineNumber(), -1); - } - } + if (obj instanceof Throwable t) { + StackTraceElement[] stack = t.getStackTrace(); + if (stack != null && stack.length > 0) { + StackTraceElement trace = stack[0]; + if (trace.getLineNumber() >= 0) { + String uri = trace.getClassName(); + if (trace.getFileName() != null) { + uri = uri.replace('.', '/'); + uri = uri.substring(0, uri.lastIndexOf('/') + 1); + uri = uri + trace.getFileName(); + URL url = ClassLoaderUtil.getResource(uri, LocationUtils.class); + if (url != null) { + uri = url.toString(); + } + } + if (description == null) { + description = "Class: " + trace.getClassName() + "\n" + + "File: " + trace.getFileName() + "\n" + + "Method: " + trace.getMethodName() + "\n" + + "Line: " + trace.getLineNumber(); + } + return new LocationImpl(description, uri, trace.getLineNumber(), -1); + } + } } if (obj instanceof StrutsJavaConfiguration) { diff --git a/core/src/main/java/com/opensymphony/xwork2/util/reflection/ReflectionContextState.java b/core/src/main/java/com/opensymphony/xwork2/util/reflection/ReflectionContextState.java index 7ee435d98d..c3556cfee2 100644 --- a/core/src/main/java/com/opensymphony/xwork2/util/reflection/ReflectionContextState.java +++ b/core/src/main/java/com/opensymphony/xwork2/util/reflection/ReflectionContextState.java @@ -34,8 +34,8 @@ public class ReflectionContextState { private static final String GETTING_BY_KEY_PROPERTY = "xwork.getting.by.key.property"; private static final String SET_MAP_KEY = "set.map.key"; - public static final String CURRENT_PROPERTY_PATH="current.property.path"; - public static final String FULL_PROPERTY_PATH="current.property.path"; + public static final String CURRENT_PROPERTY_PATH = "current.property.path"; + public static final String FULL_PROPERTY_PATH = "current.property.path"; // TODO: Probably a bug public static final String CREATE_NULL_OBJECTS = "xwork.NullHandler.createNullObjects"; public static final String DENY_METHOD_EXECUTION = "xwork.MethodAccessor.denyMethodExecution"; public static final String DENY_INDEXED_ACCESS_EXECUTION = "xwork.IndexedPropertyAccessor.denyMethodExecution"; @@ -52,19 +52,19 @@ public static void setCreatingNullObjects(Map context, boolean c public static boolean isGettingByKeyProperty(Map context) { return getBooleanProperty(GETTING_BY_KEY_PROPERTY, context); } - + public static void setDenyMethodExecution(Map context, boolean denyMethodExecution) { setBooleanValue(ReflectionContextState.DENY_METHOD_EXECUTION, context, denyMethodExecution); } - + public static boolean isDenyMethodExecution(Map context) { return getBooleanProperty(ReflectionContextState.DENY_METHOD_EXECUTION, context); } public static void setGettingByKeyProperty(Map context, boolean gettingByKeyProperty) { setBooleanValue(GETTING_BY_KEY_PROPERTY, context, gettingByKeyProperty); - } - + } + public static boolean isReportingConversionErrors(Map context) { return getBooleanProperty(XWorkConverter.REPORT_CONVERSION_ERRORS, context); } @@ -74,7 +74,7 @@ public static void setReportingConversionErrors(Map context, boo } public static Class getLastBeanClassAccessed(Map context) { - return (Class)context.get(XWorkConverter.LAST_BEAN_CLASS_ACCESSED); + return (Class) context.get(XWorkConverter.LAST_BEAN_CLASS_ACCESSED); } public static void setLastBeanPropertyAccessed(Map context, String property) { @@ -105,26 +105,22 @@ public static void setLastBeanClassAccessed(Map context, Class c * @return current property path */ public static String getCurrentPropertyPath(Map context) { - return (String)context.get(CURRENT_PROPERTY_PATH); + return (String) context.get(CURRENT_PROPERTY_PATH); } public static String getFullPropertyPath(Map context) { - return (String)context.get(FULL_PROPERTY_PATH); + return (String) context.get(FULL_PROPERTY_PATH); } public static void setFullPropertyPath(Map context, String path) { context.put(FULL_PROPERTY_PATH, path); - } public static void updateCurrentPropertyPath(Map context, Object name) { - String currentPath=getCurrentPropertyPath(context); - if (name!=null) { + String currentPath = getCurrentPropertyPath(context); + if (name != null) { if (currentPath!=null) { - StringBuilder sb = new StringBuilder(currentPath); - sb.append("."); - sb.append(name.toString()); - currentPath = sb.toString(); + currentPath = currentPath + "." + name; } else { currentPath = name.toString(); } @@ -133,8 +129,8 @@ public static void updateCurrentPropertyPath(Map context, Object } public static void setSetMap(Map context, Map setMap, String path) { - Map> mapOfSetMaps=(Map)context.get(SET_MAP_KEY); - if (mapOfSetMaps==null) { + Map> mapOfSetMaps = (Map) context.get(SET_MAP_KEY); + if (mapOfSetMaps == null) { mapOfSetMaps = new HashMap<>(); context.put(SET_MAP_KEY, mapOfSetMaps); } @@ -142,20 +138,20 @@ public static void setSetMap(Map context, Map se } public static Map getSetMap(Map context, String path) { - Map> mapOfSetMaps=(Map)context.get(SET_MAP_KEY); - if (mapOfSetMaps==null) { + Map> mapOfSetMaps = (Map) context.get(SET_MAP_KEY); + if (mapOfSetMaps == null) { return null; } return mapOfSetMaps.get(path); } private static boolean getBooleanProperty(String property, Map context) { - Boolean myBool=(Boolean)context.get(property); - return (myBool==null)?false:myBool.booleanValue(); + Boolean myBool = (Boolean) context.get(property); + return myBool != null && myBool; } private static void setBooleanValue(String property, Map context, boolean value) { - context.put(property, new Boolean(value)); + context.put(property, value); } /** @@ -166,14 +162,12 @@ public static void clearCurrentPropertyPath(Map context) { } - public static void clear(Map context) { - if (context != null) { - context.put(XWorkConverter.LAST_BEAN_CLASS_ACCESSED,null); - context.put(XWorkConverter.LAST_BEAN_PROPERTY_ACCESSED,null); - - context.put(CURRENT_PROPERTY_PATH,null); - context.put(FULL_PROPERTY_PATH,null); - } - - } + public static void clear(Map context) { + if (context != null) { + context.put(XWorkConverter.LAST_BEAN_CLASS_ACCESSED, null); + context.put(XWorkConverter.LAST_BEAN_PROPERTY_ACCESSED, null); + context.put(CURRENT_PROPERTY_PATH, null); + context.put(FULL_PROPERTY_PATH, null); + } + } } diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/AnnotationValidationConfigurationBuilder.java b/core/src/main/java/com/opensymphony/xwork2/validator/AnnotationValidationConfigurationBuilder.java index 64f46d58a2..f1de89269b 100644 --- a/core/src/main/java/com/opensymphony/xwork2/validator/AnnotationValidationConfigurationBuilder.java +++ b/core/src/main/java/com/opensymphony/xwork2/validator/AnnotationValidationConfigurationBuilder.java @@ -19,7 +19,26 @@ package com.opensymphony.xwork2.validator; import com.opensymphony.xwork2.util.AnnotationUtils; -import com.opensymphony.xwork2.validator.annotations.*; +import com.opensymphony.xwork2.validator.annotations.ConditionalVisitorFieldValidator; +import com.opensymphony.xwork2.validator.annotations.ConversionErrorFieldValidator; +import com.opensymphony.xwork2.validator.annotations.CreditCardValidator; +import com.opensymphony.xwork2.validator.annotations.CustomValidator; +import com.opensymphony.xwork2.validator.annotations.DateRangeFieldValidator; +import com.opensymphony.xwork2.validator.annotations.DoubleRangeFieldValidator; +import com.opensymphony.xwork2.validator.annotations.EmailValidator; +import com.opensymphony.xwork2.validator.annotations.ExpressionValidator; +import com.opensymphony.xwork2.validator.annotations.FieldExpressionValidator; +import com.opensymphony.xwork2.validator.annotations.IntRangeFieldValidator; +import com.opensymphony.xwork2.validator.annotations.LongRangeFieldValidator; +import com.opensymphony.xwork2.validator.annotations.RegexFieldValidator; +import com.opensymphony.xwork2.validator.annotations.RequiredFieldValidator; +import com.opensymphony.xwork2.validator.annotations.RequiredStringValidator; +import com.opensymphony.xwork2.validator.annotations.ShortRangeFieldValidator; +import com.opensymphony.xwork2.validator.annotations.StringLengthFieldValidator; +import com.opensymphony.xwork2.validator.annotations.UrlValidator; +import com.opensymphony.xwork2.validator.annotations.ValidationParameter; +import com.opensymphony.xwork2.validator.annotations.Validations; +import com.opensymphony.xwork2.validator.annotations.VisitorFieldValidator; import org.apache.commons.lang3.StringUtils; import java.lang.annotation.Annotation; @@ -27,7 +46,12 @@ import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; -import java.util.*; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; /** * AnnotationValidationConfigurationBuilder @@ -38,7 +62,7 @@ */ public class AnnotationValidationConfigurationBuilder { - private ValidatorFactory validatorFactory; + private final ValidatorFactory validatorFactory; public AnnotationValidationConfigurationBuilder(ValidatorFactory fac) { this.validatorFactory = fac; @@ -53,13 +77,11 @@ private List processAnnotations(Object o) { Annotation[] annotations = null; - if (o instanceof Class) { - Class clazz = (Class) o; + if (o instanceof Class clazz) { annotations = clazz.getAnnotations(); } - if (o instanceof Method) { - Method method = (Method) o; + if (o instanceof Method method) { fieldName = AnnotationUtils.resolvePropertyName(method); methodName = method.getName(); @@ -74,24 +96,21 @@ private List processAnnotations(Object o) { processValidationAnnotation(a, fieldName, methodName, result); } // Process single custom validator - else if (a instanceof ExpressionValidator) { - ExpressionValidator v = (ExpressionValidator) a; + else if (a instanceof ExpressionValidator v) { ValidatorConfig temp = processExpressionValidatorAnnotation(v, fieldName, methodName); if (temp != null) { result.add(temp); } } // Process single custom validator - else if (a instanceof CustomValidator) { - CustomValidator v = (CustomValidator) a; + else if (a instanceof CustomValidator v) { ValidatorConfig temp = processCustomValidatorAnnotation(v, fieldName, methodName); if (temp != null) { result.add(temp); } } // Process ConversionErrorFieldValidator - else if (a instanceof ConversionErrorFieldValidator) { - ConversionErrorFieldValidator v = (ConversionErrorFieldValidator) a; + else if (a instanceof ConversionErrorFieldValidator v) { ValidatorConfig temp = processConversionErrorFieldValidatorAnnotation(v, fieldName, methodName); if (temp != null) { result.add(temp); @@ -99,8 +118,7 @@ else if (a instanceof ConversionErrorFieldValidator) { } // Process DateRangeFieldValidator - else if (a instanceof DateRangeFieldValidator) { - DateRangeFieldValidator v = (DateRangeFieldValidator) a; + else if (a instanceof DateRangeFieldValidator v) { ValidatorConfig temp = processDateRangeFieldValidatorAnnotation(v, fieldName, methodName); if (temp != null) { result.add(temp); @@ -108,88 +126,77 @@ else if (a instanceof DateRangeFieldValidator) { } // Process EmailValidator - else if (a instanceof EmailValidator) { - EmailValidator v = (EmailValidator) a; + else if (a instanceof EmailValidator v) { ValidatorConfig temp = processEmailValidatorAnnotation(v, fieldName, methodName); if (temp != null) { result.add(temp); } } // Process CrediCardValidator - else if (a instanceof CreditCardValidator) { - CreditCardValidator v = (CreditCardValidator) a; + else if (a instanceof CreditCardValidator v) { ValidatorConfig temp = processCreditCardValidatorAnnotation(v, fieldName, methodName); if (temp != null) { result.add(temp); } } // Process FieldExpressionValidator - else if (a instanceof FieldExpressionValidator) { - FieldExpressionValidator v = (FieldExpressionValidator) a; + else if (a instanceof FieldExpressionValidator v) { ValidatorConfig temp = processFieldExpressionValidatorAnnotation(v, fieldName, methodName); if (temp != null) { result.add(temp); } } // Process IntRangeFieldValidator - else if (a instanceof IntRangeFieldValidator) { - IntRangeFieldValidator v = (IntRangeFieldValidator) a; + else if (a instanceof IntRangeFieldValidator v) { ValidatorConfig temp = processIntRangeFieldValidatorAnnotation(v, fieldName, methodName); if (temp != null) { result.add(temp); } } // Process LongRangeFieldValidator - else if (a instanceof LongRangeFieldValidator) { - LongRangeFieldValidator v = (LongRangeFieldValidator) a; + else if (a instanceof LongRangeFieldValidator v) { ValidatorConfig temp = processLongRangeFieldValidatorAnnotation(v, fieldName, methodName); if (temp != null) { result.add(temp); } } // Process ShortRangeFieldValidator - else if (a instanceof ShortRangeFieldValidator) { - ShortRangeFieldValidator v = (ShortRangeFieldValidator) a; + else if (a instanceof ShortRangeFieldValidator v) { ValidatorConfig temp = processShortRangeFieldValidatorAnnotation(v, fieldName, methodName); if (temp != null) { result.add(temp); } } // Process DoubleRangeFieldValidator - else if (a instanceof DoubleRangeFieldValidator) { - DoubleRangeFieldValidator v = (DoubleRangeFieldValidator) a; + else if (a instanceof DoubleRangeFieldValidator v) { ValidatorConfig temp = processDoubleRangeFieldValidatorAnnotation(v, fieldName, methodName); if (temp != null) { result.add(temp); } } // Process RequiredFieldValidator - else if (a instanceof RequiredFieldValidator) { - RequiredFieldValidator v = (RequiredFieldValidator) a; + else if (a instanceof RequiredFieldValidator v) { ValidatorConfig temp = processRequiredFieldValidatorAnnotation(v, fieldName, methodName); if (temp != null) { result.add(temp); } } // Process RequiredStringValidator - else if (a instanceof RequiredStringValidator) { - RequiredStringValidator v = (RequiredStringValidator) a; + else if (a instanceof RequiredStringValidator v) { ValidatorConfig temp = processRequiredStringValidatorAnnotation(v, fieldName, methodName); if (temp != null) { result.add(temp); } } // Process StringLengthFieldValidator - else if (a instanceof StringLengthFieldValidator) { - StringLengthFieldValidator v = (StringLengthFieldValidator) a; + else if (a instanceof StringLengthFieldValidator v) { ValidatorConfig temp = processStringLengthFieldValidatorAnnotation(v, fieldName, methodName); if (temp != null) { result.add(temp); } } // Process UrlValidator - else if (a instanceof UrlValidator) { - UrlValidator v = (UrlValidator) a; + else if (a instanceof UrlValidator v) { ValidatorConfig temp = processUrlValidatorAnnotation(v, fieldName, methodName); if (temp != null) { result.add(temp); @@ -197,24 +204,21 @@ else if (a instanceof UrlValidator) { } // Process ConditionalVisitorFieldValidator - else if (a instanceof ConditionalVisitorFieldValidator) { - ConditionalVisitorFieldValidator v = (ConditionalVisitorFieldValidator) a; + else if (a instanceof ConditionalVisitorFieldValidator v) { ValidatorConfig temp = processConditionalVisitorFieldValidatorAnnotation(v, fieldName, methodName); if (temp != null) { result.add(temp); } } // Process VisitorFieldValidator - else if (a instanceof VisitorFieldValidator) { - VisitorFieldValidator v = (VisitorFieldValidator) a; + else if (a instanceof VisitorFieldValidator v) { ValidatorConfig temp = processVisitorFieldValidatorAnnotation(v, fieldName, methodName); if (temp != null) { result.add(temp); } } // Process RegexFieldValidator - else if (a instanceof RegexFieldValidator) { - RegexFieldValidator v = (RegexFieldValidator) a; + else if (a instanceof RegexFieldValidator v) { ValidatorConfig temp = processRegexFieldValidatorAnnotation(v, fieldName, methodName); if (temp != null) { result.add(temp); @@ -413,8 +417,7 @@ private ValidatorConfig processCustomValidatorAnnotation(CustomValidator v, Stri if (recursedAnnotations != null) { for (Annotation a2 : recursedAnnotations) { - if (a2 instanceof ValidationParameter) { - ValidationParameter parameter = (ValidationParameter) a2; + if (a2 instanceof ValidationParameter parameter) { String parameterName = parameter.name(); String parameterValue = parameter.value(); params.put(parameterName, parameterValue); @@ -658,10 +661,10 @@ private ValidatorConfig processIntRangeFieldValidatorAnnotation(IntRangeFieldVal params.put("fieldName", v.fieldName()); } - if (v.min() != null && v.min().length() > 0) { + if (v.min() != null && !v.min().isEmpty()) { params.put("min", v.min()); } - if (v.max() != null && v.max().length() > 0) { + if (v.max() != null && !v.max().isEmpty()) { params.put("max", v.max()); } if (StringUtils.isNotEmpty(v.maxExpression())) { @@ -693,10 +696,10 @@ private ValidatorConfig processLongRangeFieldValidatorAnnotation(LongRangeFieldV params.put("fieldName", v.fieldName()); } - if (v.min() != null && v.min().length() > 0) { + if (v.min() != null && !v.min().isEmpty()) { params.put("min", v.min()); } - if (v.max() != null && v.max().length() > 0) { + if (v.max() != null && !v.max().isEmpty()) { params.put("max", v.max()); } if (StringUtils.isNotEmpty(v.maxExpression())) { @@ -759,21 +762,21 @@ private ValidatorConfig processDoubleRangeFieldValidatorAnnotation(DoubleRangeFi if (fieldName != null) { params.put("fieldName", fieldName); - } else if (v.fieldName() != null && v.fieldName().length() > 0) { + } else if (v.fieldName() != null && !v.fieldName().isEmpty()) { params.put("fieldName", v.fieldName()); } - if (v.minInclusive() != null && v.minInclusive().length() > 0) { + if (v.minInclusive() != null && !v.minInclusive().isEmpty()) { params.put("minInclusive", v.minInclusive()); } - if (v.maxInclusive() != null && v.maxInclusive().length() > 0) { + if (v.maxInclusive() != null && !v.maxInclusive().isEmpty()) { params.put("maxInclusive", v.maxInclusive()); } - if (v.minExclusive() != null && v.minExclusive().length() > 0) { + if (v.minExclusive() != null && !v.minExclusive().isEmpty()) { params.put("minExclusive", v.minExclusive()); } - if (v.maxExclusive() != null && v.maxExclusive().length() > 0) { + if (v.maxExclusive() != null && !v.maxExclusive().isEmpty()) { params.put("maxExclusive", v.maxExclusive()); } @@ -877,14 +880,14 @@ private ValidatorConfig processDateRangeFieldValidatorAnnotation(DateRangeFieldV if (fieldName != null) { params.put("fieldName", fieldName); - } else if (v.fieldName() != null && v.fieldName().length() > 0) { + } else if (v.fieldName() != null && !v.fieldName().isEmpty()) { params.put("fieldName", v.fieldName()); } - if (v.min() != null && v.min().length() > 0) { + if (v.min() != null && !v.min().isEmpty()) { final Date minDate = parseDateString(v.min(), v.dateFormat()); params.put("min", minDate == null ? v.min() : minDate); } - if (v.max() != null && v.max().length() > 0) { + if (v.max() != null && !v.max().isEmpty()) { final Date maxDate = parseDateString(v.max(), v.dateFormat()); params.put("max", maxDate == null ? v.max() : maxDate); } @@ -932,22 +935,14 @@ private ValidatorConfig processConversionErrorFieldValidatorAnnotation(Conversio public List buildAnnotationClassValidatorConfigs(Class aClass) { - List result = new ArrayList<>(); - List temp = processAnnotations(aClass); - if (temp != null) { - result.addAll(temp); - } + List result = new ArrayList<>(temp); Method[] methods = aClass.getDeclaredMethods(); - if (methods != null) { - for (Method method : methods) { - temp = processAnnotations(method); - if (temp != null) { - result.addAll(temp); - } - } + for (Method method : methods) { + temp = processAnnotations(method); + result.addAll(temp); } return result; diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/DefaultValidatorFactory.java b/core/src/main/java/com/opensymphony/xwork2/validator/DefaultValidatorFactory.java index f5f781ead0..5ae3ee8c07 100644 --- a/core/src/main/java/com/opensymphony/xwork2/validator/DefaultValidatorFactory.java +++ b/core/src/main/java/com/opensymphony/xwork2/validator/DefaultValidatorFactory.java @@ -34,7 +34,12 @@ import java.io.InputStream; import java.net.URI; import java.net.URL; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; @@ -48,7 +53,7 @@ public class DefaultValidatorFactory implements ValidatorFactory, Initializable { protected Map validators = new HashMap<>(); - private static Logger LOG = LogManager.getLogger(DefaultValidatorFactory.class); + private static final Logger LOG = LogManager.getLogger(DefaultValidatorFactory.class); protected ObjectFactory objectFactory; protected ValidatorFileParser validatorFileParser; @@ -63,6 +68,7 @@ public void init() { parseValidators(); } + @Override public Validator getValidator(ValidatorConfig cfg) { String className = lookupRegisteredValidatorType(cfg.getType()); @@ -89,11 +95,13 @@ public Validator getValidator(ValidatorConfig cfg) { return validator; } + @Override public void registerValidator(String name, String className) { LOG.debug("Registering validator of class {} with name {}", className, name); validators.put(name, className); } + @Override public String lookupRegisteredValidatorType(String name) { // lookup the validator class mapped to the type name String className = validators.get(name); @@ -118,11 +126,7 @@ private void parseValidators() { URI uri = new URI(u.toExternalForm().replaceAll(" ", "%20")); if (!uri.isOpaque() && "file".equalsIgnoreCase(uri.getScheme())) { File f = new File(uri); - FilenameFilter filter = new FilenameFilter() { - public boolean accept(File file, String fileName) { - return fileName.contains("-validators.xml"); - } - }; + FilenameFilter filter = (file, fileName) -> fileName.contains("-validators.xml"); // First check if this is a directory // If yes, then just do a "list" to get all files in this directory // and match the filenames with *-validators.xml. If the filename diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/DefaultValidatorFileParser.java b/core/src/main/java/com/opensymphony/xwork2/validator/DefaultValidatorFileParser.java index 5e36f81580..a576439db3 100644 --- a/core/src/main/java/com/opensymphony/xwork2/validator/DefaultValidatorFileParser.java +++ b/core/src/main/java/com/opensymphony/xwork2/validator/DefaultValidatorFileParser.java @@ -24,13 +24,23 @@ import com.opensymphony.xwork2.config.providers.XmlHelper; import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.util.DomHelper; -import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; -import org.w3c.dom.*; +import org.apache.logging.log4j.Logger; +import org.w3c.dom.CharacterData; +import org.w3c.dom.Comment; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.EntityReference; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import java.io.InputStream; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; /** * Parse the validation file. (eg. MyAction-validation.xml, MyAction-actionAlias-validation.xml) @@ -42,12 +52,12 @@ * @author Rob Harrop * @author Rene Gielen * @author Martin Gilday - * + * * @see com.opensymphony.xwork2.validator.ValidatorConfig */ public class DefaultValidatorFileParser implements ValidatorFileParser { - private static Logger LOG = LogManager.getLogger(DefaultValidatorFileParser.class); + private static final Logger LOG = LogManager.getLogger(DefaultValidatorFileParser.class); static final String DEFAULT_MULTI_TEXTVALUE_SEPARATOR = " "; static final String MULTI_TEXTVALUE_SEPARATOR_CONFIG_KEY = "xwork.validatorfileparser.multi_textvalue_separator"; @@ -86,18 +96,18 @@ public List parseActionValidatorConfigs(ValidatorFactory valida if (doc != null) { NodeList fieldNodes = doc.getElementsByTagName("field"); - // BUG: xw-305: Let validator be parsed first and hence added to + // BUG: xw-305: Let validator be parsed first and hence added to // the beginning of list and therefore evaluated first, so short-circuting // it will not cause field-level validator to be kicked off. { NodeList validatorNodes = doc.getElementsByTagName("validator"); - addValidatorConfigs(validatorFactory, validatorNodes, new HashMap(), validatorCfgs); + addValidatorConfigs(validatorFactory, validatorNodes, new HashMap<>(), validatorCfgs); } for (int i = 0; i < fieldNodes.getLength(); i++) { Element fieldElement = (Element) fieldNodes.item(i); String fieldName = fieldElement.getAttribute("name"); - Map extraParams = new HashMap(); + Map extraParams = new HashMap<>(); extraParams.put("fieldName", fieldName); NodeList validatorNodes = fieldElement.getElementsByTagName("field-validator"); @@ -130,7 +140,7 @@ public void parseValidatorDefinitions(Map validators, InputStrea try { // catch any problems here - objectFactory.buildValidator(className, new HashMap(), ActionContext.getContext().getContextMap()); + objectFactory.buildValidator(className, new HashMap<>(), ActionContext.getContext().getContextMap()); validators.put(name, className); } catch (Exception e) { throw new ConfigurationException("Unable to load validator class " + className, e, validatorElement); @@ -176,7 +186,7 @@ private void addValidatorConfigs(ValidatorFactory factory, NodeList validatorNod for (int j = 0; j < validatorNodes.getLength(); j++) { Element validatorElement = (Element) validatorNodes.item(j); String validatorType = validatorElement.getAttribute("type"); - Map params = new HashMap(extraParams); + Map params = new HashMap<>(extraParams); params.putAll(XmlHelper.getParams(validatorElement)); @@ -190,7 +200,7 @@ private void addValidatorConfigs(ValidatorFactory factory, NodeList validatorNod ValidatorConfig.Builder vCfg = new ValidatorConfig.Builder(validatorType) .addParams(params) .location(DomHelper.getLocationObject(validatorElement)) - .shortCircuit(Boolean.valueOf(validatorElement.getAttribute("short-circuit"))); + .shortCircuit(Boolean.parseBoolean(validatorElement.getAttribute("short-circuit"))); NodeList messageNodes = validatorElement.getElementsByTagName("message"); Element messageElement = (Element) messageNodes.item(0); @@ -203,7 +213,7 @@ private void addValidatorConfigs(ValidatorFactory factory, NodeList validatorNod String key = messageElement.getAttribute("key"); - if ((key != null) && (key.trim().length() > 0)) { + if (!key.trim().isEmpty()) { vCfg.messageKey(key); // Get the default message when pattern 2 is used. We are only interested in the @@ -223,7 +233,7 @@ private void addValidatorConfigs(ValidatorFactory factory, NodeList validatorNod // Sort the message param. those with keys as '1', '2', '3' etc. (numeric values) // are i18n message parameter, others are excluded. - TreeMap sortedMessageParameters = new TreeMap(); + TreeMap sortedMessageParameters = new TreeMap<>(); for (Map.Entry messageParamEntry : messageParams.entrySet()) { try { @@ -234,13 +244,13 @@ private void addValidatorConfigs(ValidatorFactory factory, NodeList validatorNod // ignore if its not numeric. } } - vCfg.messageParams(sortedMessageParameters.values().toArray(new String[sortedMessageParameters.values().size()])); + vCfg.messageParams(sortedMessageParameters.values().toArray(new String[0])); } else { - if (messageParams != null && (messageParams.size() > 0)) { + if (!messageParams.isEmpty()) { // we are i18n message parameters defined but no i18n message, // let's warn the user. if (LOG.isWarnEnabled()) { - LOG.warn("validator of type ["+validatorType+"] have i18n message parameters defined but no i18n message key, it's parameters will be ignored"); + LOG.warn("validator of type [{}] have i18n message parameters defined but no i18n message key, it's parameters will be ignored", validatorType); } } } diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/DelegatingValidatorContext.java b/core/src/main/java/com/opensymphony/xwork2/validator/DelegatingValidatorContext.java index 4760ef72a4..63e8c1d191 100644 --- a/core/src/main/java/com/opensymphony/xwork2/validator/DelegatingValidatorContext.java +++ b/core/src/main/java/com/opensymphony/xwork2/validator/DelegatingValidatorContext.java @@ -227,16 +227,16 @@ public boolean hasFieldErrors() { public TextProvider makeTextProvider(Object object, TextProviderFactory textProviderFactory) { // the object argument passed through here will most probably be an ActionSupport descendant which does // implements TextProvider. - if (object != null && object instanceof DelegatingValidatorContext) { - return ((DelegatingValidatorContext) object).getTextProvider(); + if (object instanceof DelegatingValidatorContext cast) { + return cast.getTextProvider(); } - if ((object != null) && (object instanceof TextProvider)) { - if (object instanceof CompositeTextProvider) { - return (CompositeTextProvider) object; + if (object instanceof TextProvider cast) { + if (object instanceof CompositeTextProvider castAgain) { + return castAgain; } return new CompositeTextProvider(new TextProvider[]{ - ((TextProvider) object), + cast, textProviderFactory.createInstance(object.getClass()) }); } else { @@ -318,7 +318,7 @@ public Locale toLocale(String localeStr) { */ private static class LoggingValidationAware implements ValidationAware { - private Logger log; + private final Logger log; public LoggingValidationAware(Class clazz) { log = LogManager.getLogger(clazz); diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/ValidatorConfig.java b/core/src/main/java/com/opensymphony/xwork2/validator/ValidatorConfig.java index 8df32577d9..4fb4933286 100644 --- a/core/src/main/java/com/opensymphony/xwork2/validator/ValidatorConfig.java +++ b/core/src/main/java/com/opensymphony/xwork2/validator/ValidatorConfig.java @@ -27,22 +27,22 @@ /** * Holds the necessary information for configuring an instance of a Validator. - * - * + * + * * @author James House * @author Rainer Hermanns * @author tm_jee - * @author Martin Gilday + * @author Martin Gilday */ public class ValidatorConfig extends Located { - private String type; + private final String type; private Map params; private String defaultMessage; private String messageKey; private boolean shortCircuit; private String[] messageParams; - + /** * @param validatorType validator type */ @@ -59,36 +59,36 @@ protected ValidatorConfig(ValidatorConfig orig) { this.shortCircuit = orig.shortCircuit; this.messageParams = orig.messageParams; } - + /** * @return Returns the defaultMessage for the validator. */ public String getDefaultMessage() { return defaultMessage; } - + /** * @return Returns the messageKey for the validator. */ public String getMessageKey() { return messageKey; } - + /** - * @return Returns wether the shortCircuit flag should be set on the + * @return Returns wether the shortCircuit flag should be set on the * validator. */ public boolean isShortCircuit() { return shortCircuit; } - + /** - * @return Returns the configured params to set on the validator. + * @return Returns the configured params to set on the validator. */ public Map getParams() { return params; } - + /** * @return Returns the type of validator to configure. */ @@ -123,7 +123,7 @@ public Builder shortCircuit(boolean shortCircuit) { } public Builder defaultMessage(String msg) { - if ((msg != null) && (msg.trim().length() > 0)) { + if (msg != null && !msg.trim().isEmpty()) { target.defaultMessage = msg; } return this; @@ -135,7 +135,7 @@ public Builder messageParams(String[] msgParams) { } public Builder messageKey(String key) { - if ((key != null) && (key.trim().length() > 0)) { + if (key != null && !key.trim().isEmpty()) { target.messageKey = key; } return this; diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/ConditionalVisitorFieldValidator.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/ConditionalVisitorFieldValidator.java index 37f893a68b..f0ef9dbc73 100644 --- a/core/src/main/java/com/opensymphony/xwork2/validator/validators/ConditionalVisitorFieldValidator.java +++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/ConditionalVisitorFieldValidator.java @@ -94,7 +94,7 @@ public boolean validateExpression(Object object) throws ValidationException { // let this pass, but it will be logged right below } - if ((obj != null) && (obj instanceof Boolean)) { + if (obj instanceof Boolean) { answer = (Boolean) obj; } else { LOG.warn("Got result of {} when trying to get Boolean.", obj); @@ -103,4 +103,4 @@ public boolean validateExpression(Object object) throws ValidationException { return answer; } -} \ No newline at end of file +} diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/ConversionErrorFieldValidator.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/ConversionErrorFieldValidator.java index 3fcf023565..d57856bc85 100644 --- a/core/src/main/java/com/opensymphony/xwork2/validator/validators/ConversionErrorFieldValidator.java +++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/ConversionErrorFieldValidator.java @@ -21,7 +21,6 @@ import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.conversion.impl.ConversionData; import com.opensymphony.xwork2.conversion.impl.XWorkConverter; -import com.opensymphony.xwork2.validator.ValidationException; import org.apache.commons.lang3.StringUtils; import java.util.Map; @@ -44,7 +43,7 @@ * <param name="fieldName">myField</param> * <message>Conversion Error Occurred</message> * </validator> - * + * * <!-- Field Validator Syntax --> * <field name="myField"> * <field-validator type="conversion"> @@ -64,22 +63,21 @@ public class ConversionErrorFieldValidator extends RepopulateConversionErrorFiel * be called with a non-null ValidatorContext before validate is called. * * @param object the object to be validated - * @throws ValidationException in case of validation problems */ @Override - public void doValidate(Object object) throws ValidationException { + public void doValidate(Object object) { String fieldName = getFieldName(); String fullFieldName = getValidatorContext().getFullFieldName(fieldName); ActionContext context = ActionContext.getContext(); Map conversionErrors = context.getConversionErrors(); - + if (conversionErrors.containsKey(fullFieldName)) { if (StringUtils.isBlank(defaultMessage)) { defaultMessage = XWorkConverter.getConversionErrorMessage(fullFieldName, conversionErrors.get(fullFieldName).getToClass(), context.getValueStack()); } - + addFieldError(fieldName, object); } } - + } diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/DoubleRangeFieldValidator.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/DoubleRangeFieldValidator.java index 1350866d5c..214e4ed186 100644 --- a/core/src/main/java/com/opensymphony/xwork2/validator/validators/DoubleRangeFieldValidator.java +++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/DoubleRangeFieldValidator.java @@ -146,7 +146,7 @@ protected void validateValue(Object obj, Double maxInclusiveToUse, Double minInc addFieldError(getFieldName(), value); } } catch (NumberFormatException e) { - LOG.debug("Cannot validate value {} - not a Double", e); + LOG.debug("Cannot validate value {} - not a Double", obj, e); } finally { setCurrentValue(null); } diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/ExpressionValidator.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/ExpressionValidator.java index e9f3fb0667..88753fb0fc 100644 --- a/core/src/main/java/com/opensymphony/xwork2/validator/validators/ExpressionValidator.java +++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/ExpressionValidator.java @@ -33,7 +33,7 @@ * * * - * + * *

        * 
        *     <validators>
      @@ -73,7 +73,7 @@ public void validate(Object object) throws ValidationException {
                   // let this pass, but it will be logged right below
               }
       
      -        if ((obj != null) && (obj instanceof Boolean)) {
      +        if (obj instanceof Boolean) {
                   answer = (Boolean) obj;
               } else {
                   LOG.warn("Got result of [{}] when trying to get Boolean.", obj);
      diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/FieldExpressionValidator.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/FieldExpressionValidator.java
      index d53c6aaa71..68f875ebef 100644
      --- a/core/src/main/java/com/opensymphony/xwork2/validator/validators/FieldExpressionValidator.java
      +++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/FieldExpressionValidator.java
      @@ -33,7 +33,7 @@
        *    
    • expression - The Ognl expression (must evaluate to a boolean) which is to be evalidated the stack
    • * * - * + * *
        * 
        *    <!-- Plain Validator Syntax -->
      @@ -44,7 +44,7 @@
        *           <param name="expression"><![CDATA[#myCreditLimit > #myGirfriendCreditLimit]]></param>
        *           <message>My credit limit should be MORE than my girlfriend</message>
        *        <validator>
      - *        
      + *
        *        <!-- Field Validator Syntax -->
        *        <field name="myField">
        *            <field-validator type="fieldexpression">
      @@ -52,7 +52,7 @@
        *                <message>My credit limit should be MORE than my girlfriend</message>
        *            </field-validator>
        *        </field>
      - *        
      + *
        *    </vaidators>
        * 
        * 
      @@ -85,7 +85,7 @@ public void validate(Object object) throws ValidationException { // let this pass, but it will be logged right below } - if ((obj != null) && (obj instanceof Boolean)) { + if (obj instanceof Boolean) { answer = (Boolean) obj; } else { LOG.warn("Got result of {} when trying to get Boolean.", obj); diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/FieldValidatorSupport.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/FieldValidatorSupport.java index 7e539aae63..61d0ea7633 100644 --- a/core/src/main/java/com/opensymphony/xwork2/validator/validators/FieldValidatorSupport.java +++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/FieldValidatorSupport.java @@ -32,10 +32,12 @@ public abstract class FieldValidatorSupport extends ValidatorSupport implements protected String type; protected Object currentValue; + @Override public void setFieldName(String fieldName) { this.fieldName = fieldName; } + @Override public String getFieldName() { return fieldName; } diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/RegexFieldValidator.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/RegexFieldValidator.java index e45a02e8fe..c05dd8a024 100644 --- a/core/src/main/java/com/opensymphony/xwork2/validator/validators/RegexFieldValidator.java +++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/RegexFieldValidator.java @@ -18,10 +18,10 @@ */ package com.opensymphony.xwork2.validator.validators; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; import com.opensymphony.xwork2.validator.ValidationException; import org.apache.commons.lang3.StringUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import java.util.Collection; import java.util.Objects; @@ -33,7 +33,7 @@ * Validates a string field using a regular expression. * * - * + * * *
        *
      • fieldName - The field name this validator is validating. Required if using Plain-Validator Syntax otherwise not required
      • @@ -128,7 +128,7 @@ public void validate(Object object) throws ValidationException { protected void validateFieldValue(Object object, String value, String regexToUse) { // string must not be empty String str = value.trim(); - if (str.length() == 0) { + if (str.isEmpty()) { LOG.debug("Value is empty, please use a required validator"); return; } diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/RepopulateConversionErrorFieldValidatorSupport.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/RepopulateConversionErrorFieldValidatorSupport.java index 7557e9f214..54d47aa06d 100644 --- a/core/src/main/java/com/opensymphony/xwork2/validator/validators/RepopulateConversionErrorFieldValidatorSupport.java +++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/RepopulateConversionErrorFieldValidatorSupport.java @@ -21,7 +21,6 @@ import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.conversion.impl.ConversionData; -import com.opensymphony.xwork2.interceptor.PreResultListener; import com.opensymphony.xwork2.util.ValueStack; import com.opensymphony.xwork2.validator.ValidationException; import org.apache.commons.text.StringEscapeUtils; @@ -146,6 +145,7 @@ public void setRepopulateField(boolean repopulateField) { this.repopulateField = repopulateField; } + @Override public void validate(Object object) throws ValidationException { doValidate(object); if (repopulateField) { @@ -153,7 +153,7 @@ public void validate(Object object) throws ValidationException { } } - public void repopulateField(Object object) throws ValidationException { + public void repopulateField(Object object) { ActionInvocation invocation = ActionContext.getContext().getActionInvocation(); Map conversionErrors = ActionContext.getContext().getConversionErrors(); @@ -163,33 +163,29 @@ public void repopulateField(Object object) throws ValidationException { if (conversionErrors.containsKey(fullFieldName)) { Object value = conversionErrors.get(fullFieldName).getValue(); - final Map fakeParams = new LinkedHashMap(); + final Map fakeParams = new LinkedHashMap<>(); boolean doExprOverride = false; - if (value instanceof String[]) { + if (value instanceof String[] tmpValue) { // take the first element, if possible - String[] tmpValue = (String[]) value; if ((tmpValue.length > 0)) { doExprOverride = true; fakeParams.put(fullFieldName, escape(tmpValue[0])); } else { LOG.warn("value is an empty array of String or with first element in it as null [{}], will not repopulate conversion error", value); } - } else if (value instanceof String) { - String tmpValue = (String) value; + } else if (value instanceof String tmpValue) { doExprOverride = true; fakeParams.put(fullFieldName, escape(tmpValue)); } else { - // opps... it should be + // opps... it should be LOG.warn("conversion error value is not a String or array of String but instead is [{}], will not repopulate conversion error", value); } if (doExprOverride) { - invocation.addPreResultListener(new PreResultListener() { - public void beforeResult(ActionInvocation invocation, String resultCode) { - ValueStack stack = ActionContext.getContext().getValueStack(); - stack.setExprOverrides(fakeParams); - } + invocation.addPreResultListener((invocation1, resultCode) -> { + ValueStack stack = ActionContext.getContext().getValueStack(); + stack.setExprOverrides(fakeParams); }); } } diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/RequiredFieldValidator.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/RequiredFieldValidator.java index c23e210904..b6492a9ee6 100644 --- a/core/src/main/java/com/opensymphony/xwork2/validator/validators/RequiredFieldValidator.java +++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/RequiredFieldValidator.java @@ -37,26 +37,26 @@ *
          * 
          * 	   <validators>
        - * 
        + *
          *         <!-- Plain Validator Syntax -->
          *         <validator type="required">
          *             <param name="fieldName">username</param>
          *             <message>username must not be null</message>
          *         </validator>
        - * 
        - * 
        + *
        + *
          *         <!-- Field Validator Syntax -->
          *         <field name="username">
          *             <field-validator type="required">
          *             	   <message>username must not be null</message>
          *             </field-validator>
          *         </field>
        - * 
        + *
          *     </validators>
          * 
          * 
        - * - * + * + * * * @author rainerh */ @@ -70,7 +70,7 @@ public void validate(Object object) throws ValidationException { addFieldError(fieldName, object); } else if (value.getClass().isArray() && Array.getLength(value) == 0) { addFieldError(fieldName, object); - } else if (Collection.class.isAssignableFrom(value.getClass()) && ((Collection) value).size() == 0) { + } else if (Collection.class.isAssignableFrom(value.getClass()) && ((Collection) value).isEmpty()) { addFieldError(fieldName, object); } } diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/RequiredStringValidator.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/RequiredStringValidator.java index 53149ef020..9c1869932a 100644 --- a/core/src/main/java/com/opensymphony/xwork2/validator/validators/RequiredStringValidator.java +++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/RequiredStringValidator.java @@ -36,7 +36,7 @@ *
      • trimExpression - (Optional) String. Specifies the trim param as an OGNL expression.
      • *
      * - * + * * * Do not use ${trimExpression} as an expression as this will turn into infinitive loop! * @@ -50,7 +50,7 @@ * <param name="trim">true</param> * <message>username is required</message> * </validator> - * + * * <!-- Field-Validator Syntax --> * <field name="username"> * <field-validator type="requiredstring"> @@ -69,7 +69,7 @@ * </validators> * *
      - * + * * @author rainerh */ public class RequiredStringValidator extends FieldValidatorSupport { @@ -119,14 +119,13 @@ protected void validateValue(Object object, Object fieldValue) { return; } - if (fieldValue instanceof String) { - String stingValue = (String) fieldValue; + if (fieldValue instanceof String stringValue) { if (trim) { - stingValue = stingValue.trim(); + stringValue = stringValue.trim(); } - if (stingValue.length() == 0) { + if (stringValue.isEmpty()) { addFieldError(getFieldName(), object); } } else { diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/URLValidator.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/URLValidator.java index d4dbb38316..7093ab7128 100644 --- a/core/src/main/java/com/opensymphony/xwork2/validator/validators/URLValidator.java +++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/URLValidator.java @@ -51,7 +51,7 @@ public class URLValidator extends FieldValidatorSupport { private static final Logger LOG = LogManager.getLogger(URLValidator.class); - public static final String DEFAULT_URL_REGEX = "^(?:https?|ftp):\\/\\/" + + public static final String DEFAULT_URL_REGEX = "^(?:https?|ftp)://" + "(?:(?:[a-z0-9$_.+!*'(),;?&=\\-]|%[0-9a-f]{2})+" + "(?::(?:[a-z0-9$_.+!*'(),;?&=\\-]|%[0-9a-f]{2})+)?" + "@)?#?" + @@ -60,8 +60,8 @@ public class URLValidator extends FieldValidatorSupport { "|(?:(?:[1-9]?\\d|1\\d{2}|2[0-4]\\d|25[0-5])\\.){3}" + "(?:[1-9]?\\d|1\\d{2}|2[0-4]\\d|25[0-5])" + ")(?::\\d+)?" + - ")(?:(?:\\/(?:[a-z0-9$_.+!*'(),;:@&=\\-]|%[0-9a-f]{2})*)*" + - "(?:\\?(?:[a-z0-9$_.+!*'(),;:@&=\\-\\/:]|%[0-9a-f]{2})*)?)?" + + ")(?:(?:/(?:[a-z0-9$_.+!*'(),;:@&=\\-]|%[0-9a-f]{2})*)*" + + "(?:\\?(?:[a-z0-9$_.+!*'(),;:@&=\\-/]|%[0-9a-f]{2})*)?)?" + "(?:#(?:[a-z0-9$_.+!*'(),;:@&=\\-]|%[0-9a-f]{2})*)?" + "$"; @@ -72,7 +72,7 @@ public void validate(Object object) throws ValidationException { Object value = getFieldValue(fieldName, object); String stringValue = Objects.toString(value, EMPTY_STRING).trim(); - if (stringValue.length() == 0) { + if (stringValue.isEmpty()) { LOG.debug("Value for field {} is empty, won't ba validated, please use a required validator", fieldName); return; } @@ -97,7 +97,7 @@ public void validate(Object object) throws ValidationException { protected void validateValue(Object object, Object value) { String stringValue = Objects.toString(value, EMPTY_STRING).trim(); - if (stringValue.length() == 0) { + if (stringValue.isEmpty()) { LOG.debug("Value for field {} is empty, won't ba validated, please use a required validator", fieldName); return; } diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/ValidatorSupport.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/ValidatorSupport.java index f7da8e44c3..e1a79f6b16 100644 --- a/core/src/main/java/com/opensymphony/xwork2/validator/validators/ValidatorSupport.java +++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/ValidatorSupport.java @@ -22,7 +22,11 @@ import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.util.TextParseUtil; import com.opensymphony.xwork2.util.ValueStack; -import com.opensymphony.xwork2.validator.*; +import com.opensymphony.xwork2.validator.DelegatingValidatorContext; +import com.opensymphony.xwork2.validator.ShortCircuitableValidator; +import com.opensymphony.xwork2.validator.ValidationException; +import com.opensymphony.xwork2.validator.Validator; +import com.opensymphony.xwork2.validator.ValidatorContext; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -84,7 +88,7 @@ public String getMessage(Object object) { stack.push(this); if (messageKey != null) { - if ((defaultMessage == null) || ("".equals(defaultMessage.trim()))) { + if (defaultMessage == null || defaultMessage.trim().isEmpty()) { defaultMessage = messageKey; } if (validatorContext == null) { diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/VisitorFieldValidator.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/VisitorFieldValidator.java index 9e488a9b42..eb07a233c6 100644 --- a/core/src/main/java/com/opensymphony/xwork2/validator/validators/VisitorFieldValidator.java +++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/VisitorFieldValidator.java @@ -140,13 +140,11 @@ public void validate(Object object) throws ValidationException { String visitorContext = (context == null) ? ActionContext.getContext().getActionName() : context; - if (value instanceof Collection) { - Collection coll = (Collection) value; + if (value instanceof Collection coll) { Object[] array = coll.toArray(); validateArrayElements(array, fieldName, visitorContext); - } else if (value instanceof Object[]) { - Object[] array = (Object[]) value; + } else if (value instanceof Object[] array) { validateArrayElements(array, fieldName, visitorContext); } else { @@ -175,11 +173,10 @@ private void validateObject(String fieldName, Object o, String visitorContext) t ValidatorContext validatorContext; + ValidatorContext parent = getValidatorContext(); if (appendPrefix) { - ValidatorContext parent = getValidatorContext(); validatorContext = new AppendingValidatorContext(parent, createTextProvider(o, parent), fieldName, getMessage(o)); } else { - ValidatorContext parent = getValidatorContext(); CompositeTextProvider textProvider = createTextProvider(o, parent); validatorContext = new DelegatingValidatorContext(parent, textProvider, parent); } @@ -201,9 +198,9 @@ private CompositeTextProvider createTextProvider(Object o, ValidatorContext pare } public static class AppendingValidatorContext extends DelegatingValidatorContext { - private String field; - private String message; - private ValidatorContext parent; + private final String field; + private final String message; + private final ValidatorContext parent; public AppendingValidatorContext(ValidatorContext parent, TextProvider textProvider, String field, String message) { super(parent, textProvider, parent); diff --git a/core/src/main/java/org/apache/struts2/RequestUtils.java b/core/src/main/java/org/apache/struts2/RequestUtils.java index fbba36cae3..46b1dac8f6 100644 --- a/core/src/main/java/org/apache/struts2/RequestUtils.java +++ b/core/src/main/java/org/apache/struts2/RequestUtils.java @@ -18,12 +18,12 @@ */ package org.apache.struts2; +import jakarta.servlet.http.HttpServletRequest; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.time.FastDateFormat; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import jakarta.servlet.http.HttpServletRequest; import java.text.ParseException; import java.util.Date; import java.util.Locale; @@ -57,7 +57,7 @@ public class RequestUtils { */ public static String getServletPath(HttpServletRequest request) { String servletPath = request.getServletPath(); - + String requestUri = request.getRequestURI(); // Detecting other characters that the servlet container cut off (like anything after ';') if (requestUri != null && servletPath != null && !requestUri.endsWith(servletPath)) { @@ -70,8 +70,8 @@ public static String getServletPath(HttpServletRequest request) { if (StringUtils.isNotEmpty(servletPath)) { return servletPath; } - - int startIndex = request.getContextPath().equals("") ? 0 : request.getContextPath().length(); + + int startIndex = request.getContextPath().isEmpty() ? 0 : request.getContextPath().length(); int endIndex = request.getPathInfo() == null ? requestUri.length() : requestUri.lastIndexOf(request.getPathInfo()); if (startIndex > endIndex) { // this should not happen diff --git a/core/src/main/java/org/apache/struts2/StrutsException.java b/core/src/main/java/org/apache/struts2/StrutsException.java index 2838f40866..9a7faa82b2 100644 --- a/core/src/main/java/org/apache/struts2/StrutsException.java +++ b/core/src/main/java/org/apache/struts2/StrutsException.java @@ -53,7 +53,7 @@ public StrutsException(String s) { * @param target the target of the exception. */ public StrutsException(String s, Object target) { - this(s, (Throwable) null, target); + this(s, null, target); } /** @@ -129,7 +129,7 @@ public String toString() { if (location != null) { if (msg != null) { - return msg + " - " + location.toString(); + return msg + " - " + location; } else { return location.toString(); } @@ -137,4 +137,4 @@ public String toString() { return msg; } } -} \ No newline at end of file +} diff --git a/core/src/main/java/org/apache/struts2/components/ActionComponent.java b/core/src/main/java/org/apache/struts2/components/ActionComponent.java index 051df9516c..96f417b03b 100644 --- a/core/src/main/java/org/apache/struts2/components/ActionComponent.java +++ b/core/src/main/java/org/apache/struts2/components/ActionComponent.java @@ -25,6 +25,9 @@ import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.util.ValueStack; import com.opensymphony.xwork2.util.ValueStackFactory; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.jsp.PageContext; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.struts2.ServletActionContext; @@ -33,14 +36,10 @@ import org.apache.struts2.dispatcher.Dispatcher; import org.apache.struts2.dispatcher.HttpParameters; import org.apache.struts2.dispatcher.RequestMap; -import org.apache.struts2.dispatcher.mapper.ActionMapper; import org.apache.struts2.dispatcher.mapper.ActionMapping; import org.apache.struts2.views.annotations.StrutsTag; import org.apache.struts2.views.annotations.StrutsTagAttribute; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import jakarta.servlet.jsp.PageContext; import java.io.IOException; import java.io.Writer; import java.util.Map; @@ -146,12 +145,6 @@ public void setValueStackFactory(ValueStackFactory valueStackFactory) { this.valueStackFactory = valueStackFactory; } - @Inject - @Override - public void setActionMapper(ActionMapper mapper) { - this.actionMapper = mapper; - } - @Override public boolean end(Writer writer, String body) { boolean end = super.end(writer, "", false); diff --git a/core/src/main/java/org/apache/struts2/components/Anchor.java b/core/src/main/java/org/apache/struts2/components/Anchor.java index 6b833da1de..8162c35691 100644 --- a/core/src/main/java/org/apache/struts2/components/Anchor.java +++ b/core/src/main/java/org/apache/struts2/components/Anchor.java @@ -20,7 +20,8 @@ import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.util.ValueStack; -import org.apache.commons.lang3.BooleanUtils; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -28,8 +29,6 @@ import org.apache.struts2.views.annotations.StrutsTag; import org.apache.struts2.views.annotations.StrutsTagAttribute; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; import java.io.StringWriter; import java.io.Writer; import java.util.LinkedHashMap; diff --git a/core/src/main/java/org/apache/struts2/components/AppendIterator.java b/core/src/main/java/org/apache/struts2/components/AppendIterator.java index 6e03d51106..974840db17 100644 --- a/core/src/main/java/org/apache/struts2/components/AppendIterator.java +++ b/core/src/main/java/org/apache/struts2/components/AppendIterator.java @@ -29,7 +29,6 @@ import java.io.Writer; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; /** @@ -124,6 +123,7 @@ public AppendIterator(ValueStack stack) { super(stack); } + @Override public boolean start(Writer writer) { _parameters = new ArrayList(); appendIteratorFilter = new AppendIteratorFilter(); @@ -131,12 +131,12 @@ public boolean start(Writer writer) { return super.start(writer); } + @Override public boolean end(Writer writer, String body) { - for (Iterator paramEntries = _parameters.iterator(); paramEntries.hasNext(); ) { + for (Object iteratorEntryObj : _parameters) { - Object iteratorEntryObj = paramEntries.next(); - if (! MakeIterator.isIterable(iteratorEntryObj)) { + if (!MakeIterator.isIterable(iteratorEntryObj)) { LOG.warn("param with value resolved as {} cannot be make as iterator, it will be ignored and hence will not appear in the merged iterator", iteratorEntryObj); continue; } @@ -153,11 +153,13 @@ public boolean end(Writer writer, String body) { } // UnnamedParametric implementation -------------------------------------- + @Override public void addParameter(Object value) { _parameters.add(value); } @StrutsTagAttribute(description="The name of which if supplied will have the resultant appended iterator stored under in the stack's context") + @Override public void setVar(String var) { super.setVar(var); } diff --git a/core/src/main/java/org/apache/struts2/components/ComboBox.java b/core/src/main/java/org/apache/struts2/components/ComboBox.java index 8356404e75..4f288fd93e 100644 --- a/core/src/main/java/org/apache/struts2/components/ComboBox.java +++ b/core/src/main/java/org/apache/struts2/components/ComboBox.java @@ -19,12 +19,12 @@ package org.apache.struts2.components; import com.opensymphony.xwork2.util.ValueStack; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.apache.struts2.util.MakeIterator; import org.apache.struts2.views.annotations.StrutsTag; import org.apache.struts2.views.annotations.StrutsTagAttribute; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; import java.util.Collection; import java.util.Iterator; import java.util.Map; @@ -126,8 +126,7 @@ public void evaluateExtraParams() { } if (value != null) { - if (value instanceof Collection) { - Collection tmp = (Collection) value; + if (value instanceof Collection tmp) { addParameter("list", tmp); if (listKey != null) { addParameter("listKey", listKey); @@ -135,11 +134,10 @@ public void evaluateExtraParams() { if (listValue != null) { addParameter("listValue", listValue); } - } else if (value instanceof Map) { - Map tmp = (Map) value; + } else if (value instanceof Map tmp) { addParameter("list", MakeIterator.convert(tmp)); addParameter("listKey", "key"); - addParameter("listValue", "value"); + addParameter("listValue", "value"); } else { // also covers "if (value.getClass().isArray())" Iterator i = MakeIterator.convert(value); addParameter("list", i); diff --git a/core/src/main/java/org/apache/struts2/components/ComponentUrlProvider.java b/core/src/main/java/org/apache/struts2/components/ComponentUrlProvider.java index e1e71d061c..a2f55c51df 100644 --- a/core/src/main/java/org/apache/struts2/components/ComponentUrlProvider.java +++ b/core/src/main/java/org/apache/struts2/components/ComponentUrlProvider.java @@ -19,9 +19,9 @@ package org.apache.struts2.components; import com.opensymphony.xwork2.util.ValueStack; - import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; + import java.util.Map; /** @@ -50,7 +50,7 @@ public class ComponentUrlProvider implements UrlProvider { protected UrlRenderer urlRenderer; protected Component component; - private Map parameters; + private final Map parameters; /** * @@ -62,180 +62,224 @@ public ComponentUrlProvider(Component component, Map parameters) { this.parameters = parameters; } + @Override public String determineActionURL(String action, String namespace, String method, HttpServletRequest req, HttpServletResponse res, Map parameters, String scheme, boolean includeContext, boolean encodeResult, boolean forceAddSchemeHostAndPort, boolean escapeAmp) { return component.determineActionURL(action, namespace, method, req, res, parameters, scheme, includeContext, encodeResult, forceAddSchemeHostAndPort, escapeAmp); } + @Override public String determineNamespace(String namespace, ValueStack stack, HttpServletRequest req) { return component.determineNamespace(namespace, stack, req); } + @Override public String findString(String expr) { return component.findString(expr); } + @Override public Map getParameters() { return parameters; } + @Override public HttpServletRequest getHttpServletRequest() { return httpServletRequest; } + @Override public void setHttpServletRequest(HttpServletRequest httpServletRequest) { this.httpServletRequest = httpServletRequest; } + @Override public HttpServletResponse getHttpServletResponse() { return httpServletResponse; } + @Override public void setHttpServletResponse(HttpServletResponse httpServletResponse) { this.httpServletResponse = httpServletResponse; } + @Override public String getIncludeParams() { return includeParams; } + @Override public void setIncludeParams(String includeParams) { this.includeParams = includeParams; } + @Override public String getScheme() { return scheme; } + @Override public void setScheme(String scheme) { this.scheme = scheme; } + @Override public boolean isPutInContext() { return component instanceof ContextBean; } + @Override public String getVar() { return isPutInContext() ? ((ContextBean)component).getVar() : null; } + @Override public String getValue() { return value; } + @Override public void setValue(String value) { this.value = value; } + @Override public String getAction() { return action; } + @Override public void setAction(String action) { this.action = action; } + @Override public String getNamespace() { return namespace; } + @Override public void setNamespace(String namespace) { this.namespace = namespace; } + @Override public String getMethod() { return method; } + @Override public void setMethod(String method) { this.method = method; } + @Override public boolean isEncode() { return encode; } + @Override public void setEncode(boolean encode) { this.encode = encode; } + @Override public boolean isIncludeContext() { return includeContext; } + @Override public void setIncludeContext(boolean includeContext) { this.includeContext = includeContext; } + @Override public boolean isEscapeAmp() { return escapeAmp; } + @Override public void setEscapeAmp(boolean escapeAmp) { this.escapeAmp = escapeAmp; } + @Override public String getPortletMode() { return portletMode; } + @Override public void setPortletMode(String portletMode) { this.portletMode = portletMode; } + @Override public String getWindowState() { return windowState; } + @Override public void setWindowState(String windowState) { this.windowState = windowState; } + @Override public String getPortletUrlType() { return portletUrlType; } + @Override public ValueStack getStack() { return component.getStack(); } + @Override public void setPortletUrlType(String portletUrlType) { this.portletUrlType = portletUrlType; } + @Override public String getAnchor() { return anchor; } + @Override public void setAnchor(String anchor) { this.anchor = anchor; } + @Override public boolean isForceAddSchemeHostAndPort() { return forceAddSchemeHostAndPort; } + @Override public void setForceAddSchemeHostAndPort(boolean forceAddSchemeHostAndPort) { this.forceAddSchemeHostAndPort = forceAddSchemeHostAndPort; } + @Override public void putInContext(String result) { if (isPutInContext()) { ((ContextBean)component).putInContext(result); } } + @Override public String getUrlIncludeParams() { return urlIncludeParams; } + @Override public void setUrlIncludeParams(String urlIncludeParams) { this.urlIncludeParams = urlIncludeParams; } + @Override public ExtraParameterProvider getExtraParameterProvider() { return extraParameterProvider; } + @Override public void setExtraParameterProvider(ExtraParameterProvider extraParameterProvider) { this.extraParameterProvider = extraParameterProvider; } @@ -244,6 +288,7 @@ public UrlRenderer getUrlRenderer() { return urlRenderer; } + @Override public void setUrlRenderer(UrlRenderer urlRenderer) { this.urlRenderer = urlRenderer; } diff --git a/core/src/main/java/org/apache/struts2/components/DateTextField.java b/core/src/main/java/org/apache/struts2/components/DateTextField.java index f55d3f76df..76fb955154 100644 --- a/core/src/main/java/org/apache/struts2/components/DateTextField.java +++ b/core/src/main/java/org/apache/struts2/components/DateTextField.java @@ -18,14 +18,12 @@ */ package org.apache.struts2.components; +import com.opensymphony.xwork2.util.ValueStack; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; - import org.apache.struts2.views.annotations.StrutsTag; import org.apache.struts2.views.annotations.StrutsTagAttribute; -import com.opensymphony.xwork2.util.ValueStack; - @StrutsTag( name="datetextfield", tldTagClass="org.apache.struts2.views.jsp.ui.DateTextFieldTag", @@ -36,7 +34,7 @@ public class DateTextField extends UIBean { * The name of the default template for the DateTextFieldTag */ final public static String TEMPLATE = "datetextfield"; - + protected String format; public DateTextField(ValueStack stack, HttpServletRequest request, HttpServletResponse response) { @@ -55,15 +53,14 @@ protected void evaluateExtraParams() { } } - @StrutsTagAttribute(description="Date format attribute", required=true, type="String") + @StrutsTagAttribute(description="Date format attribute", required=true) public void setFormat(String format) { this.format = format; } - @SuppressWarnings("unchecked") @Override protected Class getValueClassType() { return null; } - + } diff --git a/core/src/main/java/org/apache/struts2/components/Debug.java b/core/src/main/java/org/apache/struts2/components/Debug.java index 1073dba63c..634b88f860 100644 --- a/core/src/main/java/org/apache/struts2/components/Debug.java +++ b/core/src/main/java/org/apache/struts2/components/Debug.java @@ -21,18 +21,17 @@ import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.util.ValueStack; import com.opensymphony.xwork2.util.reflection.ReflectionProvider; - -import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.apache.struts2.StrutsException; +import org.apache.struts2.dispatcher.PrepareOperations; +import org.apache.struts2.views.annotations.StrutsTag; + import java.io.Writer; -import java.util.Iterator; -import java.util.Map; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; - -import org.apache.struts2.dispatcher.PrepareOperations; -import org.apache.struts2.views.annotations.StrutsTag; -import org.apache.struts2.StrutsException; +import java.util.Map; @StrutsTag(name="debug", tldTagClass="org.apache.struts2.views.jsp.ui.DebugTag", description="Prints debugging information (Only if 'struts.devMode' is enabled)") @@ -93,7 +92,7 @@ protected boolean showDebug() { } private static class DebugMapEntry implements Map.Entry { - private Object key; + private final Object key; private Object value; DebugMapEntry(Object key, Object value) { @@ -101,14 +100,17 @@ private static class DebugMapEntry implements Map.Entry { this.value = value; } + @Override public Object getKey() { return key; } + @Override public Object getValue() { return value; } + @Override public Object setValue(Object newVal) { Object oldVal = value; value = newVal; diff --git a/core/src/main/java/org/apache/struts2/components/FieldError.java b/core/src/main/java/org/apache/struts2/components/FieldError.java index 7e0095ab57..c044bfddb8 100644 --- a/core/src/main/java/org/apache/struts2/components/FieldError.java +++ b/core/src/main/java/org/apache/struts2/components/FieldError.java @@ -19,12 +19,12 @@ package org.apache.struts2.components; import com.opensymphony.xwork2.util.ValueStack; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.apache.struts2.components.Param.UnnamedParametric; import org.apache.struts2.views.annotations.StrutsTag; import org.apache.struts2.views.annotations.StrutsTagAttribute; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; import java.util.ArrayList; import java.util.List; @@ -87,7 +87,7 @@ "or partial depending on param tag nested)if they exists") public class FieldError extends UIBean implements UnnamedParametric { - private List errorFieldNames = new ArrayList<>(); + private final List errorFieldNames = new ArrayList<>(); private boolean escape = true; public FieldError(ValueStack stack, HttpServletRequest request, HttpServletResponse response) { @@ -120,7 +120,7 @@ public List getFieldErrorFieldNames() { return errorFieldNames; } - @StrutsTagAttribute(description="Field name for single field attribute usage", type="String") + @StrutsTagAttribute(description="Field name for single field attribute usage") public void setFieldName(String fieldName) { addParameter(fieldName); } diff --git a/core/src/main/java/org/apache/struts2/components/File.java b/core/src/main/java/org/apache/struts2/components/File.java index ffe8e227cf..605fd97f70 100644 --- a/core/src/main/java/org/apache/struts2/components/File.java +++ b/core/src/main/java/org/apache/struts2/components/File.java @@ -19,14 +19,13 @@ package org.apache.struts2.components; import com.opensymphony.xwork2.util.ValueStack; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.struts2.views.annotations.StrutsTag; import org.apache.struts2.views.annotations.StrutsTagAttribute; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; - /** * * Renders an HTML file input element. @@ -95,7 +94,7 @@ public void setAccept(String accept) { this.accept = accept; } - @StrutsTagAttribute(description="HTML size attribute", required=false, type="Integer") + @StrutsTagAttribute(description="HTML size attribute", type="Integer") public void setSize(String size) { this.size = size; } diff --git a/core/src/main/java/org/apache/struts2/components/Form.java b/core/src/main/java/org/apache/struts2/components/Form.java index 43d162f24d..019e39bef2 100644 --- a/core/src/main/java/org/apache/struts2/components/Form.java +++ b/core/src/main/java/org/apache/struts2/components/Form.java @@ -33,13 +33,13 @@ import com.opensymphony.xwork2.validator.Validator; import com.opensymphony.xwork2.validator.ValidatorContext; import com.opensymphony.xwork2.validator.validators.VisitorFieldValidator; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.apache.commons.lang3.StringUtils; import org.apache.struts2.dispatcher.mapper.ActionMapping; import org.apache.struts2.views.annotations.StrutsTag; import org.apache.struts2.views.annotations.StrutsTagAttribute; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; @@ -253,11 +253,10 @@ protected void evaluateClientSideJsEnablement(String actionName, String namespac if (actionConfig != null) { List interceptors = actionConfig.getInterceptors(); for (InterceptorMapping interceptorMapping : interceptors) { - if (ValidationInterceptor.class.isInstance(interceptorMapping.getInterceptor())) { - ValidationInterceptor validationInterceptor = (ValidationInterceptor) interceptorMapping.getInterceptor(); + if (interceptorMapping.getInterceptor() instanceof ValidationInterceptor validationInterceptor) { - Set excludeMethods = validationInterceptor.getExcludeMethodsSet(); - Set includeMethods = validationInterceptor.getIncludeMethodsSet(); + Set excludeMethods = validationInterceptor.getExcludeMethodsSet(); + Set includeMethods = validationInterceptor.getIncludeMethodsSet(); if (MethodFilterInterceptorUtil.applyMethod(excludeMethods, includeMethods, actionMethod)) { addParameter("performValidation", Boolean.TRUE); @@ -309,8 +308,7 @@ private boolean isValidateAnnotatedMethodOnly(String actionName) { if (actionConfig != null) { List interceptors = actionConfig.getInterceptors(); for (InterceptorMapping interceptorMapping : interceptors) { - if (ValidationInterceptor.class.isInstance(interceptorMapping.getInterceptor())) { - ValidationInterceptor validationInterceptor = (ValidationInterceptor) interceptorMapping.getInterceptor(); + if (interceptorMapping.getInterceptor() instanceof ValidationInterceptor validationInterceptor) { return validationInterceptor.isValidateAnnotatedMethodOnly(); } } @@ -322,8 +320,7 @@ private void findFieldValidators(String name, Class actionClass, String actionNa List validatorList, List resultValidators, String prefix) { for (Validator validator : validatorList) { - if (validator instanceof FieldValidator) { - FieldValidator fieldValidator = (FieldValidator) validator; + if (validator instanceof FieldValidator fieldValidator) { if (validator instanceof VisitorFieldValidator) { VisitorFieldValidator vfValidator = (VisitorFieldValidator) fieldValidator; @@ -456,7 +453,7 @@ protected Class getVisitorReturnType(Class actionClass, String visitorFieldName) } String methodName = "get" + StringUtils.capitalize(visitorFieldName); try { - Method method = actionClass.getMethod(methodName, new Class[0]); + Method method = actionClass.getMethod(methodName); return method.getReturnType(); } catch (NoSuchMethodException e) { return null; diff --git a/core/src/main/java/org/apache/struts2/components/FormButton.java b/core/src/main/java/org/apache/struts2/components/FormButton.java index 5f70c5b027..914d050c9c 100644 --- a/core/src/main/java/org/apache/struts2/components/FormButton.java +++ b/core/src/main/java/org/apache/struts2/components/FormButton.java @@ -18,14 +18,11 @@ */ package org.apache.struts2.components; -import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.util.ValueStack; -import org.apache.struts2.dispatcher.mapper.ActionMapper; -import org.apache.struts2.dispatcher.mapper.ActionMapping; -import org.apache.struts2.views.annotations.StrutsTagAttribute; - import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import org.apache.struts2.dispatcher.mapper.ActionMapping; +import org.apache.struts2.views.annotations.StrutsTagAttribute; /** * FormButton. @@ -132,11 +129,6 @@ protected void populateComponentHtmlId(Form form) { */ protected abstract boolean supportsImageType(); - @Inject - public void setActionMapper(ActionMapper mapper) { - this.actionMapper = mapper; - } - @StrutsTagAttribute(description = "Set action attribute.") public void setAction(String action) { this.action = action; diff --git a/core/src/main/java/org/apache/struts2/components/If.java b/core/src/main/java/org/apache/struts2/components/If.java index fa312ee7d8..1ff0fc8f10 100644 --- a/core/src/main/java/org/apache/struts2/components/If.java +++ b/core/src/main/java/org/apache/struts2/components/If.java @@ -18,12 +18,11 @@ */ package org.apache.struts2.components; -import java.io.Writer; - +import com.opensymphony.xwork2.util.ValueStack; import org.apache.struts2.views.annotations.StrutsTag; import org.apache.struts2.views.annotations.StrutsTagAttribute; -import com.opensymphony.xwork2.util.ValueStack; +import java.io.Writer; /** * @@ -86,7 +85,7 @@ public boolean start(Writer writer) { answer = Boolean.FALSE; } stack.getContext().put(ANSWER, answer); - return answer.booleanValue(); + return answer; } public boolean end(Writer writer, String body) { diff --git a/core/src/main/java/org/apache/struts2/components/Include.java b/core/src/main/java/org/apache/struts2/components/Include.java index 857a500043..02867d890a 100644 --- a/core/src/main/java/org/apache/struts2/components/Include.java +++ b/core/src/main/java/org/apache/struts2/components/Include.java @@ -20,16 +20,6 @@ import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.util.ValueStack; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.apache.struts2.RequestUtils; -import org.apache.struts2.StrutsConstants; -import org.apache.struts2.StrutsException; -import org.apache.struts2.util.FastByteArrayOutputStream; -import org.apache.struts2.views.annotations.StrutsTag; -import org.apache.struts2.views.annotations.StrutsTagAttribute; - import jakarta.servlet.RequestDispatcher; import jakarta.servlet.ServletException; import jakarta.servlet.ServletOutputStream; @@ -38,10 +28,26 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponseWrapper; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.struts2.RequestUtils; +import org.apache.struts2.StrutsConstants; +import org.apache.struts2.StrutsException; +import org.apache.struts2.util.FastByteArrayOutputStream; +import org.apache.struts2.views.annotations.StrutsTag; +import org.apache.struts2.views.annotations.StrutsTagAttribute; -import java.io.*; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.io.Writer; import java.net.URLEncoder; -import java.util.*; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Stack; +import java.util.StringTokenizer; /** * @@ -97,8 +103,8 @@ public class Include extends Component { private static final String systemEncoding = System.getProperty("file.encoding"); protected String value; - private HttpServletRequest req; - private HttpServletResponse res; + private final HttpServletRequest req; + private final HttpServletResponse res; private String defaultEncoding; // Made non-static (during WW-4971 fix) private boolean useResponseEncoding = true; // Added with WW-4971 fix (allows switch between usage of response or default encoding) @@ -125,7 +131,7 @@ public boolean end(Writer writer, String body) { if (useResponseEncoding) { encodingForInclude = res.getCharacterEncoding(); // Use response (page) encoding - if (encodingForInclude == null || encodingForInclude.length() == 0) { + if (encodingForInclude == null || encodingForInclude.isEmpty()) { encodingForInclude = defaultEncoding; // Revert to defaultEncoding when response (page) encoding is invalid } } @@ -137,7 +143,7 @@ public boolean end(Writer writer, String body) { urlBuf.append(page); // Add request parameters - if (parameters.size() > 0) { + if (!parameters.isEmpty()) { urlBuf.append('?'); String concat = ""; @@ -153,11 +159,7 @@ public boolean end(Writer writer, String body) { urlBuf.append(name); urlBuf.append('='); - try { - urlBuf.append(URLEncoder.encode(value.toString(), "UTF-8")); - } catch (UnsupportedEncodingException e) { - LOG.warn("Unable to url-encode {}, it will be ignored", value); - } + urlBuf.append(URLEncoder.encode(value.toString(), StandardCharsets.UTF_8)); concat = "&"; } @@ -186,10 +188,9 @@ public static String getContextRelativePath(ServletRequest request, String relat if (relativePath.startsWith("/")) { returnValue = relativePath; - } else if (!(request instanceof HttpServletRequest)) { + } else if (!(request instanceof HttpServletRequest hrequest)) { returnValue = relativePath; } else { - HttpServletRequest hrequest = (HttpServletRequest) request; String uri = (String) request.getAttribute("jakarta.servlet.include.servlet_path"); if (uri == null) { @@ -291,7 +292,7 @@ public static void include( String relativePath, Writer writer, ServletRequest r */ static final class PageOutputStream extends ServletOutputStream { - private FastByteArrayOutputStream buffer; + private final FastByteArrayOutputStream buffer; public PageOutputStream() { @@ -321,22 +322,27 @@ public FastByteArrayOutputStream getBuffer() throws IOException { return buffer; } + @Override public void close() throws IOException { buffer.close(); } + @Override public void flush() throws IOException { buffer.flush(); } + @Override public void write(byte[] b, int o, int l) throws IOException { buffer.write(b, o, l); } + @Override public void write(int i) throws IOException { buffer.write(i); } + @Override public void write(byte[] b) throws IOException { buffer.write(b); } @@ -363,8 +369,7 @@ public void write(byte[] b) throws IOException { */ static final class PageResponse extends HttpServletResponseWrapper { - protected PrintWriter pagePrintWriter; - protected ServletOutputStream outputStream; + private PrintWriter pagePrintWriter; private PageOutputStream pageOutputStream = null; @@ -375,7 +380,6 @@ public PageResponse(HttpServletResponse response) { super(response); } - /** * Return the content buffered inside the {@link PageOutputStream}. * @@ -397,6 +401,7 @@ public FastByteArrayOutputStream getContent() throws IOException { * Return instance of {@link PageOutputStream} * allowing all data written to stream to be stored in temporary buffer. */ + @Override public ServletOutputStream getOutputStream() throws IOException { if (pageOutputStream == null) { pageOutputStream = new PageOutputStream(); @@ -408,6 +413,7 @@ public ServletOutputStream getOutputStream() throws IOException { /** * Return PrintWriter wrapper around PageOutputStream. */ + @Override public PrintWriter getWriter() throws IOException { if (pagePrintWriter == null) { pagePrintWriter = new PrintWriter(new OutputStreamWriter(getOutputStream(), getCharacterEncoding())); diff --git a/core/src/main/java/org/apache/struts2/components/InputTransferSelect.java b/core/src/main/java/org/apache/struts2/components/InputTransferSelect.java index 1cab765e83..585f4c803e 100644 --- a/core/src/main/java/org/apache/struts2/components/InputTransferSelect.java +++ b/core/src/main/java/org/apache/struts2/components/InputTransferSelect.java @@ -19,14 +19,14 @@ package org.apache.struts2.components; import com.opensymphony.xwork2.util.ValueStack; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.struts2.views.annotations.StrutsTag; import org.apache.struts2.views.annotations.StrutsTagAttribute; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; import java.util.LinkedHashMap; import java.util.Map; @@ -193,7 +193,7 @@ public void evaluateExtraParams() { } else { if (LOG.isWarnEnabled()) { - LOG.warn("form enclosing inputtransferselect "+this+" not found, auto select upon form submit of inputtransferselect will not work"); + LOG.warn("form enclosing inputtransferselect {} not found, auto select upon form submit of inputtransferselect will not work", this); } } } diff --git a/core/src/main/java/org/apache/struts2/components/IteratorComponent.java b/core/src/main/java/org/apache/struts2/components/IteratorComponent.java index 7ff83bd458..b17943a0a5 100644 --- a/core/src/main/java/org/apache/struts2/components/IteratorComponent.java +++ b/core/src/main/java/org/apache/struts2/components/IteratorComponent.java @@ -289,8 +289,7 @@ public boolean start(Writer writer) { if (end == null) end = step > 0 ? values.length - 1 : 0; iterator = new CounterIterator(begin, end, step, Arrays.asList(values)); - } else if (iteratorTarget instanceof List) { - List values = (List) iteratorTarget; + } else if (iteratorTarget instanceof List values) { if (end == null) end = step > 0 ? values.size() - 1 : 0; iterator = new CounterIterator(begin, end, step, values); @@ -363,9 +362,9 @@ public boolean end(Writer writer, String body) { static class CounterIterator implements Iterator { private int step; - private int end; + private final int end; private int currentIndex; - private List values; + private final List values; CounterIterator(Integer begin, Integer end, Integer step, List values) { this.end = end; @@ -375,11 +374,13 @@ static class CounterIterator implements Iterator { this.values = values; } + @Override public boolean hasNext() { int next = peekNextIndex(); return step > 0 ? next <= end : next >= end; } + @Override public Object next() { if (hasNext()) { int nextIndex = peekNextIndex(); @@ -394,6 +395,7 @@ private int peekNextIndex() { return currentIndex + step; } + @Override public void remove() { throw new UnsupportedOperationException("Values cannot be removed from this iterator"); } diff --git a/core/src/main/java/org/apache/struts2/components/Label.java b/core/src/main/java/org/apache/struts2/components/Label.java index 2ffc5d7f8e..787f0f6583 100644 --- a/core/src/main/java/org/apache/struts2/components/Label.java +++ b/core/src/main/java/org/apache/struts2/components/Label.java @@ -18,14 +18,12 @@ */ package org.apache.struts2.components; +import com.opensymphony.xwork2.util.ValueStack; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; - +import org.apache.struts2.util.TextProviderHelper; import org.apache.struts2.views.annotations.StrutsTag; import org.apache.struts2.views.annotations.StrutsTagAttribute; -import org.apache.struts2.util.TextProviderHelper; - -import com.opensymphony.xwork2.util.ValueStack; /** * @@ -82,7 +80,7 @@ protected void evaluateExtraParams() { addParameter("nameValue", findString(value)); } else if (key != null) { Object nameValue = parameters.get("nameValue"); - if (nameValue == null || nameValue.toString().length() == 0) { + if (nameValue == null || nameValue.toString().isEmpty()) { // get the label from a TextProvider (default value is the key) String providedLabel = TextProviderHelper.getText(key, key, stack); addParameter("nameValue", providedLabel); diff --git a/core/src/main/java/org/apache/struts2/components/ListUIBean.java b/core/src/main/java/org/apache/struts2/components/ListUIBean.java index 362220cf6f..2e7d6587de 100644 --- a/core/src/main/java/org/apache/struts2/components/ListUIBean.java +++ b/core/src/main/java/org/apache/struts2/components/ListUIBean.java @@ -64,7 +64,7 @@ protected ListUIBean(ValueStack stack, HttpServletRequest request, HttpServletRe @Override public void evaluateExtraParams() { - Object value = null; + Object value; if (list == null) { list = parameters.get("list"); @@ -75,13 +75,13 @@ public void evaluateExtraParams() { if (value == null) { if (throwExceptionOnNullValueAttribute) { // will throw an exception if not found - value = findValue((list == null) ? (String) list : list.toString(), "list", + value = findValue(list == null ? null : list.toString(), "list", "The requested list key '" + list + "' could not be resolved as a collection/array/map/enumeration/iterator type. " + "Example: people or people.{name}"); } else { // ww-1010, allows value with null value to be compatible with ww // 2.1.7 behaviour - value = findValue((list == null) ? (String) list : list.toString()); + value = findValue(list == null ? null : list.toString()); } } } else { diff --git a/core/src/main/java/org/apache/struts2/components/Number.java b/core/src/main/java/org/apache/struts2/components/Number.java index 7ca45b14c2..f1e1d79b18 100644 --- a/core/src/main/java/org/apache/struts2/components/Number.java +++ b/core/src/main/java/org/apache/struts2/components/Number.java @@ -20,8 +20,8 @@ import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.util.ValueStack; -import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.apache.struts2.views.annotations.StrutsTag; import org.apache.struts2.views.annotations.StrutsTagAttribute; @@ -172,7 +172,7 @@ private void findCurrency(NumberFormat format) { try { format.setCurrency(Currency.getInstance(currency)); } catch (IllegalArgumentException iae) { - LOG.error("Could not recognise a currency of [" + currency + "]"); + LOG.error("Could not recognise a currency of [{}]", currency); } } } @@ -208,7 +208,7 @@ private java.lang.Number findNumberName() { number = (java.lang.Number) numberObject; } } catch (Exception e) { - LOG.error("Could not convert object with key [" + name + "] to a java.lang.Number instance"); + LOG.error("Could not convert object with key [{}] to a java.lang.Number instance", name); } return number; } @@ -233,7 +233,7 @@ private void setRoundingMode(NumberFormat format) { } else if ("up".equals(roundingMode)) { format.setRoundingMode(RoundingMode.UP); } else { - LOG.error("Could not recognise a roundingMode of [" + roundingMode + "]"); + LOG.error("Could not recognise a roundingMode of [{}]", roundingMode); } } } diff --git a/core/src/main/java/org/apache/struts2/components/OptGroup.java b/core/src/main/java/org/apache/struts2/components/OptGroup.java index 6483ad2094..d7fae9fa6b 100644 --- a/core/src/main/java/org/apache/struts2/components/OptGroup.java +++ b/core/src/main/java/org/apache/struts2/components/OptGroup.java @@ -18,21 +18,19 @@ */ package org.apache.struts2.components; -import java.io.Writer; -import java.util.ArrayList; -import java.util.List; - +import com.opensymphony.xwork2.inject.Container; +import com.opensymphony.xwork2.inject.Inject; +import com.opensymphony.xwork2.util.ValueStack; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; - +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.apache.struts2.views.annotations.StrutsTag; import org.apache.struts2.views.annotations.StrutsTagAttribute; -import com.opensymphony.xwork2.inject.Container; -import com.opensymphony.xwork2.inject.Inject; -import com.opensymphony.xwork2.util.ValueStack; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; +import java.io.Writer; +import java.util.ArrayList; +import java.util.List; /** * @@ -73,7 +71,7 @@ public class OptGroup extends Component { public static final String INTERNAL_LIST_UI_BEAN_LIST_PARAMETER_KEY = "optGroupInternalListUiBeanList"; - private static Logger LOG = LogManager.getLogger(OptGroup.class); + private static final Logger LOG = LogManager.getLogger(OptGroup.class); protected HttpServletRequest req; protected HttpServletResponse res; @@ -90,7 +88,7 @@ protected String getDefaultTemplate() { } }; } - + @Inject public void setContainer(Container container) { container.inject(internalUiBean); diff --git a/core/src/main/java/org/apache/struts2/components/OptionTransferSelect.java b/core/src/main/java/org/apache/struts2/components/OptionTransferSelect.java index 56a48a169b..6e340ce1d0 100644 --- a/core/src/main/java/org/apache/struts2/components/OptionTransferSelect.java +++ b/core/src/main/java/org/apache/struts2/components/OptionTransferSelect.java @@ -19,14 +19,14 @@ package org.apache.struts2.components; import com.opensymphony.xwork2.util.ValueStack; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.struts2.views.annotations.StrutsTag; import org.apache.struts2.views.annotations.StrutsTagAttribute; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; import java.util.LinkedHashMap; import java.util.Map; @@ -137,7 +137,7 @@ protected String getDefaultTemplate() { public void evaluateExtraParams() { super.evaluateExtraParams(); - Object doubleValue = null; + Object doubleValue; // override DoubleListUIBean's if (doubleList != null) { @@ -319,7 +319,7 @@ public void evaluateExtraParams() { } else { if (LOG.isWarnEnabled()) { - LOG.warn("form enclosing optiontransferselect "+this+" not found, auto select upon form submit of optiontransferselect will not work"); + LOG.warn("form enclosing optiontransferselect {} not found, auto select upon form submit of optiontransferselect will not work", this); } } } diff --git a/core/src/main/java/org/apache/struts2/components/Property.java b/core/src/main/java/org/apache/struts2/components/Property.java index 29aebe9fde..4351a8507f 100644 --- a/core/src/main/java/org/apache/struts2/components/Property.java +++ b/core/src/main/java/org/apache/struts2/components/Property.java @@ -134,7 +134,7 @@ public void setEscapeXml(boolean escapeXml) { public boolean start(Writer writer) { boolean result = super.start(writer); - String actualValue = null; + String actualValue; if (value == null) { value = "top"; diff --git a/core/src/main/java/org/apache/struts2/components/Radio.java b/core/src/main/java/org/apache/struts2/components/Radio.java index 88a6afc453..2b53484d06 100644 --- a/core/src/main/java/org/apache/struts2/components/Radio.java +++ b/core/src/main/java/org/apache/struts2/components/Radio.java @@ -19,11 +19,9 @@ package org.apache.struts2.components; import com.opensymphony.xwork2.util.ValueStack; -import org.apache.struts2.views.annotations.StrutsTag; -import org.apache.struts2.views.annotations.StrutsTagAttribute; - import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import org.apache.struts2.views.annotations.StrutsTag; /** * diff --git a/core/src/main/java/org/apache/struts2/components/Set.java b/core/src/main/java/org/apache/struts2/components/Set.java index 4d8f7c8981..750763050c 100644 --- a/core/src/main/java/org/apache/struts2/components/Set.java +++ b/core/src/main/java/org/apache/struts2/components/Set.java @@ -18,13 +18,12 @@ */ package org.apache.struts2.components; -import java.io.Writer; - +import com.opensymphony.xwork2.util.ValueStack; import org.apache.struts2.dispatcher.DispatcherConstants; import org.apache.struts2.views.annotations.StrutsTag; import org.apache.struts2.views.annotations.StrutsTagAttribute; -import com.opensymphony.xwork2.util.ValueStack; +import java.io.Writer; /** * @@ -76,7 +75,7 @@ * * */ -@StrutsTag(name="set", tldBodyContent="JSP", tldTagClass="org.apache.struts2.views.jsp.SetTag", description="Assigns a value to a variable in a specified scope") +@StrutsTag(name="set", tldTagClass="org.apache.struts2.views.jsp.SetTag", description="Assigns a value to a variable in a specified scope") public class Set extends ContextBean { protected String scope; protected String value; diff --git a/core/src/main/java/org/apache/struts2/components/Submit.java b/core/src/main/java/org/apache/struts2/components/Submit.java index 09ec301eea..eceb5df3dd 100644 --- a/core/src/main/java/org/apache/struts2/components/Submit.java +++ b/core/src/main/java/org/apache/struts2/components/Submit.java @@ -23,9 +23,6 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; -import com.opensymphony.xwork2.inject.Inject; -import org.apache.commons.lang3.BooleanUtils; -import org.apache.struts2.StrutsConstants; import org.apache.struts2.views.annotations.StrutsTag; import org.apache.struts2.views.annotations.StrutsTagAttribute; diff --git a/core/src/main/java/org/apache/struts2/components/UIBean.java b/core/src/main/java/org/apache/struts2/components/UIBean.java index d501442fb6..ff89c035da 100644 --- a/core/src/main/java/org/apache/struts2/components/UIBean.java +++ b/core/src/main/java/org/apache/struts2/components/UIBean.java @@ -22,6 +22,8 @@ import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.util.TextParseUtil; import com.opensymphony.xwork2.util.ValueStack; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; @@ -38,8 +40,6 @@ import org.apache.struts2.views.annotations.StrutsTagAttribute; import org.apache.struts2.views.util.ContextUtil; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; import java.io.Writer; import java.util.HashMap; import java.util.LinkedHashMap; @@ -974,11 +974,10 @@ protected Map getTooltipConfig(UIBean component) { // 2] param tag value attribute result = new LinkedHashMap((Map) tooltipConfigObj); - } else if (tooltipConfigObj instanceof String) { + } else if (tooltipConfigObj instanceof String tooltipConfigStr) { // we get this if its configured using // ... tag's body - String tooltipConfigStr = (String) tooltipConfigObj; String[] tooltipConfigArray = tooltipConfigStr.split("\\|"); for (String aTooltipConfigArray : tooltipConfigArray) { diff --git a/core/src/main/java/org/apache/struts2/components/URL.java b/core/src/main/java/org/apache/struts2/components/URL.java index 5f9198e8b1..2da816f658 100644 --- a/core/src/main/java/org/apache/struts2/components/URL.java +++ b/core/src/main/java/org/apache/struts2/components/URL.java @@ -20,12 +20,12 @@ import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.util.ValueStack; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.apache.struts2.StrutsConstants; import org.apache.struts2.views.annotations.StrutsTag; import org.apache.struts2.views.annotations.StrutsTagAttribute; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; import java.io.Writer; /** @@ -106,7 +106,7 @@ @StrutsTag(name="url", tldTagClass="org.apache.struts2.views.jsp.URLTag", description="This tag is used to create a URL") public class URL extends ContextBean { - private UrlProvider urlProvider; + private final UrlProvider urlProvider; private UrlRenderer urlRenderer; public URL(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { diff --git a/core/src/main/java/org/apache/struts2/components/UpDownSelect.java b/core/src/main/java/org/apache/struts2/components/UpDownSelect.java index 238cf4410b..2c6c0d287a 100644 --- a/core/src/main/java/org/apache/struts2/components/UpDownSelect.java +++ b/core/src/main/java/org/apache/struts2/components/UpDownSelect.java @@ -19,14 +19,14 @@ package org.apache.struts2.components; import com.opensymphony.xwork2.util.ValueStack; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.struts2.views.annotations.StrutsTag; import org.apache.struts2.views.annotations.StrutsTagAttribute; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; import java.util.LinkedHashMap; import java.util.Map; @@ -70,7 +70,7 @@ * {@literal @}s.tag name="updownselect" tld-body-content="JSP" tld-tag-class="org.apache.struts2.views.jsp.ui.UpDownSelectTag" * description="Render a up down select element" */ -@StrutsTag(name="updownselect", tldTagClass="org.apache.struts2.views.jsp.ui.UpDownSelectTag", +@StrutsTag(name="updownselect", tldTagClass="org.apache.struts2.views.jsp.ui.UpDownSelectTag", description="Create a Select component with buttons to move the elements in the select component up and down") public class UpDownSelect extends Select { @@ -146,7 +146,7 @@ public void evaluateParams() { } else { if (LOG.isWarnEnabled()) { - LOG.warn("no ancestor form found for updownselect "+this+", therefore autoselect of all elements upon form submission will not work "); + LOG.warn("no ancestor form found for updownselect {}, therefore autoselect of all elements upon form submission will not work ", this); } } } diff --git a/core/src/main/java/org/apache/struts2/components/template/FreemarkerTemplateEngine.java b/core/src/main/java/org/apache/struts2/components/template/FreemarkerTemplateEngine.java index 2e82ed6374..2f46a42ed9 100644 --- a/core/src/main/java/org/apache/struts2/components/template/FreemarkerTemplateEngine.java +++ b/core/src/main/java/org/apache/struts2/components/template/FreemarkerTemplateEngine.java @@ -26,18 +26,16 @@ import freemarker.core.ParseException; import freemarker.template.Configuration; import freemarker.template.SimpleHash; +import jakarta.servlet.ServletContext; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.apache.struts2.ServletActionContext; import org.apache.struts2.views.freemarker.FreemarkerManager; -import jakarta.servlet.ServletContext; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.Writer; import java.util.List; -import java.util.Map; /** * Freemarker based template engine. @@ -135,7 +133,7 @@ public void renderTemplate(TemplateRenderingContext templateContext) throws Exce Writer writer = templateContext.getWriter(); final Writer wrapped = writer; writer = new Writer() { - public void write(char cbuf[], int off, int len) throws IOException { + public void write(char[] cbuf, int off, int len) throws IOException { wrapped.write(cbuf, off, len); } diff --git a/core/src/main/java/org/apache/struts2/components/template/JspTemplateEngine.java b/core/src/main/java/org/apache/struts2/components/template/JspTemplateEngine.java index 5c308bb9a4..7707a050c1 100644 --- a/core/src/main/java/org/apache/struts2/components/template/JspTemplateEngine.java +++ b/core/src/main/java/org/apache/struts2/components/template/JspTemplateEngine.java @@ -20,6 +20,8 @@ import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.util.ValueStack; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.jsp.PageContext; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.struts2.ServletActionContext; @@ -27,8 +29,6 @@ import org.apache.struts2.components.Include; import org.apache.struts2.components.UIBean; -import jakarta.servlet.http.HttpServletResponse; -import jakarta.servlet.jsp.PageContext; import java.util.List; /** @@ -44,6 +44,7 @@ public void setEncoding(String encoding) { this.encoding = encoding; } + @Override public void renderTemplate(TemplateRenderingContext templateContext) throws Exception { Template template = templateContext.getTemplate(); @@ -81,6 +82,7 @@ public void renderTemplate(TemplateRenderingContext templateContext) throws Exce stack.pop(); } + @Override protected String getSuffix() { return "jsp"; } diff --git a/core/src/main/java/org/apache/struts2/components/template/Template.java b/core/src/main/java/org/apache/struts2/components/template/Template.java index 26dbe5e69b..f3a47f226a 100644 --- a/core/src/main/java/org/apache/struts2/components/template/Template.java +++ b/core/src/main/java/org/apache/struts2/components/template/Template.java @@ -20,6 +20,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Objects; /** *

      @@ -58,7 +59,7 @@ public String getName() { } public List