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 <[email protected]>
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. -->