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));
+    }
+
+}

Reply via email to