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

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

commit 11cc91bace56c580952dc16ca98a223e7d98eac8
Author: Claus Ibsen <[email protected]>
AuthorDate: Tue Feb 15 10:47:54 2022 +0100

    CAMEL-17647: camel-core - Properties component should support pluggable 
functions
---
 .../org/apache/camel/properties-function/base64    |  2 +
 .../base64/Base64PropertiesFunction.java           | 35 +++++++++-----
 .../base64/Base64PropertiesFunctionTest.java       | 47 ++++++++++++++++++
 .../properties/PropertiesFunctionResolver.java     | 55 +++++++++++++++++-----
 .../camel/spi/annotations/PropertiesFunction.java  | 25 +++++-----
 5 files changed, 125 insertions(+), 39 deletions(-)

diff --git 
a/components/camel-base64/src/generated/resources/META-INF/services/org/apache/camel/properties-function/base64
 
b/components/camel-base64/src/generated/resources/META-INF/services/org/apache/camel/properties-function/base64
new file mode 100644
index 0000000..bb73781
--- /dev/null
+++ 
b/components/camel-base64/src/generated/resources/META-INF/services/org/apache/camel/properties-function/base64
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.dataformat.base64.Base64PropertiesFunction
diff --git 
a/core/camel-api/src/main/java/org/apache/camel/spi/PropertiesFunctionFactory.java
 
b/components/camel-base64/src/main/java/org/apache/camel/dataformat/base64/Base64PropertiesFunction.java
similarity index 51%
copy from 
core/camel-api/src/main/java/org/apache/camel/spi/PropertiesFunctionFactory.java
copy to 
components/camel-base64/src/main/java/org/apache/camel/dataformat/base64/Base64PropertiesFunction.java
index 1e04d3f..4eedd37 100644
--- 
a/core/camel-api/src/main/java/org/apache/camel/spi/PropertiesFunctionFactory.java
+++ 
b/components/camel-base64/src/main/java/org/apache/camel/dataformat/base64/Base64PropertiesFunction.java
@@ -14,21 +14,30 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.spi;
+package org.apache.camel.dataformat.base64;
 
-/**
- * Pluggable Factory for creating custom {@link PropertiesFunction}.
- */
-public interface PropertiesFunctionFactory {
+import org.apache.camel.spi.PropertiesFunction;
+import org.apache.commons.codec.binary.Base64;
+
[email protected]("base64")
+public class Base64PropertiesFunction implements PropertiesFunction {
+
+    private final int lineLength = Base64.MIME_CHUNK_SIZE;
+    private final byte[] lineSeparator = { '\r', '\n' };
+    private final Base64 codec;
 
-    /**
-     * Service factory key.
-     */
-    String FACTORY = "properties-function";
+    public Base64PropertiesFunction() {
+        this.codec = new Base64(lineLength, lineSeparator, true);
+    }
 
-    /**
-     * Creates the {@link PropertiesFunction}
-     */
-    PropertiesFunction createPropertiesFunction();
+    @Override
+    public String getName() {
+        return "base64";
+    }
 
+    @Override
+    public String apply(String remainder) {
+        byte[] arr = codec.decode(remainder);
+        return new String(arr);
+    }
 }
diff --git 
a/components/camel-base64/src/test/java/org/apache/camel/dataformat/base64/Base64PropertiesFunctionTest.java
 
b/components/camel-base64/src/test/java/org/apache/camel/dataformat/base64/Base64PropertiesFunctionTest.java
new file mode 100644
index 0000000..462c672
--- /dev/null
+++ 
b/components/camel-base64/src/test/java/org/apache/camel/dataformat/base64/Base64PropertiesFunctionTest.java
@@ -0,0 +1,47 @@
+/*
+ * 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.dataformat.base64;
+
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.junit.jupiter.api.Test;
+
+public class Base64PropertiesFunctionTest extends CamelTestSupport {
+
+    @Test
+    public void testBase64() throws Exception {
+        getMockEndpoint("mock:result").expectedBodiesReceived("Hello Camel");
+
+        template.sendBody("direct:start", "Hello");
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Override
+    protected RoutesBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:start")
+                        // Q2FtZWw== is the word Camel
+                        .setBody(simple("${body} {{base64:Q2FtZWw==}}"))
+                        .to("mock:result");
+            }
+        };
+    }
+}
diff --git 
a/core/camel-base/src/main/java/org/apache/camel/component/properties/PropertiesFunctionResolver.java
 
b/core/camel-base/src/main/java/org/apache/camel/component/properties/PropertiesFunctionResolver.java
index f6cff57..ec1d733 100644
--- 
a/core/camel-base/src/main/java/org/apache/camel/component/properties/PropertiesFunctionResolver.java
+++ 
b/core/camel-base/src/main/java/org/apache/camel/component/properties/PropertiesFunctionResolver.java
@@ -24,15 +24,20 @@ import org.apache.camel.CamelContextAware;
 import org.apache.camel.ExtendedCamelContext;
 import org.apache.camel.spi.FactoryFinder;
 import org.apache.camel.spi.PropertiesFunction;
-import org.apache.camel.spi.PropertiesFunctionFactory;
-import org.apache.camel.support.ResolverHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Resolver for built-in and custom {@link PropertiesFunction}.
  */
 public final class PropertiesFunctionResolver implements CamelContextAware {
 
+    public static final String RESOURCE_PATH = 
"META-INF/services/org/apache/camel/properties-function/";
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(PropertiesFunctionResolver.class);
+
     private CamelContext camelContext;
+    private FactoryFinder factoryFinder;
     private final Map<String, PropertiesFunction> functions = new 
LinkedHashMap<>();
 
     public PropertiesFunctionResolver() {
@@ -80,20 +85,44 @@ public final class PropertiesFunctionResolver implements 
CamelContextAware {
     public PropertiesFunction resolvePropertiesFunction(String name) {
         PropertiesFunction answer = functions.get(name);
         if (answer == null) {
-            // it may be a custom function from a 3rd party JAR so use factory 
finder
-            ExtendedCamelContext ecc = 
camelContext.adapt(ExtendedCamelContext.class);
-            FactoryFinder finder = 
ecc.getBootstrapFactoryFinder(PropertiesFunctionFactory.FACTORY);
-
-            PropertiesFunctionFactory factory
-                    = ResolverHelper.resolveService(ecc, finder, name, 
PropertiesFunctionFactory.class).orElse(null);
-            if (factory != null) {
-                answer = factory.createPropertiesFunction();
-                if (answer != null) {
-                    functions.put(name, answer);
-                }
+            answer = resolve(camelContext, name);
+            if (answer != null) {
+                functions.put(name, answer);
             }
         }
         return answer;
     }
 
+    private PropertiesFunction resolve(CamelContext context, String name) {
+        // use factory finder to find a custom implementations
+        Class<?> type = null;
+        try {
+            type = findFactory(name, context);
+        } catch (Exception e) {
+            // ignore
+        }
+
+        if (type != null) {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Found PropertiesFunction: {} via: {}{}", 
type.getName(), factoryFinder.getResourcePath(), name);
+            }
+            if (PropertiesFunction.class.isAssignableFrom(type)) {
+                PropertiesFunction answer = (PropertiesFunction) 
context.getInjector().newInstance(type, false);
+                CamelContextAware.trySetCamelContext(answer, camelContext);
+                return answer;
+            } else {
+                throw new IllegalArgumentException("Type is not a 
PropertiesFunction implementation. Found: " + type.getName());
+            }
+        }
+
+        return null;
+    }
+
+    private Class<?> findFactory(String name, CamelContext context) {
+        if (factoryFinder == null) {
+            factoryFinder = 
context.adapt(ExtendedCamelContext.class).getFactoryFinder(RESOURCE_PATH);
+        }
+        return factoryFinder.findClass(name).orElse(null);
+    }
+
 }
diff --git 
a/core/camel-api/src/main/java/org/apache/camel/spi/PropertiesFunctionFactory.java
 
b/tooling/spi-annotations/src/main/java/org/apache/camel/spi/annotations/PropertiesFunction.java
similarity index 65%
rename from 
core/camel-api/src/main/java/org/apache/camel/spi/PropertiesFunctionFactory.java
rename to 
tooling/spi-annotations/src/main/java/org/apache/camel/spi/annotations/PropertiesFunction.java
index 1e04d3f..7e9e966 100644
--- 
a/core/camel-api/src/main/java/org/apache/camel/spi/PropertiesFunctionFactory.java
+++ 
b/tooling/spi-annotations/src/main/java/org/apache/camel/spi/annotations/PropertiesFunction.java
@@ -14,21 +14,20 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.spi;
+package org.apache.camel.spi.annotations;
 
-/**
- * Pluggable Factory for creating custom {@link PropertiesFunction}.
- */
-public interface PropertiesFunctionFactory {
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
 
-    /**
-     * Service factory key.
-     */
-    String FACTORY = "properties-function";
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Target({ ElementType.TYPE })
+@ServiceFactory("properties-function")
+public @interface PropertiesFunction {
 
-    /**
-     * Creates the {@link PropertiesFunction}
-     */
-    PropertiesFunction createPropertiesFunction();
+    String value();
 
 }

Reply via email to