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

Croway pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new c0a3b3875128 CAMEL-23914: handle @@CamelMagicValue@@ property 
conversion
c0a3b3875128 is described below

commit c0a3b38751280a9a5160bbb0bdb94a608799b559
Author: Marco Carletti <[email protected]>
AuthorDate: Mon Jul 6 10:29:14 2026 +0200

    CAMEL-23914: handle @@CamelMagicValue@@ property conversion
    
    Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
---
 .../PropertyConfigurerSupportMagicValueTest.java   | 123 +++++++++++++++++++++
 .../component/PropertyConfigurerSupport.java       |  56 +++++++---
 .../camel/main/download/ExportTypeConverter.java   |  61 +++-------
 .../dsl/yaml/validator/DummyTypeConverter.java     |  61 +++-------
 4 files changed, 195 insertions(+), 106 deletions(-)

diff --git 
a/core/camel-core/src/test/java/org/apache/camel/support/PropertyConfigurerSupportMagicValueTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/support/PropertyConfigurerSupportMagicValueTest.java
new file mode 100644
index 000000000000..e759a0141a2e
--- /dev/null
+++ 
b/core/camel-core/src/test/java/org/apache/camel/support/PropertyConfigurerSupportMagicValueTest.java
@@ -0,0 +1,123 @@
+/*
+ * 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.camel.support;
+
+import java.time.Duration;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.support.component.PropertyConfigurerSupport;
+import org.junit.jupiter.api.Test;
+
+import static 
org.apache.camel.support.component.PropertyConfigurerSupport.MAGIC_VALUE;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+/**
+ * Tests that PropertyConfigurerSupport.property() handles the 
@@CamelMagicValue@@ placeholder for all primitive/wrapper
+ * types, returning type-safe defaults instead of throwing 
NumberFormatException. This covers the camel-launcher export
+ * scenario where optional kamelet properties (e.g. salesforce-source replayId 
of type Long) are resolved to the magic
+ * placeholder.
+ */
+public class PropertyConfigurerSupportMagicValueTest extends 
ContextTestSupport {
+
+    @Test
+    public void testMagicValueToLong() {
+        Long result = PropertyConfigurerSupport.property(context, Long.class, 
MAGIC_VALUE);
+        assertNotNull(result);
+        assertEquals(1L, result);
+    }
+
+    @Test
+    public void testMagicValueToPrimitiveLong() {
+        long result = PropertyConfigurerSupport.property(context, long.class, 
MAGIC_VALUE);
+        assertEquals(1L, result);
+    }
+
+    @Test
+    public void testMagicValueToInteger() {
+        Integer result = PropertyConfigurerSupport.property(context, 
Integer.class, MAGIC_VALUE);
+        assertNotNull(result);
+        assertEquals(1, result);
+    }
+
+    @Test
+    public void testMagicValueToPrimitiveInt() {
+        int result = PropertyConfigurerSupport.property(context, int.class, 
MAGIC_VALUE);
+        assertEquals(1, result);
+    }
+
+    @Test
+    public void testMagicValueToDouble() {
+        Double result = PropertyConfigurerSupport.property(context, 
Double.class, MAGIC_VALUE);
+        assertNotNull(result);
+        assertEquals(1d, result);
+    }
+
+    @Test
+    public void testMagicValueToFloat() {
+        Float result = PropertyConfigurerSupport.property(context, 
Float.class, MAGIC_VALUE);
+        assertNotNull(result);
+        assertEquals(1f, result);
+    }
+
+    @Test
+    public void testMagicValueToShort() {
+        Short result = PropertyConfigurerSupport.property(context, 
Short.class, MAGIC_VALUE);
+        assertNotNull(result);
+        assertEquals((short) 1, result);
+    }
+
+    @Test
+    public void testMagicValueToByte() {
+        Byte result = PropertyConfigurerSupport.property(context, Byte.class, 
MAGIC_VALUE);
+        assertNotNull(result);
+        assertEquals((byte) 0, result);
+    }
+
+    @Test
+    public void testMagicValueToBoolean() {
+        Boolean result = PropertyConfigurerSupport.property(context, 
Boolean.class, MAGIC_VALUE);
+        assertNotNull(result);
+        assertEquals(Boolean.TRUE, result);
+    }
+
+    @Test
+    public void testMagicValueToPrimitiveBoolean() {
+        boolean result = PropertyConfigurerSupport.property(context, 
boolean.class, MAGIC_VALUE);
+        assertEquals(true, result);
+    }
+
+    @Test
+    public void testMagicValueToDuration() {
+        Duration result = PropertyConfigurerSupport.property(context, 
Duration.class, MAGIC_VALUE);
+        assertNotNull(result);
+        assertEquals(Duration.ofMillis(1), result);
+    }
+
+    @Test
+    public void testMagicValueToString() {
+        String result = PropertyConfigurerSupport.property(context, 
String.class, MAGIC_VALUE);
+        assertEquals(MAGIC_VALUE, result);
+    }
+
+    @Test
+    public void testRegularLongConversion() {
+        Long result = PropertyConfigurerSupport.property(context, Long.class, 
"42");
+        assertNotNull(result);
+        assertEquals(42L, result);
+    }
+}
diff --git 
a/core/camel-support/src/main/java/org/apache/camel/support/component/PropertyConfigurerSupport.java
 
b/core/camel-support/src/main/java/org/apache/camel/support/component/PropertyConfigurerSupport.java
index 80d6854da1a2..242fc9876288 100644
--- 
a/core/camel-support/src/main/java/org/apache/camel/support/component/PropertyConfigurerSupport.java
+++ 
b/core/camel-support/src/main/java/org/apache/camel/support/component/PropertyConfigurerSupport.java
@@ -16,6 +16,7 @@
  */
 package org.apache.camel.support.component;
 
+import java.time.Duration;
 import java.util.List;
 
 import org.apache.camel.CamelContext;
@@ -65,22 +66,25 @@ public abstract class PropertyConfigurerSupport {
                 }
                 value = obj;
             } else if (type == long.class || type == Long.class || type == 
int.class || type == Integer.class) {
-                Object obj = null;
-                // string to long/int then it may be a duration where we can 
convert the value to milli seconds
-                // it may be a time pattern, such as 5s for 5 seconds = 5000
-                try {
-                    long num = TimeUtils.toMilliSeconds(text);
-                    if (type == int.class || type == Integer.class) {
-                        // need to cast to int
-                        obj = (int) num;
-                    } else {
-                        obj = num;
+                // skip duration conversion for magic export placeholder
+                if (!MAGIC_VALUE.equals(text)) {
+                    Object obj = null;
+                    // string to long/int then it may be a duration where we 
can convert the value to milli seconds
+                    // it may be a time pattern, such as 5s for 5 seconds = 
5000
+                    try {
+                        long num = TimeUtils.toMilliSeconds(text);
+                        if (type == int.class || type == Integer.class) {
+                            // need to cast to int
+                            obj = (int) num;
+                        } else {
+                            obj = num;
+                        }
+                    } catch (IllegalArgumentException e) {
+                        // ignore
+                    }
+                    if (obj != null) {
+                        value = obj;
                     }
-                } catch (IllegalArgumentException e) {
-                    // ignore
-                }
-                if (obj != null) {
-                    value = obj;
                 }
             }
         }
@@ -95,10 +99,26 @@ public abstract class PropertyConfigurerSupport {
         }
 
         if (value != null) {
-            try {
-                if (MAGIC_VALUE.equals(value) && boolean.class == type) {
-                    value = "true";
+            if (MAGIC_VALUE.equals(value)) {
+                if (boolean.class == type || Boolean.class == type) {
+                    return (T) Boolean.TRUE;
+                } else if (int.class == type || Integer.class == type) {
+                    return (T) Integer.valueOf(1);
+                } else if (long.class == type || Long.class == type) {
+                    return (T) Long.valueOf(1L);
+                } else if (double.class == type || Double.class == type) {
+                    return (T) Double.valueOf(1d);
+                } else if (float.class == type || Float.class == type) {
+                    return (T) Float.valueOf(1f);
+                } else if (short.class == type || Short.class == type) {
+                    return (T) Short.valueOf((short) 1);
+                } else if (byte.class == type || Byte.class == type) {
+                    return (T) Byte.valueOf((byte) 0);
+                } else if (Duration.class == type) {
+                    return (T) Duration.ofMillis(1);
                 }
+            }
+            try {
                 return 
camelContext.getTypeConverter().mandatoryConvertTo(type, value);
             } catch (NoTypeConversionAvailableException e) {
                 throw RuntimeCamelException.wrapRuntimeCamelException(e);
diff --git 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/ExportTypeConverter.java
 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/ExportTypeConverter.java
index a449c0692c03..1ec5c51cff7e 100644
--- 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/ExportTypeConverter.java
+++ 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/ExportTypeConverter.java
@@ -16,13 +16,10 @@
  */
 package org.apache.camel.main.download;
 
-import java.time.Duration;
-
 import org.apache.camel.Exchange;
 import org.apache.camel.TypeConversionException;
 import org.apache.camel.converter.ObjectConverter;
 import org.apache.camel.support.TypeConverterSupport;
-import org.apache.camel.support.component.PropertyConfigurerSupport;
 import org.apache.camel.util.ObjectHelper;
 
 /**
@@ -33,47 +30,23 @@ public class ExportTypeConverter extends 
TypeConverterSupport {
 
     @Override
     public <T> T convertTo(Class<T> type, Exchange exchange, Object value) 
throws TypeConversionException {
-        if (PropertyConfigurerSupport.MAGIC_VALUE.equals(value)) {
-            // attempt to convert to the given type using different common 
inputs (boolean, numeric, string)
-            if (boolean.class == type || Boolean.class == type) {
-                return (T) Boolean.TRUE;
-            } else if (type == int.class || type == Integer.class) {
-                return (T) Integer.valueOf("1");
-            } else if (type == long.class || type == Long.class) {
-                return (T) Long.valueOf("1");
-            } else if (type == double.class || type == Double.class) {
-                return (T) Double.valueOf("1");
-            } else if (type == float.class || type == Float.class) {
-                return (T) Float.valueOf("1");
-            } else if (type == short.class || type == Short.class) {
-                return (T) Short.valueOf("1");
-            } else if (type == byte.class || type == Byte.class) {
-                return (T) Byte.valueOf("0");
-            } else if (type == Duration.class) {
-                return (T) Duration.ofMillis(1);
-            } else if (type == String.class) {
-                return (T) PropertyConfigurerSupport.MAGIC_VALUE;
-            }
-        } else {
-            String s = value.toString();
-            // regular values so convert normally
-            if (boolean.class == type || Boolean.class == type) {
-                return (T) ObjectHelper.toBoolean(s);
-            } else if (type == int.class || type == Integer.class) {
-                return (T) ObjectConverter.toInteger(s);
-            } else if (type == long.class || type == Long.class) {
-                return (T) ObjectConverter.toLong(s);
-            } else if (type == double.class || type == Double.class) {
-                return (T) ObjectConverter.toDouble(s);
-            } else if (type == float.class || type == Float.class) {
-                return (T) ObjectConverter.toFloat(s);
-            } else if (type == short.class || type == Short.class) {
-                return (T) ObjectConverter.toShort(s);
-            } else if (type == byte.class || type == Byte.class) {
-                return (T) ObjectConverter.toByte(s);
-            } else if (type == String.class) {
-                return (T) s;
-            }
+        String s = value.toString();
+        if (boolean.class == type || Boolean.class == type) {
+            return (T) ObjectHelper.toBoolean(s);
+        } else if (type == int.class || type == Integer.class) {
+            return (T) ObjectConverter.toInteger(s);
+        } else if (type == long.class || type == Long.class) {
+            return (T) ObjectConverter.toLong(s);
+        } else if (type == double.class || type == Double.class) {
+            return (T) ObjectConverter.toDouble(s);
+        } else if (type == float.class || type == Float.class) {
+            return (T) ObjectConverter.toFloat(s);
+        } else if (type == short.class || type == Short.class) {
+            return (T) ObjectConverter.toShort(s);
+        } else if (type == byte.class || type == Byte.class) {
+            return (T) ObjectConverter.toByte(s);
+        } else if (type == String.class) {
+            return (T) s;
         }
         return null;
     }
diff --git 
a/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/main/java/org/apache/camel/dsl/yaml/validator/DummyTypeConverter.java
 
b/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/main/java/org/apache/camel/dsl/yaml/validator/DummyTypeConverter.java
index ae91557b4e86..bd3187328b36 100644
--- 
a/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/main/java/org/apache/camel/dsl/yaml/validator/DummyTypeConverter.java
+++ 
b/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/main/java/org/apache/camel/dsl/yaml/validator/DummyTypeConverter.java
@@ -16,13 +16,10 @@
  */
 package org.apache.camel.dsl.yaml.validator;
 
-import java.time.Duration;
-
 import org.apache.camel.Exchange;
 import org.apache.camel.TypeConversionException;
 import org.apache.camel.converter.ObjectConverter;
 import org.apache.camel.support.TypeConverterSupport;
-import org.apache.camel.support.component.PropertyConfigurerSupport;
 import org.apache.camel.util.ObjectHelper;
 
 /**
@@ -33,47 +30,23 @@ public class DummyTypeConverter extends 
TypeConverterSupport {
 
     @Override
     public <T> T convertTo(Class<T> type, Exchange exchange, Object value) 
throws TypeConversionException {
-        if (PropertyConfigurerSupport.MAGIC_VALUE.equals(value)) {
-            // attempt to convert to the given type using different common 
inputs (boolean, numeric, string)
-            if (boolean.class == type || Boolean.class == type) {
-                return (T) Boolean.TRUE;
-            } else if (type == int.class || type == Integer.class) {
-                return (T) Integer.valueOf("1");
-            } else if (type == long.class || type == Long.class) {
-                return (T) Long.valueOf("1");
-            } else if (type == double.class || type == Double.class) {
-                return (T) Double.valueOf("1");
-            } else if (type == float.class || type == Float.class) {
-                return (T) Float.valueOf("1");
-            } else if (type == short.class || type == Short.class) {
-                return (T) Short.valueOf("1");
-            } else if (type == byte.class || type == Byte.class) {
-                return (T) Byte.valueOf("0");
-            } else if (type == Duration.class) {
-                return (T) Duration.ofMillis(1);
-            } else if (type == String.class) {
-                return (T) PropertyConfigurerSupport.MAGIC_VALUE;
-            }
-        } else {
-            String s = value.toString();
-            // regular values so convert normally
-            if (boolean.class == type || Boolean.class == type) {
-                return (T) ObjectHelper.toBoolean(s);
-            } else if (type == int.class || type == Integer.class) {
-                return (T) ObjectConverter.toInteger(s);
-            } else if (type == long.class || type == Long.class) {
-                return (T) ObjectConverter.toLong(s);
-            } else if (type == double.class || type == Double.class) {
-                return (T) ObjectConverter.toDouble(s);
-            } else if (type == float.class || type == Float.class) {
-                return (T) ObjectConverter.toFloat(s);
-            } else if (type == short.class || type == Short.class) {
-                return (T) ObjectConverter.toShort(s);
-            } else if (type == byte.class || type == Byte.class) {
-                return (T) ObjectConverter.toByte(s);
-            } else if (type == String.class) {
-                return (T) s;
-            }
+        String s = value.toString();
+        if (boolean.class == type || Boolean.class == type) {
+            return (T) ObjectHelper.toBoolean(s);
+        } else if (type == int.class || type == Integer.class) {
+            return (T) ObjectConverter.toInteger(s);
+        } else if (type == long.class || type == Long.class) {
+            return (T) ObjectConverter.toLong(s);
+        } else if (type == double.class || type == Double.class) {
+            return (T) ObjectConverter.toDouble(s);
+        } else if (type == float.class || type == Float.class) {
+            return (T) ObjectConverter.toFloat(s);
+        } else if (type == short.class || type == Short.class) {
+            return (T) ObjectConverter.toShort(s);
+        } else if (type == byte.class || type == Byte.class) {
+            return (T) ObjectConverter.toByte(s);
+        } else if (type == String.class) {
+            return (T) s;
         }
         return null;
     }

Reply via email to