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

albumenj pushed a commit to branch 3.3
in repository https://gitbox.apache.org/repos/asf/dubbo.git


The following commit(s) were added to refs/heads/3.3 by this push:
     new 31a21f07f6 Fix #14779 (#14813)
31a21f07f6 is described below

commit 31a21f07f645ee2bdd6ff6173d13744e0f123bbd
Author: Sean Yang <[email protected]>
AuthorDate: Tue Oct 22 16:27:11 2024 +0800

    Fix #14779 (#14813)
---
 .../org/apache/dubbo/config/AbstractConfig.java    | 71 ++++++++++++++++++++--
 1 file changed, 65 insertions(+), 6 deletions(-)

diff --git 
a/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractConfig.java 
b/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractConfig.java
index 2c481f7ca1..bc709a3541 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractConfig.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractConfig.java
@@ -37,6 +37,7 @@ import org.apache.dubbo.config.context.ConfigMode;
 import org.apache.dubbo.config.support.Nested;
 import org.apache.dubbo.config.support.Parameter;
 import org.apache.dubbo.rpc.model.ApplicationModel;
+import org.apache.dubbo.rpc.model.FrameworkModel;
 import org.apache.dubbo.rpc.model.ModuleModel;
 import org.apache.dubbo.rpc.model.ScopeModel;
 import org.apache.dubbo.rpc.model.ScopeModelUtil;
@@ -49,6 +50,7 @@ import java.beans.PropertyDescriptor;
 import java.beans.Transient;
 import java.io.Serializable;
 import java.lang.annotation.Annotation;
+import java.lang.reflect.Array;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
@@ -325,6 +327,23 @@ public abstract class AbstractConfig implements 
Serializable {
                 && method.getReturnType() == Map.class);
     }
 
+    private static boolean isPropertySetter(Method method) {
+        String name = method.getName();
+        if (name.startsWith("set")
+                && name.length() > 3
+                && Modifier.isPublic(method.getModifiers())
+                && method.getParameterCount() == 1) {
+            Class<?> paramType = method.getParameterTypes()[0];
+            if (paramType.isArray()) {
+                Class<?> componentType = paramType.getComponentType();
+                return componentType.isPrimitive() || 
isSimpleType(componentType);
+            } else {
+                return paramType.isPrimitive() || isSimpleType(paramType);
+            }
+        }
+        return false;
+    }
+
     private static boolean isParametersSetter(Method method) {
         return ("setParameters".equals(method.getName())
                 && Modifier.isPublic(method.getModifiers())
@@ -770,11 +789,13 @@ public abstract class AbstractConfig implements 
Serializable {
         // even if old one (this) contains non-null value, do override
         boolean overrideAll = configMode == ConfigMode.OVERRIDE_ALL;
 
+        FrameworkModel frameworkModel = 
ScopeModelUtil.getFrameworkModel(getScopeModel());
+
         // loop methods, get override value and set the new value back to 
method
         List<Method> methods =
                 MethodUtils.getMethods(obj.getClass(), method -> 
method.getDeclaringClass() != Object.class);
         for (Method method : methods) {
-            if (MethodUtils.isSetter(method)) {
+            if (isPropertySetter(method)) {
                 String propertyName = extractPropertyName(method.getName());
 
                 // if config mode is OVERRIDE_IF_ABSENT and property has set, 
skip
@@ -787,17 +808,55 @@ public abstract class AbstractConfig implements 
Serializable {
 
                 try {
                     String value = 
StringUtils.trim(configuration.getString(kebabPropertyName));
+
+                    Class<?> paramType = method.getParameterTypes()[0];
+                    if (paramType.isArray()) {
+                        if (isIgnoredAttribute(obj.getClass(), propertyName)) {
+                            continue;
+                        }
+
+                        Class<?> itemType = paramType.getComponentType();
+                        List<Object> items = new ArrayList<>();
+                        if (StringUtils.hasText(value)) {
+                            value = environment.resolvePlaceholders(value);
+                            if (StringUtils.hasText(value)) {
+                                for (String item : StringUtils.tokenize(value, 
',')) {
+                                    
items.add(ClassUtils.convertPrimitive(frameworkModel, itemType, item));
+                                }
+                            }
+                        } else {
+                            for (int i = 0; ; i++) {
+                                value = 
StringUtils.trim(configuration.getString(kebabPropertyName + '[' + i + ']'));
+                                if (value == null) {
+                                    break;
+                                }
+                                if (StringUtils.hasText(value)) {
+                                    value = 
environment.resolvePlaceholders(value);
+                                    if (StringUtils.hasText(value)) {
+                                        
items.add(ClassUtils.convertPrimitive(frameworkModel, itemType, value));
+                                    }
+                                }
+                            }
+                        }
+                        int len = items.size();
+                        if (len > 0) {
+                            Object array = Array.newInstance(itemType, len);
+                            for (int i = 0; i < len; i++) {
+                                Array.set(array, i, items.get(i));
+                            }
+                            method.invoke(obj, array);
+                        }
+                        continue;
+                    }
+
                     // isTypeMatch() is called to avoid duplicate and 
incorrect update, for example, we have two
                     // 'setGeneric' methods in ReferenceConfig.
                     if (StringUtils.hasText(value)
-                            && 
ClassUtils.isTypeMatch(method.getParameterTypes()[0], value)
+                            && ClassUtils.isTypeMatch(paramType, value)
                             && !isIgnoredAttribute(obj.getClass(), 
propertyName)) {
                         value = environment.resolvePlaceholders(value);
                         if (StringUtils.hasText(value)) {
-                            Object arg = ClassUtils.convertPrimitive(
-                                    
ScopeModelUtil.getFrameworkModel(getScopeModel()),
-                                    method.getParameterTypes()[0],
-                                    value);
+                            Object arg = 
ClassUtils.convertPrimitive(frameworkModel, paramType, value);
                             if (arg != null) {
                                 method.invoke(obj, arg);
                             }

Reply via email to