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

mridulpathak pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ofbiz-framework.git


The following commit(s) were added to refs/heads/trunk by this push:
     new 68a5b47c7b Make entity condition lists and field maps immutable
68a5b47c7b is described below

commit 68a5b47c7b4901fc32584c7ddc1c3f047e39cb4f
Author: Mridul Pathak <[email protected]>
AuthorDate: Mon Oct 26 23:17:24 2026 +0530

    Make entity condition lists and field maps immutable
    
    EntityConditionListBase and EntityFieldMap now keep an unmodifiable copy of 
the list or map they are built from, instead of holding on to the caller's 
collection, so later changes to the source no longer alter the condition and 
getConditions() can't be used to modify it. The varargs makeCondition factories 
copy their elements into a new list rather than wrapping the array with 
Arrays.asList, which lets the build drop the -Xlint:-varargs exclusion. The 
EntityFieldMap varargs constructo [...]
---
 build.gradle                                        |  2 --
 .../ofbiz/base/util/collections/MapContextTest.java |  2 --
 .../ofbiz/entity/condition/EntityCondition.java     | 20 ++++++++++++++------
 .../entity/condition/EntityConditionListBase.java   |  7 +++++--
 .../ofbiz/entity/condition/EntityFieldMap.java      | 21 ++++-----------------
 .../org/apache/ofbiz/entity/util/EntityUtil.java    |  9 ++++-----
 6 files changed, 27 insertions(+), 34 deletions(-)

diff --git a/build.gradle b/build.gradle
index 3875426e1f..254b3b130e 100644
--- a/build.gradle
+++ b/build.gradle
@@ -212,8 +212,6 @@ tasks.withType(JavaCompile) {
     options.encoding = 'UTF-8'
     if (!project.hasProperty('Xlint:none')) {
         options.compilerArgs << '-Xlint:all'
-        // Exclude varargs warnings which are not silenced by @SafeVarargs.
-        options.compilerArgs << '-Xlint:-varargs'
         // this-escape lint was introduced in JDK 21's javac and is an invalid 
flag on JDK 17,
         // so only pass it when compiling with a JDK that recognizes it.
         if (JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_21)) {
diff --git 
a/framework/base/src/test/java/org/apache/ofbiz/base/util/collections/MapContextTest.java
 
b/framework/base/src/test/java/org/apache/ofbiz/base/util/collections/MapContextTest.java
index 723da34b77..c9acf602a4 100644
--- 
a/framework/base/src/test/java/org/apache/ofbiz/base/util/collections/MapContextTest.java
+++ 
b/framework/base/src/test/java/org/apache/ofbiz/base/util/collections/MapContextTest.java
@@ -48,7 +48,6 @@ public class MapContextTest {
          * Constructs a node without properties.
          * @param includes  the included nodes
          */
-        @SafeVarargs
         PNode(PNode... includes) {
             this(Collections.emptyMap(), includes);
         }
@@ -58,7 +57,6 @@ public class MapContextTest {
          * @param props  the properties of the node
          * @param includes  the included nodes
          */
-        @SafeVarargs
         PNode(Map<String, String> props, PNode... includes) {
             this.props = props;
             this.includes = Arrays.asList(includes);
diff --git 
a/framework/entity/src/main/java/org/apache/ofbiz/entity/condition/EntityCondition.java
 
b/framework/entity/src/main/java/org/apache/ofbiz/entity/condition/EntityCondition.java
index a994adc351..538800c1af 100644
--- 
a/framework/entity/src/main/java/org/apache/ofbiz/entity/condition/EntityCondition.java
+++ 
b/framework/entity/src/main/java/org/apache/ofbiz/entity/condition/EntityCondition.java
@@ -20,7 +20,6 @@ package org.apache.ofbiz.entity.condition;
 
 import java.io.Serializable;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 
@@ -30,6 +29,7 @@ import org.apache.ofbiz.entity.GenericEntity;
 import org.apache.ofbiz.entity.GenericModelException;
 import org.apache.ofbiz.entity.config.model.Datasource;
 import org.apache.ofbiz.entity.model.ModelEntity;
+import org.apache.ofbiz.entity.util.EntityUtil;
 
 /**
  * Represents a condition expression that can be used in a SQL 'WHERE' clause
@@ -88,7 +88,11 @@ public interface EntityCondition extends IsEmpty, 
Serializable {
     @SafeVarargs
     static <R extends EntityCondition, T extends R>
             EntityConditionList<R> makeCondition(EntityJoinOperator operator, 
T... conditionList) {
-        return new EntityConditionList<>(Arrays.asList(conditionList), 
operator);
+        List<R> conditions = new ArrayList<>(conditionList.length);
+        for (T condition : conditionList) {
+            conditions.add(condition);
+        }
+        return new EntityConditionList<>(conditions, operator);
     }
 
     /**
@@ -99,7 +103,11 @@ public interface EntityCondition extends IsEmpty, 
Serializable {
     @SafeVarargs
     static <R extends EntityCondition, T extends R>
             EntityConditionList<R> makeCondition(T... conditionList) {
-        return new EntityConditionList<>(Arrays.asList(conditionList), 
EntityOperator.AND);
+        List<R> conditions = new ArrayList<>(conditionList.length);
+        for (T condition : conditionList) {
+            conditions.add(condition);
+        }
+        return new EntityConditionList<>(conditions, EntityOperator.AND);
     }
 
     /**
@@ -162,7 +170,7 @@ public interface EntityCondition extends IsEmpty, 
Serializable {
      */
     static <L, R> EntityFieldMap makeCondition(EntityComparisonOperator<L, R> 
compOp, EntityJoinOperator joinOp,
             Object... keysValues) {
-        return new EntityFieldMap(compOp, joinOp, keysValues);
+        return new EntityFieldMap(EntityUtil.makeFields(keysValues), compOp, 
joinOp);
     }
 
     /**
@@ -172,7 +180,7 @@ public interface EntityCondition extends IsEmpty, 
Serializable {
      * @return a condition expression representing a combination of 
field/value equality comparisons
      */
     static EntityFieldMap makeCondition(EntityJoinOperator joinOp, Object... 
keysValues) {
-        return new EntityFieldMap(EntityOperator.EQUALS, joinOp, keysValues);
+        return new EntityFieldMap(EntityUtil.makeFields(keysValues), 
EntityOperator.EQUALS, joinOp);
     }
 
     /**
@@ -181,7 +189,7 @@ public interface EntityCondition extends IsEmpty, 
Serializable {
      * @return a condition expression representing a conjunction of 
field/value equality comparisons
      */
     static EntityFieldMap makeConditionMap(Object... keysValues) {
-        return new EntityFieldMap(EntityOperator.EQUALS, EntityOperator.AND, 
keysValues);
+        return new EntityFieldMap(EntityUtil.makeFields(keysValues), 
EntityOperator.EQUALS, EntityOperator.AND);
     }
 
     /**
diff --git 
a/framework/entity/src/main/java/org/apache/ofbiz/entity/condition/EntityConditionListBase.java
 
b/framework/entity/src/main/java/org/apache/ofbiz/entity/condition/EntityConditionListBase.java
index 90042f3e82..0e5faf9bac 100644
--- 
a/framework/entity/src/main/java/org/apache/ofbiz/entity/condition/EntityConditionListBase.java
+++ 
b/framework/entity/src/main/java/org/apache/ofbiz/entity/condition/EntityConditionListBase.java
@@ -18,6 +18,8 @@
  
*******************************************************************************/
 package org.apache.ofbiz.entity.condition;
 
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 
@@ -37,18 +39,19 @@ abstract class EntityConditionListBase<T extends 
EntityCondition> implements Ent
         return conditions;
     }
 
-    /** The list of condition expressions to combine.  */
+    /** The unmodifiable list of condition expressions to combine.  */
     private final List<? extends T> conditions;
     /** The infix operator used to combine every elements in the list of 
conditions.  */
     private final EntityJoinOperator operator;
 
     /**
      * Constructs a combination of multiple condition expressions.
+     * The list is copied, so later changes to {@code conditions} do not 
affect this condition.
      * @param conditions the list of condition expressions to combine
      * @param operator the infix operator used to combine every elements in 
the list of conditions
      */
     protected EntityConditionListBase(List<? extends T> conditions, 
EntityJoinOperator operator) {
-        this.conditions = conditions;
+        this.conditions = Collections.unmodifiableList(new 
ArrayList<>(conditions));
         this.operator = operator;
     }
 
diff --git 
a/framework/entity/src/main/java/org/apache/ofbiz/entity/condition/EntityFieldMap.java
 
b/framework/entity/src/main/java/org/apache/ofbiz/entity/condition/EntityFieldMap.java
index 2cff636708..67af58856b 100644
--- 
a/framework/entity/src/main/java/org/apache/ofbiz/entity/condition/EntityFieldMap.java
+++ 
b/framework/entity/src/main/java/org/apache/ofbiz/entity/condition/EntityFieldMap.java
@@ -20,12 +20,12 @@ package org.apache.ofbiz.entity.condition;
 
 import java.util.Collections;
 import java.util.Iterator;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
 
 import org.apache.ofbiz.base.util.UtilGenerics;
-import org.apache.ofbiz.entity.util.EntityUtil;
 
 /**
  * A condition expression corresponding to an unordered collection of
@@ -40,7 +40,7 @@ import org.apache.ofbiz.entity.util.EntityUtil;
 @SuppressWarnings("serial")
 public final class EntityFieldMap extends EntityConditionListBase<EntityExpr> {
 
-    /** The map whose entries correspond to the set of equality checks 
conditions. */
+    /** The unmodifiable map whose entries correspond to the set of equality 
checks conditions. */
     private final Map<String, ?> fieldMap;
 
     /**
@@ -59,20 +59,7 @@ public final class EntityFieldMap extends 
EntityConditionListBase<EntityExpr> {
 
     /**
      * Constructs a map of fields.
-     * @param compOp the operator used to compare fields
-     * @param joinOp the operator used to join field comparisons
-     * @param keysValues a list of values that the field map will contain.
-     *        This list must be of even length and each successive pair will
-     *        be associated in the field map.
-     * @param <V> The type of values that are compared.
-     */
-    @SafeVarargs
-    public <V> EntityFieldMap(EntityComparisonOperator<?, ?> compOp, 
EntityJoinOperator joinOp, V... keysValues) {
-        this(EntityUtil.makeFields(keysValues), UtilGenerics.cast(compOp), 
joinOp);
-    }
-
-    /**
-     * Constructs a map of fields.
+     * The map is copied in its iteration order, so later changes to {@code 
fieldMap} do not affect this condition.
      * @param fieldMap the map containing the fields to compare
      * @param compOp the operator to compare fields
      * @param joinOp the operator to join entries in the field map
@@ -81,7 +68,7 @@ public final class EntityFieldMap extends 
EntityConditionListBase<EntityExpr> {
     public <V> EntityFieldMap(Map<String, V> fieldMap, 
EntityComparisonOperator<?, ?> compOp,
                               EntityJoinOperator joinOp) {
         super(makeConditionList(fieldMap, UtilGenerics.cast(compOp)), joinOp);
-        this.fieldMap = (fieldMap == null) ? Collections.emptyMap() : fieldMap;
+        this.fieldMap = (fieldMap == null) ? Collections.emptyMap() : 
Collections.unmodifiableMap(new LinkedHashMap<>(fieldMap));
     }
 
     /**
diff --git 
a/framework/entity/src/main/java/org/apache/ofbiz/entity/util/EntityUtil.java 
b/framework/entity/src/main/java/org/apache/ofbiz/entity/util/EntityUtil.java
index f9a1749cc9..7a6d4b5a96 100644
--- 
a/framework/entity/src/main/java/org/apache/ofbiz/entity/util/EntityUtil.java
+++ 
b/framework/entity/src/main/java/org/apache/ofbiz/entity/util/EntityUtil.java
@@ -65,16 +65,15 @@ public final class EntityUtil {
 
     private EntityUtil() { }
 
-    @SafeVarargs
-    public static <V> Map<String, V> makeFields(V... args) {
-        Map<String, V> fields = new HashMap<>();
+    public static Map<String, Object> makeFields(Object... args) {
+        Map<String, Object> fields = new HashMap<>();
         if (args != null) {
             for (int i = 0; i < args.length;) {
-                V keyValue = args[i];
+                Object keyValue = args[i];
                 if (!(keyValue instanceof String)) throw new 
IllegalArgumentException("Key(" + i + "), with value(" + args[i] + ") is not a 
String.");
                 String key = (String) keyValue;
                 i++;
-                V value = args[i];
+                Object value = args[i];
                 if (value != null) {
                     if (!(value instanceof Comparable<?>)) {
                         throw new IllegalArgumentException("Value(" + i + "), 
with value(" + args[i] + ") does not implement Comparable.");

Reply via email to