You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2023/12/06 12:42:33 UTC
(camel) branch main updated: CAMEL-20197: camel-catalog - Allow to provide options for validateLanguage
This is an automated email from the ASF dual-hosted git repository.
davsclaus 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 df19aec0091 CAMEL-20197: camel-catalog - Allow to provide options for validateLanguage
df19aec0091 is described below
commit df19aec009164ba821c60518651dfc5eda3aee7d
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Wed Dec 6 13:42:15 2023 +0100
CAMEL-20197: camel-catalog - Allow to provide options for validateLanguage
---
.../org/apache/camel/catalog/CamelCatalog.java | 6 +++
.../org/apache/camel/catalog/CamelCatalogTest.java | 5 ++
.../camel/catalog/impl/AbstractCamelCatalog.java | 24 ++++++++++
.../org/apache/camel/util/ReflectionHelper.java | 56 +++++++++++++++++++++-
4 files changed, 90 insertions(+), 1 deletion(-)
diff --git a/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/CamelCatalog.java b/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/CamelCatalog.java
index 673ee0fdc89..3b5fefe5ac3 100644
--- a/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/CamelCatalog.java
+++ b/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/CamelCatalog.java
@@ -405,6 +405,9 @@ public interface CamelCatalog {
/**
* Parses and validates the language as a predicate
* <p/>
+ * It is possible to specify language options as query parameters in the language parameter, such as
+ * jsonpath?unpackArray=true&allowEasyPredicate=false
+ *
* <b>Important:</b> This requires having <tt>camel-core</tt> and the language dependencies on the classpath
*
* @param classLoader a custom classloader to use for loading the language from the classpath, or <tt>null</tt> for
@@ -418,6 +421,9 @@ public interface CamelCatalog {
/**
* Parses and validates the language as an expression
* <p/>
+ * It is possible to specify language options as query parameters in the language parameter, such as
+ * jsonpath?unpackArray=true&allowEasyPredicate=false
+ *
* <b>Important:</b> This requires having <tt>camel-core</tt> and the language dependencies on the classpath
*
* @param classLoader a custom classloader to use for loading the language from the classpath, or <tt>null</tt> for
diff --git a/catalog/camel-catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java b/catalog/camel-catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java
index 9ac367295f4..f4725ca3afc 100644
--- a/catalog/camel-catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java
+++ b/catalog/camel-catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java
@@ -1089,6 +1089,11 @@ public class CamelCatalogTest {
assertFalse(result.isSuccess());
assertEquals("$.store.book[?(@.price ^^^ 10)]", result.getText());
assertEquals("Expected character: )", result.getError());
+
+ // just to call via a configuration option
+ result = catalog.validateLanguageExpression(null, "jsonpath?unpackArray=true", "$.store.book[?(@.price < 10)]");
+ assertTrue(result.isSuccess());
+ assertEquals("$.store.book[?(@.price < 10)]", result.getText());
}
@Test
diff --git a/core/camel-core-catalog/src/main/java/org/apache/camel/catalog/impl/AbstractCamelCatalog.java b/core/camel-core-catalog/src/main/java/org/apache/camel/catalog/impl/AbstractCamelCatalog.java
index e9a316cfc81..5f4584431a7 100644
--- a/core/camel-core-catalog/src/main/java/org/apache/camel/catalog/impl/AbstractCamelCatalog.java
+++ b/core/camel-core-catalog/src/main/java/org/apache/camel/catalog/impl/AbstractCamelCatalog.java
@@ -54,6 +54,7 @@ import org.apache.camel.tooling.model.LanguageModel;
import org.apache.camel.tooling.model.MainModel;
import org.apache.camel.tooling.model.OtherModel;
import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.ReflectionHelper;
import org.apache.camel.util.StringHelper;
import org.apache.camel.util.URISupport;
@@ -1400,6 +1401,18 @@ public abstract class AbstractCamelCatalog {
LanguageValidationResult answer = new LanguageValidationResult(text);
+ Map<String, Object> options = null;
+ if (language.contains("?")) {
+ String query = URISupport.extractQuery(language);
+ language = StringHelper.before(language, "?");
+ try {
+ options = URISupport.parseQuery(query);
+ } catch (Exception e) {
+ answer.setError("Cannot parse language options: " + query);
+ return answer;
+ }
+ }
+
LanguageModel model = languageModel(language);
if (model == null) {
answer.setError("Unknown language " + language);
@@ -1419,6 +1432,17 @@ public abstract class AbstractCamelCatalog {
} catch (Exception e) {
// ignore
}
+ // set options on the language
+ if (options != null) {
+ final Map<String, Object> fOptions = options;
+ final Object fInstance = instance;
+ ReflectionHelper.doWithFields(clazz, field -> {
+ Object value = fOptions.get(field.getName());
+ if (value != null) {
+ ReflectionHelper.setField(field, fInstance, value);
+ }
+ });
+ }
if (clazz != null && instance != null) {
Throwable cause = null;
diff --git a/core/camel-util/src/main/java/org/apache/camel/util/ReflectionHelper.java b/core/camel-util/src/main/java/org/apache/camel/util/ReflectionHelper.java
index 719663f3f6f..649fca93bf2 100644
--- a/core/camel-util/src/main/java/org/apache/camel/util/ReflectionHelper.java
+++ b/core/camel-util/src/main/java/org/apache/camel/util/ReflectionHelper.java
@@ -21,6 +21,8 @@ import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
+import javax.swing.text.Document;
+
/**
* Helper for working with reflection on classes.
* <p/>
@@ -182,7 +184,59 @@ public final class ReflectionHelper {
if (!Modifier.isPublic(f.getModifiers()) && !f.canAccess(instance)) {
f.setAccessible(true);
}
- f.set(instance, value);
+ // must use fine-grained for the correct type when setting a field value via reflection
+ Class<?> type = f.getType();
+ if (boolean.class == type || Boolean.class == type) {
+ boolean val;
+ if (value instanceof Boolean) {
+ val = (boolean) value;
+ } else {
+ val = Boolean.parseBoolean(value.toString());
+ }
+ f.setBoolean(instance, val);
+ } else if (byte.class == type || Byte.class == type) {
+ byte val;
+ if (value instanceof Byte) {
+ val = (byte) value;
+ } else {
+ val = Byte.parseByte(value.toString());
+ }
+ f.setByte(instance, val);
+ } else if (int.class == type || Integer.class == type) {
+ int val;
+ if (value instanceof Integer) {
+ val = (int) value;
+ } else {
+ val = Integer.parseInt(value.toString());
+ }
+ f.setInt(instance, val);
+ } else if (long.class == type || Long.class == type) {
+ long val;
+ if (value instanceof Long) {
+ val = (long) value;
+ } else {
+ val = Long.parseLong(value.toString());
+ }
+ f.setLong(instance, val);
+ } else if (float.class == type || Float.class == type) {
+ float val;
+ if (value instanceof Float) {
+ val = (float) value;
+ } else {
+ val = Float.parseFloat(value.toString());
+ }
+ f.setFloat(instance, val);
+ } else if (double.class == type || Double.class == type) {
+ double val;
+ if (value instanceof Document) {
+ val = (double) value;
+ } else {
+ val = Double.parseDouble(value.toString());
+ }
+ f.setDouble(instance, val);
+ } else {
+ f.set(instance, value);
+ }
} catch (Exception ex) {
throw new UnsupportedOperationException("Cannot inject value of class: " + value.getClass() + " into: " + f);
}