This is an automated email from the ASF dual-hosted git repository. kusal pushed a commit to branch kusal-depr-apis-8 in repository https://gitbox.apache.org/repos/asf/struts.git
commit ef0825e2cf0d7e9daf1bae1b80d0641d4e4f2c4c Author: Kusal Kithul-Godage <g...@kusal.io> AuthorDate: Thu Oct 17 19:00:07 2024 +1100 WW-3714 Deprecate and migrate (Field)ValidationSupport --- .../opensymphony/xwork2/util/TextParseUtil.java | 4 + .../validators/FieldValidatorSupport.java | 60 ++++++ .../validator/validators/ValidatorSupport.java | 221 +++++++++++++++++++++ 3 files changed, 285 insertions(+) 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 9220159bf..9b61f3e88 100644 --- a/core/src/main/java/com/opensymphony/xwork2/util/TextParseUtil.java +++ b/core/src/main/java/com/opensymphony/xwork2/util/TextParseUtil.java @@ -104,6 +104,10 @@ public class TextParseUtil { return translateVariables(open, expression, stack, asType, null); } + public static Object translateVariables(char open, String expression, org.apache.struts2.util.ValueStack stack, Class asType) { + return translateVariables(open, expression, ValueStack.adapt(stack), asType); + } + /** * Converted object from variable translation. * diff --git a/core/src/main/java/org/apache/struts2/validator/validators/FieldValidatorSupport.java b/core/src/main/java/org/apache/struts2/validator/validators/FieldValidatorSupport.java new file mode 100644 index 000000000..bdbd62210 --- /dev/null +++ b/core/src/main/java/org/apache/struts2/validator/validators/FieldValidatorSupport.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.struts2.validator.validators; + +import org.apache.struts2.validator.FieldValidator; + +/** + * Base class for field validators. + * + * You can access fieldName and its currentValue in a message using expression, e.g. + * "Wrong value ${currentValue} for ${fieldName}" + */ +public abstract class FieldValidatorSupport extends ValidatorSupport implements FieldValidator { + + protected String fieldName; + protected String type; + protected Object currentValue; + + public void setFieldName(String fieldName) { + this.fieldName = fieldName; + } + + public String getFieldName() { + return fieldName; + } + + @Override + public void setValidatorType(String type) { + this.type = type; + } + + @Override + public String getValidatorType() { + return type; + } + + public Object getCurrentValue() { + return currentValue; + } + + void setCurrentValue(Object currentValue) { + this.currentValue = currentValue; + } +} diff --git a/core/src/main/java/org/apache/struts2/validator/validators/ValidatorSupport.java b/core/src/main/java/org/apache/struts2/validator/validators/ValidatorSupport.java new file mode 100644 index 000000000..07bb9616a --- /dev/null +++ b/core/src/main/java/org/apache/struts2/validator/validators/ValidatorSupport.java @@ -0,0 +1,221 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.struts2.validator.validators; + +import com.opensymphony.xwork2.TextProviderFactory; +import com.opensymphony.xwork2.inject.Inject; +import com.opensymphony.xwork2.util.TextParseUtil; +import com.opensymphony.xwork2.validator.DelegatingValidatorContext; +import org.apache.commons.lang3.StringUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.struts2.util.ValueStack; +import org.apache.struts2.validator.ShortCircuitableValidator; +import org.apache.struts2.validator.ValidationException; +import org.apache.struts2.validator.Validator; +import org.apache.struts2.validator.ValidatorContext; + +import java.util.ArrayList; +import java.util.List; + +/** + * Abstract implementation of the Validator interface suitable for subclassing. + * + * @author Jason Carreira + * @author tm_jee + * @author Martin Gilday + */ +public abstract class ValidatorSupport implements Validator, ShortCircuitableValidator { + + private static final Logger LOG = LogManager.getLogger(ValidatorSupport.class); + + public static final String EMPTY_STRING = ""; + + private ValidatorContext validatorContext; + private boolean shortCircuit; + private String type; + private String[] messageParameters; + + protected String defaultMessage = ""; + protected String messageKey; + protected ValueStack stack; + protected TextProviderFactory textProviderFactory; + + @Inject + public void setTextProviderFactory(TextProviderFactory textProviderFactory) { + this.textProviderFactory = textProviderFactory; + } + + public void setValueStack(ValueStack stack) { + this.stack = stack; + } + + public void setDefaultMessage(String message) { + if (StringUtils.isNotEmpty(message)) { + this.defaultMessage = message; + } + } + + public String getDefaultMessage() { + return defaultMessage; + } + + public String getMessage(Object object) { + String message; + boolean pop = false; + + if (!stack.getRoot().contains(object)) { + stack.push(object); + pop = true; + } + + stack.push(this); + + if (messageKey != null) { + if ((defaultMessage == null) || ("".equals(defaultMessage.trim()))) { + defaultMessage = messageKey; + } + if (validatorContext == null) { + validatorContext = new DelegatingValidatorContext(object, textProviderFactory); + } + List<Object> parsedMessageParameters = null; + if (messageParameters != null) { + parsedMessageParameters = new ArrayList<>(); + for (String messageParameter : messageParameters) { + if (messageParameter != null) { + try { + Object val = stack.findValue(messageParameter); + parsedMessageParameters.add(val); + } catch (Exception e) { + // if there's an exception in parsing, we'll just treat the expression itself as the + // parameter + LOG.warn("exception while parsing message parameter [{}]", messageParameter, e); + parsedMessageParameters.add(messageParameter); + } + } + } + } + + message = validatorContext.getText(messageKey, defaultMessage, parsedMessageParameters); + } else { + message = defaultMessage; + } + + if (StringUtils.isNotBlank(message)) + message = TextParseUtil.translateVariables(message, stack); + + stack.pop(); + + if (pop) { + stack.pop(); + } + + return message; + } + + public void setMessageKey(String key) { + messageKey = key; + } + + public String getMessageKey() { + return messageKey; + } + + public String[] getMessageParameters() { + return this.messageParameters; + } + + public void setMessageParameters(String[] messageParameters) { + this.messageParameters = messageParameters; + } + + public void setShortCircuit(boolean shortcircuit) { + shortCircuit = shortcircuit; + } + + public boolean isShortCircuit() { + return shortCircuit; + } + + public void setValidatorContext(ValidatorContext validatorContext) { + this.validatorContext = validatorContext; + } + + public ValidatorContext getValidatorContext() { + return validatorContext; + } + + public void setValidatorType(String type) { + this.type = type; + } + + public String getValidatorType() { + return type; + } + + /** + * Parse <code>expression</code> passed in against value stack. + * + * @param expression an OGNL expression + * @param type type to return + * @return Object + */ + protected Object parse(String expression, Class type) { + if (expression == null) { + return null; + } + return TextParseUtil.translateVariables('$', expression, stack, type); + } + + /** + * Return the field value named <code>name</code> from <code>object</code>, + * <code>object</code> should have the appropriate getter/setter. + * + * @param name name of the field + * @param object to search field name on + * @return Object as field value + * @throws ValidationException in case of validation problems + */ + protected Object getFieldValue(String name, Object object) throws ValidationException { + + boolean pop = false; + + if (!stack.getRoot().contains(object)) { + stack.push(object); + pop = true; + } + + Object retVal = stack.findValue(name); + + if (pop) { + stack.pop(); + } + + return retVal; + } + + protected void addActionError(Object object) { + validatorContext.addActionError(getMessage(object)); + } + + protected void addFieldError(String propertyName, Object object) { + validatorContext.addFieldError(propertyName, getMessage(object)); + } + +}