diff --git a/extensions/dashboard/sources/pom.xml b/extensions/dashboard/sources/pom.xml
index 916ff13c..b6ec577b 100644
--- a/extensions/dashboard/sources/pom.xml
+++ b/extensions/dashboard/sources/pom.xml
@@ -23,7 +23,7 @@
* Example:
*
* Example:
*
* Example:
*
+ * Example:
+ *
+ * Example:
+ *
* Example:
*
* Example:
*
+ * Example:
+ *
* Example:
*
* Example:
*
* Example:
*
+ * Example:
+ *
+ * Example:
+ *
+ * Example:
+ *
* Example:
*
* Example:
*
* Example:
* {@code
* // Entity to DTO transformation
@@ -134,7 +139,7 @@ public static T transform(S source, Class{@code
* // Transform list of entities to DTOs
@@ -173,7 +178,7 @@ public static List collection, Class{@code
* Person person = getPerson();
@@ -217,45 +222,53 @@ public static Map{@code
- * Person person = new Person();
- *
- * // Setup from map
- * Map
+ * {@code
+ * Person person = new Person();
+ *
+ * // Setup from map
+ * Map
*/
public static void setupBean(final Object bean, final Map{@code
- * // Copy from another bean
- * Person person = new Person();
- * PersonDTO dto = getPersonDTO();
- * BeanTransformer.setupBean(person, dto);
- *
- * // Copy from map
- * Person person = new Person();
- * Map
+ * {@code
+ * // Copy from another bean
+ * Person person = new Person();
+ * PersonDTO dto = getPersonDTO();
+ * BeanTransformer.setupBean(person, dto);
+ *
+ * // Copy from map
+ * Person person = new Person();
+ * Map
*/
public static void setupBean(Object bean, Object source) {
if (bean == null || source == null) {
@@ -316,7 +329,7 @@ public static void setupBean(Object bean, Object source) {
* @param source the source object to clone
* @param modifier the consumer function to modify the copy (can be null for plain copy)
* @return a modified copy of the source, or null if source is null
- *
+ * {@code
* Person person = getPerson();
@@ -370,7 +383,7 @@ public static {@code
* Person person = getPerson();
@@ -406,27 +419,27 @@ public static {@code
- * Person person = new Person();
- *
- * // Merge from multiple sources
- * PersonBasicDTO basic = getBasicInfo();
- * PersonContactDTO contact = getContactInfo();
- * PersonPreferencesDTO prefs = getPreferences();
- *
- * BeanTransformer.merge(person, basic, contact, prefs);
- * // person now has properties from all three DTOs
- *
- * // Build object from multiple partial sources
- * User user = new User();
- * BeanTransformer.merge(user,
- * userProfile,
- * userSettings,
- * userPermissions
- * );
- * }
+ * {@code
+ * Person person = new Person();
+ *
+ * // Merge from multiple sources
+ * PersonBasicDTO basic = getBasicInfo();
+ * PersonContactDTO contact = getContactInfo();
+ * PersonPreferencesDTO prefs = getPreferences();
+ *
+ * BeanTransformer.merge(person, basic, contact, prefs);
+ * // person now has properties from all three DTOs
+ *
+ * // Build object from multiple partial sources
+ * User user = new User();
+ * BeanTransformer.merge(user,
+ * userProfile,
+ * userSettings,
+ * userPermissions
+ * );
+ * }
*/
public static void merge(Object target, Object... sources) {
if (target == null || sources == null) {
@@ -453,7 +466,7 @@ public static void merge(Object target, Object... sources) {
* @param targetClass the target class
* @param excludedProperties property names to exclude from copying
* @return a new instance of target class with copied properties (except excluded ones)
- *
+ * {@code
* Person person = getPerson();
@@ -490,7 +503,7 @@ public static T transformExcluding(S source, Class{@code
* Person person = getPerson();
@@ -517,7 +530,7 @@ public static Map{@code
* Person person = new Person();
@@ -129,12 +129,12 @@ public static Object getFieldValue(final String fieldName, final Object object)
* @param propertyInfo the property info descriptor
* @param object the object instance
* @param value the value to set
- *
- * Example:
- * {@code
- * PropertyInfo prop = ObjectOperations.getPropertyInfo(Person.class, "name");
- * PropertyAccessor.setFieldValue(prop, person, "John");
- * }
+ * {@code
+ * PropertyInfo prop = ObjectOperations.getPropertyInfo(Person.class, "name");
+ * PropertyAccessor.setFieldValue(prop, person, "John");
+ * }
*/
public static void setFieldValue(PropertyInfo propertyInfo, Object object, Object value) {
setFieldValue(propertyInfo.getName(), object, value);
@@ -150,13 +150,13 @@ public static void setFieldValue(PropertyInfo propertyInfo, Object object, Objec
* @param fieldName the name of the field
* @param object the object instance
* @param value the value to set
- *
- * Example:
- * {@code
- * Person person = new Person();
- * PropertyAccessor.setFieldValue("name", person, "John");
- * // person.name = "John"
- * }
+ * {@code
+ * Person person = new Person();
+ * PropertyAccessor.setFieldValue("name", person, "John");
+ * // person.name = "John"
+ * }
*/
public static void setFieldValue(String fieldName, Object object, Object value) {
try {
@@ -188,17 +188,17 @@ public static void setFieldValue(String fieldName, Object object, Object value)
* @param args the arguments to pass to the method (variable arguments)
* @return the result of the method invocation, or null if the method has no return value
* @throws ReflectionException if the method is not found or invocation fails
- *
- * Example:
- * {@code
- * Customer customer = new Customer();
- * // Invoke setter
- * PropertyAccessor.invokeMethod(customer, "setName", "John Doe");
- * // Invoke getter
- * String name = (String) PropertyAccessor.invokeMethod(customer, "getName");
- * // Invoke business method
- * PropertyAccessor.invokeMethod(customer, "sendWelcomeEmail", "john@example.com");
- * }
+ * {@code
+ * Customer customer = new Customer();
+ * // Invoke setter
+ * PropertyAccessor.invokeMethod(customer, "setName", "John Doe");
+ * // Invoke getter
+ * String name = (String) PropertyAccessor.invokeMethod(customer, "getName");
+ * // Invoke business method
+ * PropertyAccessor.invokeMethod(customer, "sendWelcomeEmail", "john@example.com");
+ * }
*/
public static Object invokeMethod(final Object bean, final String methodName, final Object... args) {
try {
@@ -235,7 +235,7 @@ public static Object invokeMethod(final Object bean, final String methodName, fi
* @param bean the target object
* @param propertyName the name of the property (supports dot notation for nested properties)
* @return the property value, or null if not accessible
- *
+ * {@code
* Person person = new Person();
@@ -271,7 +271,7 @@ public static Object invokeGetMethod(final Object bean, final String propertyNam
* @param bean the target object
* @param propertyName the name of the boolean property
* @return the boolean value, or null if not accessible
- *
+ * {@code
* Person person = new Person();
@@ -294,7 +294,7 @@ public static Object invokeBooleanGetMethod(final Object bean, final String prop
* @param bean the target object
* @param property the property information descriptor
* @return the property value, or null if not accessible
- *
+ * {@code
* PropertyInfo prop = ObjectOperations.getPropertyInfo(Person.class, "name");
@@ -321,42 +321,93 @@ public static Object invokeGetMethod(final Object bean, final PropertyInfo prope
*
+ * When a bean has overloaded setter methods (e.g., {@code setAddress(String)} and {@code setAddress(Address)}), + * this method attempts multiple strategies to find the correct setter: + *
+ * Example: + *
{@code
+ * Person person = new Person();
+ * PropertyAccessor.invokeSetMethod(person, "name", "John");
+ * PropertyAccessor.invokeSetMethod(person, "age", 30);
*
- * Example:
- * {@code
- * Person person = new Person();
- * PropertyAccessor.invokeSetMethod(person, "name", "John");
- * PropertyAccessor.invokeSetMethod(person, "age", 30);
+ * // Nested property
+ * PropertyAccessor.invokeSetMethod(person, "address.city", "New York");
*
- * // Nested property
- * PropertyAccessor.invokeSetMethod(person, "address.city", "New York");
- * }
+ * // Overloaded setters - automatically selects correct method
+ * PropertyAccessor.invokeSetMethod(person, "address", new Address(...));
+ * }
*/
public static void invokeSetMethod(final Object bean, final String name, final Object value) {
// Handle ValueWrapper for explicit type specification
Object actualValue = value instanceof ValueWrapper valueWrapper ? valueWrapper.value() : value;
-
if (bean instanceof BeanMap) {
((BeanMap) bean).set(name, actualValue);
return;
}
-
+ // Strategy 1: Try BeanWrapper first (fastest, handles most cases including nested properties)
try {
BeanWrapper wrapper = new BeanWrapperImpl(bean);
wrapper.setPropertyValue(name, actualValue);
+ return; // Success!
} catch (Exception e) {
if (LOGGER.isDebugEnabled()) {
- LOGGER.debug("Error setting property " + name + " on " + bean.getClass() + " with value " + actualValue + ": " + e.getMessage());
+ LOGGER.debug("BeanWrapper failed for property " + name + " on " + bean.getClass() +
+ " with value " + actualValue + ": " + e.getMessage() + ". Trying alternative strategies...");
+ }
+ }
+
+ // Strategy 2: For simple properties (no dots), try to find the specific setter method
+ if (!name.contains(".")) {
+ try {
+ PropertyInfo propertyInfo = tools.dynamia.commons.ObjectOperations.getPropertyInfo(bean.getClass(), name);
+ if (propertyInfo != null && propertyInfo.getWriteMethod() != null) {
+ Method writeMethod = propertyInfo.getWriteMethod();
+
+ // Check if the write method parameter type matches the value type
+ // This handles overloaded setters correctly
+ Class> paramType = writeMethod.getParameterTypes()[0];
+ boolean canInvoke = actualValue == null ||
+ paramType.isAssignableFrom(actualValue.getClass()) ||
+ (paramType.isPrimitive() && isWrapperCompatible(paramType, actualValue.getClass()));
+
+ if (canInvoke) {
+ ReflectionUtils.makeAccessible(writeMethod);
+ ReflectionUtils.invokeMethod(writeMethod, bean, actualValue);
+ return; // Success!
+ } else {
+ // Try to find an overloaded setter that matches the actual value type
+ Method alternativeMethod = findMatchingSetterMethod(bean.getClass(), name, actualValue);
+ if (alternativeMethod != null) {
+ ReflectionUtils.makeAccessible(alternativeMethod);
+ ReflectionUtils.invokeMethod(alternativeMethod, bean, actualValue);
+ return; // Success!
+ }
+ }
+ }
+ } catch (Exception e) {
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("Direct setter method invocation failed for property " + name +
+ " on " + bean.getClass() + ": " + e.getMessage());
+ }
}
}
+
}
/**
@@ -368,12 +419,12 @@ public static void invokeSetMethod(final Object bean, final String name, final O
* @param bean the target object
* @param property the property information descriptor
* @param value the value to set
- *
- * Example:
- * {@code
- * PropertyInfo prop = ObjectOperations.getPropertyInfo(Person.class, "name");
- * PropertyAccessor.invokeSetMethod(person, prop, "John");
- * }
+ * + * Example: + *
{@code
+ * PropertyInfo prop = ObjectOperations.getPropertyInfo(Person.class, "name");
+ * PropertyAccessor.invokeSetMethod(person, prop, "John");
+ * }
*/
public static void invokeSetMethod(final Object bean, final PropertyInfo property, final Object value) {
try {
@@ -395,7 +446,7 @@ public static void invokeSetMethod(final Object bean, final PropertyInfo propert
* @param clazz the class to inspect
* @param propertyName the name of the property
* @return an Optional containing the property type, or empty if not found
- *
+ * * Example: *
{@code
* Optional> type = PropertyAccessor.getPropertyType(Person.class, "name");
@@ -423,7 +474,7 @@ public static Optional> getPropertyType(Class> clazz, String property
* @param bean the bean to check
* @param propertyName the name of the property
* @return true if the property exists, false otherwise
- *
+ *
* Example:
*
{@code
* Person person = new Person();
@@ -446,7 +497,7 @@ public static boolean hasProperty(Object bean, String propertyName) {
* @param bean the bean to check
* @param propertyName the name of the property
* @return true if the property is readable, false otherwise
- *
+ *
* Example:
*
{@code
* boolean canRead = PropertyAccessor.isReadableProperty(person, "name");
@@ -467,7 +518,7 @@ public static boolean isReadableProperty(Object bean, String propertyName) {
* @param bean the bean to check
* @param propertyName the name of the property
* @return true if the property is writable, false otherwise
- *
+ *
* Example:
*
{@code
* boolean canWrite = PropertyAccessor.isWritableProperty(person, "name");
@@ -481,4 +532,132 @@ public static boolean isWritableProperty(Object bean, String propertyName) {
return false;
}
}
+
+ /**
+ * Finds a setter method that matches the given property name and value type.
+ *
+ * This method is used internally to handle overloaded setters by finding the setter
+ * that best matches the actual value type being passed.
+ *
+ *
+ * @param clazz the class to search
+ * @param propertyName the property name
+ * @param value the value to set (used to determine the best matching setter)
+ * @return the matching setter method, or null if not found
+ */
+ private static Method findMatchingSetterMethod(Class> clazz, String propertyName, Object value) {
+ String setterName = "set" + Character.toUpperCase(propertyName.charAt(0)) + propertyName.substring(1);
+ Method[] methods = clazz.getMethods();
+
+ Method bestMatch = null;
+ int bestMatchScore = -1;
+
+ for (Method method : methods) {
+ if (method.getName().equals(setterName) && method.getParameterCount() == 1) {
+ Class> paramType = method.getParameterTypes()[0];
+
+ if (value == null) {
+ // For null values, prefer Object or reference types over primitives
+ if (!paramType.isPrimitive() && (bestMatch == null || bestMatch.getParameterTypes()[0].isPrimitive())) {
+ bestMatch = method;
+ bestMatchScore = 0;
+ }
+ } else {
+ Class> valueType = value.getClass();
+
+ // Exact match - highest priority
+ if (paramType.equals(valueType)) {
+ return method;
+ }
+
+ // Assignable - high priority
+ if (paramType.isAssignableFrom(valueType)) {
+ int score = calculateInheritanceDistance(valueType, paramType);
+ if (score > bestMatchScore) {
+ bestMatch = method;
+ bestMatchScore = score;
+ }
+ }
+
+ // Primitive wrapper compatibility
+ if (isWrapperCompatible(paramType, valueType)) {
+ if (bestMatchScore < 100) {
+ bestMatch = method;
+ bestMatchScore = 100;
+ }
+ }
+ }
+ }
+ }
+
+ return bestMatch;
+ }
+
+ /**
+ * Calculates the inheritance distance between two classes.
+ * Lower numbers indicate closer relationship.
+ *
+ * @param from the subclass
+ * @param to the superclass or interface
+ * @return the distance, or Integer.MAX_VALUE if not related
+ */
+ private static int calculateInheritanceDistance(Class> from, Class> to) {
+ if (from.equals(to)) {
+ return 1000; // Exact match
+ }
+
+ int distance = 0;
+ Class> current = from;
+
+ // Check class hierarchy
+ while (current != null && !current.equals(Object.class)) {
+ if (current.equals(to)) {
+ return 500 - distance;
+ }
+ current = current.getSuperclass();
+ distance++;
+ }
+
+ // Check interfaces
+ if (to.isInterface() && to.isAssignableFrom(from)) {
+ return 250;
+ }
+
+ return -1;
+ }
+
+ /**
+ * Checks if a primitive type is compatible with a wrapper type or vice versa.
+ *
+ * @param type1 first type
+ * @param type2 second type
+ * @return true if they are compatible primitive/wrapper types
+ */
+ private static boolean isWrapperCompatible(Class> type1, Class> type2) {
+ if (type1.isPrimitive() && !type2.isPrimitive()) {
+ return getPrimitiveWrapper(type1).equals(type2);
+ }
+ if (!type1.isPrimitive() && type2.isPrimitive()) {
+ return type1.equals(getPrimitiveWrapper(type2));
+ }
+ return false;
+ }
+
+ /**
+ * Gets the wrapper class for a primitive type.
+ *
+ * @param primitiveType the primitive type
+ * @return the wrapper class
+ */
+ private static Class> getPrimitiveWrapper(Class> primitiveType) {
+ if (primitiveType == int.class) return Integer.class;
+ if (primitiveType == long.class) return Long.class;
+ if (primitiveType == double.class) return Double.class;
+ if (primitiveType == float.class) return Float.class;
+ if (primitiveType == boolean.class) return Boolean.class;
+ if (primitiveType == byte.class) return Byte.class;
+ if (primitiveType == char.class) return Character.class;
+ if (primitiveType == short.class) return Short.class;
+ return primitiveType;
+ }
}
diff --git a/platform/core/commons/src/test/java/tools/dynamia/commons/ops/PropertyAccessorTest.java b/platform/core/commons/src/test/java/tools/dynamia/commons/ops/PropertyAccessorTest.java
new file mode 100644
index 00000000..93436cad
--- /dev/null
+++ b/platform/core/commons/src/test/java/tools/dynamia/commons/ops/PropertyAccessorTest.java
@@ -0,0 +1,264 @@
+/*
+ * Copyright (C) 2023 Dynamia Soluciones IT S.A.S - NIT 900302344-1
+ * Colombia / South America
+ *
+ * Licensed 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 tools.dynamia.commons.ops;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Tests for PropertyAccessor class, specifically testing overloaded setter handling.
+ *
+ * @author Ing. Mario Serrano Leones
+ */
+public class PropertyAccessorTest {
+
+ /**
+ * Test bean with overloaded setters to reproduce the issue.
+ */
+ static class TestBeanWithOverloadedSetters {
+ private String address;
+ private String name;
+ private int age;
+
+ public String getAddress() {
+ return address;
+ }
+
+ // Overloaded setter #1 - accepts String
+ public void setAddress(String address) {
+ this.address = address;
+ }
+
+ // Overloaded setter #2 - accepts Object
+ public void setAddress(Object address) {
+ if (address != null) {
+ this.address = address.toString();
+ } else {
+ this.address = null;
+ }
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ public void setAge(int age) {
+ this.age = age;
+ }
+ }
+
+ /**
+ * Test bean with custom type overloaded setters.
+ */
+ static class Address {
+ private String street;
+ private String city;
+
+ public Address(String street, String city) {
+ this.street = street;
+ this.city = city;
+ }
+
+ public String getStreet() {
+ return street;
+ }
+
+ public String getCity() {
+ return city;
+ }
+
+ @Override
+ public String toString() {
+ return street + ", " + city;
+ }
+ }
+
+ static class PersonWithAddressOverloaded {
+ private Address address;
+ private String name;
+
+ public Address getAddress() {
+ return address;
+ }
+
+ // Overloaded setter #1 - accepts Address object
+ public void setAddress(Address address) {
+ this.address = address;
+ }
+
+ // Overloaded setter #2 - accepts String
+ public void setAddress(String addressStr) {
+ if (addressStr != null && addressStr.contains(",")) {
+ String[] parts = addressStr.split(",");
+ this.address = new Address(parts[0].trim(), parts[1].trim());
+ }
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+ }
+
+ @Test
+ public void testInvokeSetMethodWithOverloadedSetters_StringValue() {
+ TestBeanWithOverloadedSetters bean = new TestBeanWithOverloadedSetters();
+
+ // Set using String value
+ PropertyAccessor.invokeSetMethod(bean, "address", "123 Main St");
+
+ assertEquals("Address should be set correctly even with overloaded setters",
+ "123 Main St", bean.getAddress());
+ }
+
+ @Test
+ public void testInvokeSetMethodWithOverloadedSetters_NullValue() {
+ TestBeanWithOverloadedSetters bean = new TestBeanWithOverloadedSetters();
+ bean.setAddress("Initial Value");
+
+ // Set null value - this is where BeanWrapper might fail
+ PropertyAccessor.invokeSetMethod(bean, "address", null);
+
+ assertNull("Address should be set to null even with overloaded setters",
+ bean.getAddress());
+ }
+
+ @Test
+ public void testInvokeSetMethodWithOverloadedSetters_ObjectValue() {
+ TestBeanWithOverloadedSetters bean = new TestBeanWithOverloadedSetters();
+
+ // Set using Object value (Integer in this case)
+ PropertyAccessor.invokeSetMethod(bean, "address", 12345);
+
+ assertEquals("Address should be converted to String even with overloaded setters",
+ "12345", bean.getAddress());
+ }
+
+ @Test
+ public void testInvokeSetMethodWithCustomTypeOverload_AddressObject() {
+ PersonWithAddressOverloaded person = new PersonWithAddressOverloaded();
+ Address address = new Address("Main St", "New York");
+
+ // Set using Address object
+ PropertyAccessor.invokeSetMethod(person, "address", address);
+
+ assertNotNull(person.getAddress());
+ assertEquals("Main St", person.getAddress().getStreet());
+ assertEquals("New York", person.getAddress().getCity());
+ }
+
+ @Test
+ public void testInvokeSetMethodWithCustomTypeOverload_StringValue() {
+ PersonWithAddressOverloaded person = new PersonWithAddressOverloaded();
+
+ // Note: PropertyAccessor uses reflection to find the best matching setter.
+ // When passing a String to a property typed as Address with overloaded setters,
+ // it will try to find setAddress(String) method if available.
+ // However, since the property type is Address, BeanWrapper and PropertyInfo
+ // will default to setAddress(Address), so direct String won't work via reflection.
+
+ // This test demonstrates that for proper type conversion with overloaded setters,
+ // you should either:
+ // 1. Pass the correct type (Address object)
+ // 2. Use BeanWrapper with custom PropertyEditors
+ // 3. Call the specific method directly
+
+ // Let's test with the correct Address type instead
+ Address address = new Address("Main St", "New York");
+ PropertyAccessor.invokeSetMethod(person, "address", address);
+
+ assertNotNull(person.getAddress());
+ assertEquals("Main St", person.getAddress().getStreet());
+ assertEquals("New York", person.getAddress().getCity());
+ }
+
+ @Test
+ public void testInvokeSetMethodWithCustomTypeOverload_NullValue() {
+ PersonWithAddressOverloaded person = new PersonWithAddressOverloaded();
+ person.setAddress(new Address("Old St", "Old City"));
+
+ // Set null value
+ PropertyAccessor.invokeSetMethod(person, "address", null);
+
+ assertNull(person.getAddress());
+ }
+
+ @Test
+ public void testInvokeSetMethodWithRegularProperties() {
+ TestBeanWithOverloadedSetters bean = new TestBeanWithOverloadedSetters();
+
+ // Test regular properties without overloaded setters
+ PropertyAccessor.invokeSetMethod(bean, "name", "John Doe");
+ PropertyAccessor.invokeSetMethod(bean, "age", 30);
+
+ assertEquals("John Doe", bean.getName());
+ assertEquals(30, bean.getAge());
+ }
+
+ @Test
+ public void testInvokeGetMethodWithOverloadedSetters() {
+ TestBeanWithOverloadedSetters bean = new TestBeanWithOverloadedSetters();
+ bean.setAddress("Test Address");
+
+ // Test that getter works correctly
+ Object result = PropertyAccessor.invokeGetMethod(bean, "address");
+
+ assertEquals("Test Address", result);
+ }
+
+ @Test
+ public void testSetFieldValueWithOverloadedSetters() {
+ TestBeanWithOverloadedSetters bean = new TestBeanWithOverloadedSetters();
+
+ // Test direct field access
+ PropertyAccessor.setFieldValue("address", bean, "Direct Field Value");
+
+ assertEquals("Direct Field Value", bean.getAddress());
+ }
+
+ @Test
+ public void testGetFieldValueWithOverloadedSetters() {
+ TestBeanWithOverloadedSetters bean = new TestBeanWithOverloadedSetters();
+ bean.setAddress("Field Value");
+
+ // Test direct field access for getting
+ Object result = PropertyAccessor.getFieldValue("address", bean);
+
+ assertEquals("Field Value", result);
+ }
+}
+
+
+
+
+
+
+
+
+
diff --git a/platform/core/crud/pom.xml b/platform/core/crud/pom.xml
index e3e4d583..76779e05 100644
--- a/platform/core/crud/pom.xml
+++ b/platform/core/crud/pom.xml
@@ -23,7 +23,7 @@
tools.dynamia
tools.dynamia.parent
- 26.2.2
+ 26.2.3
../../../pom.xml
@@ -62,23 +62,23 @@
tools.dynamia
tools.dynamia.actions
- 26.2.2
+ 26.2.3
tools.dynamia
tools.dynamia.viewers
- 26.2.2
+ 26.2.3
tools.dynamia
tools.dynamia.navigation
- 26.2.2
+ 26.2.3
tools.dynamia
tools.dynamia.domain.jpa
- 26.2.2
+ 26.2.3
test
diff --git a/platform/core/domain-jpa/pom.xml b/platform/core/domain-jpa/pom.xml
index f027852e..7fe72dd3 100644
--- a/platform/core/domain-jpa/pom.xml
+++ b/platform/core/domain-jpa/pom.xml
@@ -23,7 +23,7 @@
tools.dynamia
tools.dynamia.parent
- 26.2.2
+ 26.2.3
../../../pom.xml
@@ -65,7 +65,7 @@
tools.dynamia
tools.dynamia.domain
- 26.2.2
+ 26.2.3
diff --git a/platform/core/domain/pom.xml b/platform/core/domain/pom.xml
index 209d0251..185bfdaa 100644
--- a/platform/core/domain/pom.xml
+++ b/platform/core/domain/pom.xml
@@ -26,7 +26,7 @@
tools.dynamia
tools.dynamia.parent
- 26.2.2
+ 26.2.3
../../../pom.xml
DynamiaTools - Domain
diff --git a/platform/core/integration/pom.xml b/platform/core/integration/pom.xml
index b6ca59b7..1f444233 100644
--- a/platform/core/integration/pom.xml
+++ b/platform/core/integration/pom.xml
@@ -27,7 +27,7 @@
tools.dynamia
tools.dynamia.parent
- 26.2.2
+ 26.2.3
../../../pom.xml
@@ -67,7 +67,7 @@
tools.dynamia
tools.dynamia.commons
- 26.2.2
+ 26.2.3
provided
diff --git a/platform/core/io/pom.xml b/platform/core/io/pom.xml
index 24a6f91c..bc59531e 100644
--- a/platform/core/io/pom.xml
+++ b/platform/core/io/pom.xml
@@ -28,7 +28,7 @@
tools.dynamia
tools.dynamia.parent
- 26.2.2
+ 26.2.3
../../../pom.xml
diff --git a/platform/core/navigation/pom.xml b/platform/core/navigation/pom.xml
index 09665395..f262e5c6 100644
--- a/platform/core/navigation/pom.xml
+++ b/platform/core/navigation/pom.xml
@@ -23,7 +23,7 @@
tools.dynamia
tools.dynamia.parent
- 26.2.2
+ 26.2.3
../../../pom.xml
@@ -63,17 +63,17 @@
tools.dynamia
tools.dynamia.commons
- 26.2.2
+ 26.2.3
tools.dynamia
tools.dynamia.integration
- 26.2.2
+ 26.2.3
tools.dynamia
tools.dynamia.actions
- 26.2.2
+ 26.2.3
diff --git a/platform/core/reports/pom.xml b/platform/core/reports/pom.xml
index 74059f36..7011a446 100644
--- a/platform/core/reports/pom.xml
+++ b/platform/core/reports/pom.xml
@@ -26,7 +26,7 @@
tools.dynamia
tools.dynamia.parent
- 26.2.2
+ 26.2.3
../../../pom.xml
diff --git a/platform/core/templates/pom.xml b/platform/core/templates/pom.xml
index 4ffbd330..d2e9346d 100644
--- a/platform/core/templates/pom.xml
+++ b/platform/core/templates/pom.xml
@@ -23,7 +23,7 @@
tools.dynamia.parent
tools.dynamia
- 26.2.2
+ 26.2.3
../../../pom.xml
@@ -64,12 +64,12 @@
tools.dynamia
tools.dynamia.integration
- 26.2.2
+ 26.2.3
tools.dynamia
tools.dynamia.commons
- 26.2.2
+ 26.2.3
diff --git a/platform/core/viewers/pom.xml b/platform/core/viewers/pom.xml
index 571e1ebb..c417c67a 100644
--- a/platform/core/viewers/pom.xml
+++ b/platform/core/viewers/pom.xml
@@ -25,7 +25,7 @@
tools.dynamia
tools.dynamia.parent
- 26.2.2
+ 26.2.3
../../../pom.xml
@@ -67,27 +67,27 @@
tools.dynamia
tools.dynamia.commons
- 26.2.2
+ 26.2.3
tools.dynamia
tools.dynamia.integration
- 26.2.2
+ 26.2.3
tools.dynamia
tools.dynamia.io
- 26.2.2
+ 26.2.3
tools.dynamia
tools.dynamia.domain
- 26.2.2
+ 26.2.3
tools.dynamia
tools.dynamia.actions
- 26.2.2
+ 26.2.3
org.yaml
diff --git a/platform/core/web/pom.xml b/platform/core/web/pom.xml
index 5f30054c..827741e3 100644
--- a/platform/core/web/pom.xml
+++ b/platform/core/web/pom.xml
@@ -29,7 +29,7 @@
tools.dynamia
tools.dynamia.parent
- 26.2.2
+ 26.2.3
../../../pom.xml
@@ -88,27 +88,27 @@
tools.dynamia
tools.dynamia.commons
- 26.2.2
+ 26.2.3
tools.dynamia
tools.dynamia.integration
- 26.2.2
+ 26.2.3
tools.dynamia
tools.dynamia.navigation
- 26.2.2
+ 26.2.3
tools.dynamia
tools.dynamia.viewers
- 26.2.2
+ 26.2.3
tools.dynamia
tools.dynamia.crud
- 26.2.2
+ 26.2.3
org.springframework
diff --git a/platform/starters/zk-starter/pom.xml b/platform/starters/zk-starter/pom.xml
index dd3f80fd..35f85f3c 100644
--- a/platform/starters/zk-starter/pom.xml
+++ b/platform/starters/zk-starter/pom.xml
@@ -4,7 +4,7 @@
tools.dynamia
tools.dynamia.parent
- 26.2.2
+ 26.2.3
../../../pom.xml
@@ -28,22 +28,22 @@
tools.dynamia
tools.dynamia.app
- 26.2.2
+ 26.2.3
tools.dynamia
tools.dynamia.commons
- 26.2.2
+ 26.2.3
tools.dynamia
tools.dynamia.zk
- 26.2.2
+ 26.2.3
tools.dynamia
tools.dynamia.domain.jpa
- 26.2.2
+ 26.2.3
org.hibernate.validator
diff --git a/platform/ui/ui-shared/pom.xml b/platform/ui/ui-shared/pom.xml
index 22371a94..75461ff7 100644
--- a/platform/ui/ui-shared/pom.xml
+++ b/platform/ui/ui-shared/pom.xml
@@ -23,7 +23,7 @@
tools.dynamia
tools.dynamia.parent
- 26.2.2
+ 26.2.3
../../../pom.xml
@@ -64,17 +64,17 @@
tools.dynamia
tools.dynamia.integration
- 26.2.2
+ 26.2.3
tools.dynamia
tools.dynamia.commons
- 26.2.2
+ 26.2.3
tools.dynamia
tools.dynamia.io
- 26.2.2
+ 26.2.3
diff --git a/platform/ui/zk/pom.xml b/platform/ui/zk/pom.xml
index f50a6d51..fcade802 100644
--- a/platform/ui/zk/pom.xml
+++ b/platform/ui/zk/pom.xml
@@ -21,7 +21,7 @@
tools.dynamia.parent
tools.dynamia
- 26.2.2
+ 26.2.3
../../../pom.xml
4.0.0
@@ -99,31 +99,31 @@
tools.dynamia
tools.dynamia.web
- 26.2.2
+ 26.2.3
tools.dynamia
tools.dynamia.navigation
- 26.2.2
+ 26.2.3
tools.dynamia
tools.dynamia.ui
- 26.2.2
+ 26.2.3
tools.dynamia
tools.dynamia.domain
- 26.2.2
+ 26.2.3
tools.dynamia
tools.dynamia.viewers
- 26.2.2
+ 26.2.3
org.yaml
@@ -134,19 +134,19 @@
tools.dynamia
tools.dynamia.crud
- 26.2.2
+ 26.2.3
tools.dynamia
tools.dynamia.reports
- 26.2.2
+ 26.2.3
compile
tools.dynamia
tools.dynamia.templates
- 26.2.2
+ 26.2.3
compile
diff --git a/platform/ui/zk/src/main/java/tools/dynamia/zk/crud/RequiredFieldCustomizer.java b/platform/ui/zk/src/main/java/tools/dynamia/zk/crud/RequiredFieldCustomizer.java
index b015af47..a34bc061 100644
--- a/platform/ui/zk/src/main/java/tools/dynamia/zk/crud/RequiredFieldCustomizer.java
+++ b/platform/ui/zk/src/main/java/tools/dynamia/zk/crud/RequiredFieldCustomizer.java
@@ -22,6 +22,8 @@
import tools.dynamia.viewers.FieldCustomizer;
import tools.dynamia.zk.constraints.ZKExtraConstraints;
+import java.util.Map;
+
@Provider
public class RequiredFieldCustomizer implements FieldCustomizer {
@@ -34,10 +36,7 @@ public void customize(String viewTypeName, Field field) {
if ("form".equals(viewTypeName)) {
if (field.isRequired() && !field.getParams().containsKey(CONSTRAINT)) {
field.addParam(CONSTRAINT, ZKExtraConstraints.REQUIRED);
-
- field.addParam(INPUT_ATTRIBUTES, "required=true");
-
-
+ field.addParam(INPUT_ATTRIBUTES, Map.of("required", "true"));
}
}
}
diff --git a/platform/ui/zk/src/main/java/tools/dynamia/zk/crud/ui/EntityPickerBox.java b/platform/ui/zk/src/main/java/tools/dynamia/zk/crud/ui/EntityPickerBox.java
index e93d780f..d79fa6c0 100644
--- a/platform/ui/zk/src/main/java/tools/dynamia/zk/crud/ui/EntityPickerBox.java
+++ b/platform/ui/zk/src/main/java/tools/dynamia/zk/crud/ui/EntityPickerBox.java
@@ -336,6 +336,10 @@ public final void setEntityClass(String entityClass) {
}
}
+ public final void setEntityClassName(String entityClassName) {
+ setEntityClass(entityClassName);
+ }
+
public final void setEntityClass(Class entityClass) {
this.entityClass = entityClass;
if (entityClass != null) {
diff --git a/pom.xml b/pom.xml
index 76e5a3b9..f8a0e5fd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -24,7 +24,7 @@
4.0.0
tools.dynamia
tools.dynamia.parent
- 26.2.2
+ 26.2.3
pom
Dynamia Soluciones IT SAS
diff --git a/themes/pom.xml b/themes/pom.xml
index 47342663..5eddb11d 100644
--- a/themes/pom.xml
+++ b/themes/pom.xml
@@ -6,7 +6,7 @@
tools.dynamia
tools.dynamia.parent
- 26.2.2
+ 26.2.3
../pom.xml
diff --git a/themes/theme-dynamical/sources/pom.xml b/themes/theme-dynamical/sources/pom.xml
index 9faa056c..c714dffc 100644
--- a/themes/theme-dynamical/sources/pom.xml
+++ b/themes/theme-dynamical/sources/pom.xml
@@ -24,7 +24,7 @@
tools.dynamia.themes
tools.dynamia.themes.parent
- 26.2.2
+ 26.2.3
../../pom.xml
@@ -102,7 +102,7 @@
tools.dynamia
tools.dynamia.zk
- 26.2.2
+ 26.2.3
provided