This is an automated email from the ASF dual-hosted git repository.

lukaszlenart pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/struts.git


The following commit(s) were added to refs/heads/master by this push:
     new c094052  Uses Java Reflections instead BeanUtils to read property
c094052 is described below

commit c0940529690697611aaab38ea9ea1186d909267b
Author: Lukasz Lenart <lukaszlen...@apache.org>
AuthorDate: Fri Mar 4 12:52:33 2022 +0100

    Uses Java Reflections instead BeanUtils to read property
---
 .../validation/BeanValidationExampleAction.java    | 30 ++++----
 .../conversion/annotations/TypeConversion.java     |  3 +-
 plugins/bean-validation/pom.xml                    | 18 +++--
 .../constraints/impl/FieldMatchValidator.java      | 19 ++++-
 .../constraints/impl/FieldMatchValidatorTest.java  | 84 ++++++++++++++++++++++
 pom.xml                                            |  2 +-
 6 files changed, 129 insertions(+), 27 deletions(-)

diff --git 
a/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/BeanValidationExampleAction.java
 
b/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/BeanValidationExampleAction.java
index 67190e0..4c07f51 100644
--- 
a/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/BeanValidationExampleAction.java
+++ 
b/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/BeanValidationExampleAction.java
@@ -27,22 +27,24 @@ import org.apache.struts2.convention.annotation.Namespace;
 import org.apache.struts2.convention.annotation.ParentPackage;
 import org.apache.struts2.convention.annotation.Result;
 import org.apache.struts2.interceptor.validation.SkipValidation;
-import org.hibernate.validator.constraints.Email;
-import org.hibernate.validator.constraints.NotBlank;
 import org.hibernate.validator.constraints.ScriptAssert;
 import org.hibernate.validator.constraints.URL;
 
-import javax.validation.constraints.*;
+import javax.validation.constraints.Email;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Pattern;
+import javax.validation.constraints.Size;
 import java.util.Date;
 
-/**
- * <!-- START SNIPPET: beanValidatationExample -->
- */
+// <!-- START SNIPPET: beanValidationExample -->
 @Namespace("/bean-validation")
 @ParentPackage("bean-validation")
 @Action(results = {
-        @Result(name = "input", location = "bean-validation.jsp"),
-        @Result(name = "success", location = 
"/WEB-INF/validation/successFieldValidatorsExample.jsp")
+    @Result(name = "input", location = "bean-validation.jsp"),
+    @Result(name = "success", location = 
"/WEB-INF/validation/successFieldValidatorsExample.jsp")
 })
 @FieldMatch(first = "fieldExpressionValidatorField", second = 
"requiredValidatorField", message = "requiredValidatorField and 
fieldExpressionValidatorField are not matching")
 @ScriptAssert(lang = "javascript", script = "_this.dateValidatorField != null 
&& _this.dateValidatorField.before(new java.util.Date())", message = "Date need 
to before now")
@@ -82,10 +84,10 @@ public class BeanValidationExampleAction extends 
ActionSupport {
     private String fieldExpressionValidatorField = null;
 
     @Action(value = "bean-validation", results = {
-            @Result(name = "success", location = "bean-validation.jsp")
+        @Result(name = "success", location = "bean-validation.jsp")
     })
     @SkipValidation
-    public String beanValidation(){
+    public String beanValidation() {
         return SUCCESS;
     }
 
@@ -150,7 +152,7 @@ public class BeanValidationExampleAction extends 
ActionSupport {
     }
 
     public void setFieldExpressionValidatorField(
-            String fieldExpressionValidatorField) {
+        String fieldExpressionValidatorField) {
         this.fieldExpressionValidatorField = fieldExpressionValidatorField;
     }
 
@@ -163,8 +165,4 @@ public class BeanValidationExampleAction extends 
ActionSupport {
     }
 }
 
-/**
- * <!-- END SNIPPET: beanValidatationExample -->
- */
-
-
+// <!-- END SNIPPET: beanValidationExample -->
diff --git 
a/core/src/main/java/com/opensymphony/xwork2/conversion/annotations/TypeConversion.java
 
b/core/src/main/java/com/opensymphony/xwork2/conversion/annotations/TypeConversion.java
index 6c86d4a..eda8a58 100644
--- 
a/core/src/main/java/com/opensymphony/xwork2/conversion/annotations/TypeConversion.java
+++ 
b/core/src/main/java/com/opensymphony/xwork2/conversion/annotations/TypeConversion.java
@@ -38,7 +38,8 @@ import java.lang.annotation.Target;
  *
  * <p>
  * Application wide conversion:<br>
- * The conversion rules will be assembled within the 
<code>xwork-conversion.properties</code> file within the classpath root.
+ * The conversion rules will be assembled within the 
<code>struts-conversion.properties</code> or
+ * <code>xwork-conversion.properties</code> (deprecated) file within the 
classpath root.
  * Set type to: <code>type = ConversionType.APPLICATION</code>
  * </p>
  * <!-- END SNIPPET: description -->
diff --git a/plugins/bean-validation/pom.xml b/plugins/bean-validation/pom.xml
index b593675..aed8f05 100644
--- a/plugins/bean-validation/pom.xml
+++ b/plugins/bean-validation/pom.xml
@@ -45,11 +45,6 @@
         </dependency>
 
         <dependency>
-            <groupId>commons-beanutils</groupId>
-            <artifactId>commons-beanutils</artifactId>
-        </dependency>
-
-        <dependency>
             <groupId>org.hibernate</groupId>
             <artifactId>hibernate-validator</artifactId>
             <version>6.1.2.Final</version>
@@ -60,6 +55,17 @@
             <artifactId>javax.el</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <!-- this library is excluded in the parent pom as it clashes with 
Easymock dependencies -->
+        <dependency>
+            <groupId>org.objenesis</groupId>
+            <artifactId>objenesis</artifactId>
+            <version>3.2</version>
+        </dependency>
 
         <!--
          The Java EE API modules listed below are all marked 
@Deprecated(forRemoval=true), because they are scheduled
@@ -94,4 +100,4 @@
 
     </dependencies>
 
-</project>
\ No newline at end of file
+</project>
diff --git 
a/plugins/bean-validation/src/main/java/org/apache/struts/beanvalidation/constraints/impl/FieldMatchValidator.java
 
b/plugins/bean-validation/src/main/java/org/apache/struts/beanvalidation/constraints/impl/FieldMatchValidator.java
index 9ad2d19..40837cb 100644
--- 
a/plugins/bean-validation/src/main/java/org/apache/struts/beanvalidation/constraints/impl/FieldMatchValidator.java
+++ 
b/plugins/bean-validation/src/main/java/org/apache/struts/beanvalidation/constraints/impl/FieldMatchValidator.java
@@ -20,17 +20,20 @@
  */
 package org.apache.struts.beanvalidation.constraints.impl;
 
-import org.apache.commons.beanutils.PropertyUtils;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.apache.struts.beanvalidation.constraints.FieldMatch;
 
 import javax.validation.ConstraintValidator;
 import javax.validation.ConstraintValidatorContext;
+import java.beans.BeanInfo;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
 
 public class FieldMatchValidator implements ConstraintValidator<FieldMatch, 
Object> {
 
     private static final Logger LOG = 
LogManager.getLogger(FieldMatchValidator.class);
+
     private String firstFieldName;
     private String secondFieldName;
 
@@ -41,13 +44,23 @@ public class FieldMatchValidator implements 
ConstraintValidator<FieldMatch, Obje
 
     public boolean isValid(final Object value, final 
ConstraintValidatorContext context) {
         try {
-            final Object firstObj = PropertyUtils.getProperty(value, 
this.firstFieldName);
-            final Object secondObj = PropertyUtils.getProperty(value, 
this.secondFieldName);
+            final Object firstObj = readPropertyValue(value, 
this.firstFieldName);
+            final Object secondObj = readPropertyValue(value, 
this.secondFieldName);
             return firstObj == null && secondObj == null || firstObj != null 
&& firstObj.equals(secondObj);
         } catch (final Exception ex) {
             LOG.info("Error while getting values from object", ex);
             return false;
         }
+    }
 
+    private Object readPropertyValue(Object bean, String propertyName) throws 
Exception {
+        BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass());
+        for (PropertyDescriptor descriptor : 
beanInfo.getPropertyDescriptors()) {
+            if (propertyName.equals(descriptor.getName())) {
+                return descriptor.getReadMethod().invoke(bean);
+            }
+        }
+        return null;
     }
+
 }
diff --git 
a/plugins/bean-validation/src/test/java/org/apache/struts/beanvalidation/constraints/impl/FieldMatchValidatorTest.java
 
b/plugins/bean-validation/src/test/java/org/apache/struts/beanvalidation/constraints/impl/FieldMatchValidatorTest.java
new file mode 100644
index 0000000..5b5608c
--- /dev/null
+++ 
b/plugins/bean-validation/src/test/java/org/apache/struts/beanvalidation/constraints/impl/FieldMatchValidatorTest.java
@@ -0,0 +1,84 @@
+/*
+ * 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.struts.beanvalidation.constraints.impl;
+
+import org.apache.struts.beanvalidation.constraints.FieldMatch;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import javax.validation.ConstraintValidatorContext;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class FieldMatchValidatorTest {
+
+    @Test
+    public void matchingFields() {
+        // given
+        FieldMatchValidator validator = new FieldMatchValidator();
+        
validator.initialize(FieldMatchTestBean.class.getAnnotation(FieldMatch.class));
+
+        ConstraintValidatorContext context = 
Mockito.mock(ConstraintValidatorContext.class);
+
+        // when
+        FieldMatchTestBean bean = new FieldMatchTestBean("12345678", 
"12345678");
+
+        boolean valid = validator.isValid(bean, context);
+
+        // then
+        assertTrue(valid);
+    }
+
+    @Test
+    public void notMatchingFields() {
+        // given
+        FieldMatchValidator validator = new FieldMatchValidator();
+        
validator.initialize(FieldMatchTestBean.class.getAnnotation(FieldMatch.class));
+
+        ConstraintValidatorContext context = 
Mockito.mock(ConstraintValidatorContext.class);
+
+        // when
+        FieldMatchTestBean bean = new FieldMatchTestBean("12345678", 
"87654321");
+
+        boolean valid = validator.isValid(bean, context);
+
+        // then
+        assertFalse(valid);
+    }
+
+    @FieldMatch(first = "password", second = "repeatPassword")
+    public static class FieldMatchTestBean {
+        String password;
+        String repeatPassword;
+
+        public FieldMatchTestBean(String password, String repeatPassword) {
+            this.password = password;
+            this.repeatPassword = repeatPassword;
+        }
+
+        public String getPassword() {
+            return password;
+        }
+
+        public String getRepeatPassword() {
+            return repeatPassword;
+        }
+    }
+}
diff --git a/pom.xml b/pom.xml
index cc586d6..a238c0c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1075,7 +1075,7 @@
             <dependency>
                 <groupId>org.mockito</groupId>
                 <artifactId>mockito-core</artifactId>
-                <version>3.3.3</version>
+                <version>4.3.1</version>
                 <exclusions>
                     <!-- The mockito-core artifact and easymock artifact use 
different versions of objenesis (2.6 vs 3.1).
                          Excluding the older version here to pass enforcer.  
When next upgrading mockito-core, confirm whether this exclusion is still 
required. -->

Reply via email to