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

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

commit 577a4f173e128e7ffd24884b0c20e2d27fc895dd
Author: Claus Ibsen <claus.ib...@gmail.com>
AuthorDate: Sun Jun 7 22:10:46 2020 +0200

    CAMEL-15155: camel-core - PropertyBindingSupport - Add # syntax to refer to 
property placeholder by id
---
 .../remote/FromFilePasswordPropertyRefTest.java    | 61 ++++++++++++++++++++++
 .../component/properties/PropertiesComponent.java  |  9 +++-
 .../camel/support/PropertyBindingSupportTest.java  | 37 +++++++++++++
 .../camel/support/PropertyBindingSupport.java      | 36 ++++++++++++-
 4 files changed, 139 insertions(+), 4 deletions(-)

diff --git 
a/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/FromFilePasswordPropertyRefTest.java
 
b/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/FromFilePasswordPropertyRefTest.java
new file mode 100644
index 0000000..58101be
--- /dev/null
+++ 
b/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/FromFilePasswordPropertyRefTest.java
@@ -0,0 +1,61 @@
+/*
+ * 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.component.file.remote;
+
+import java.util.Properties;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.junit.jupiter.api.Test;
+
+public class FromFilePasswordPropertyRefTest extends FtpServerTestSupport {
+
+    protected String getFtpUrl() {
+        return "ftp://localhost:"; + getPort() + 
"/tmp3/camel?username=us@r&password=#property:myPass&initialDelay=3000";
+    }
+
+    @Override
+    protected CamelContext createCamelContext() throws Exception {
+        CamelContext context = super.createCamelContext();
+
+        Properties prop = new Properties();
+        prop.setProperty("myPass", "t%st");
+        context.getPropertiesComponent().setInitialProperties(prop);
+
+        return context;
+    }
+
+    @Test
+    public void testFromFileToFtp() throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:result");
+        mock.expectedMessageCount(2);
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            public void configure() throws Exception {
+                from(getFtpUrl()).to("mock:result");
+
+                
from("file:src/main/data?noop=true&delay=3000").to(getFtpUrl());
+            }
+        };
+    }
+}
diff --git 
a/core/camel-base/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java
 
b/core/camel-base/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java
index 36d66f8..1d3151f 100644
--- 
a/core/camel-base/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java
+++ 
b/core/camel-base/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java
@@ -158,8 +158,13 @@ public class PropertiesComponent extends ServiceSupport 
implements org.apache.ca
 
     @Override
     public Optional<String> resolveProperty(String key) {
-        String value = parseUri(key, propertiesLookup);
-        return Optional.of(value);
+        try {
+            String value = parseUri(key, propertiesLookup);
+            return Optional.of(value);
+        } catch (IllegalArgumentException e) {
+            // property not found
+            return Optional.empty();
+        }
     }
 
     @Override
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/support/PropertyBindingSupportTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/support/PropertyBindingSupportTest.java
index 8b96ed1..b115104 100644
--- 
a/core/camel-core/src/test/java/org/apache/camel/support/PropertyBindingSupportTest.java
+++ 
b/core/camel-core/src/test/java/org/apache/camel/support/PropertyBindingSupportTest.java
@@ -24,6 +24,7 @@ import org.apache.camel.CamelContext;
 import org.apache.camel.ContextTestSupport;
 import org.apache.camel.PropertyBindingException;
 import org.apache.camel.spi.Injector;
+import org.apache.camel.spi.PropertiesComponent;
 import org.junit.Test;
 
 /**
@@ -73,6 +74,42 @@ public class PropertyBindingSupportTest extends 
ContextTestSupport {
     }
 
     @Test
+    public void testProperty() throws Exception {
+        PropertiesComponent pc = context.getPropertiesComponent();
+        Properties prop = new Properties();
+        prop.setProperty("customerName", "James");
+        prop.setProperty("customerAge", "33");
+        prop.setProperty("workKey", "customerWork");
+        prop.setProperty("customerWork", "Acme");
+        pc.setInitialProperties(prop);
+
+        Foo foo = new Foo();
+
+        PropertyBindingSupport.build().bind(context, foo, "name", 
"#property:customerName");
+        PropertyBindingSupport.build().bind(context, foo, "bar.age", 
"#property:customerAge");
+        PropertyBindingSupport.build().bind(context, foo, "bar.gold-customer", 
"true");
+        PropertyBindingSupport.build().bind(context, foo, "bar.rider", "true");
+        PropertyBindingSupport.build().bind(context, foo, "bar.work.id", 
"456");
+        PropertyBindingSupport.build().bind(context, foo, "bar.work.name", 
"#property:{{workKey}}");
+
+        assertEquals("James", foo.getName());
+        assertEquals(33, foo.getBar().getAge());
+        assertTrue(foo.getBar().isRider());
+        assertTrue(foo.getBar().isGoldCustomer());
+        assertEquals(456, foo.getBar().getWork().getId());
+        assertEquals("Acme", foo.getBar().getWork().getName());
+
+        try {
+            PropertyBindingSupport.build().bind(context, foo, "name", 
"#property:unknown");
+            fail("Should have thrown exception");
+        } catch (PropertyBindingException e) {
+            assertEquals("name", e.getPropertyName());
+            assertEquals("#property:unknown", e.getValue());
+            assertEquals("Property with key unknown not found by properties 
component", e.getCause().getMessage());
+        }
+    }
+
+    @Test
     public void testWithFluentBuilder() throws Exception {
         Foo foo = new Foo();
 
diff --git 
a/core/camel-support/src/main/java/org/apache/camel/support/PropertyBindingSupport.java
 
b/core/camel-support/src/main/java/org/apache/camel/support/PropertyBindingSupport.java
index ca08ab0..f99d662 100644
--- 
a/core/camel-support/src/main/java/org/apache/camel/support/PropertyBindingSupport.java
+++ 
b/core/camel-support/src/main/java/org/apache/camel/support/PropertyBindingSupport.java
@@ -28,11 +28,13 @@ import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.Component;
 import org.apache.camel.ExtendedCamelContext;
+import org.apache.camel.NoSuchPropertyException;
 import org.apache.camel.PropertyBindingException;
 import org.apache.camel.spi.PropertyConfigurer;
 import org.apache.camel.spi.PropertyConfigurerGetter;
@@ -51,6 +53,7 @@ import static org.apache.camel.util.ObjectHelper.isNotEmpty;
  *     <li>map</li> - Properties can lookup in Map's using map syntax, eg 
foo[bar] where foo is the name of the property that is a Map instance, and bar 
is the name of the key.</li>
  *     <li>list</li> - Properties can refer or add to in List's using list 
syntax, eg foo[0] where foo is the name of the property that is a
  *                     List instance, and 0 is the index. To refer to the last 
element, then use last as key.</li>
+ *     <li>reference by property placeholder id - Values can refer to a 
property placeholder key with #property:myKey</li>
  *     <li>reference by bean id - Values can refer to other beans in the 
registry by prefixing with with # or #bean: eg #myBean or #bean:myBean</li>
  *     <li>reference by type - Values can refer to singleton beans by their 
type in the registry by prefixing with #type: syntax, eg 
#type:com.foo.MyClassType</li>
  *     <li>autowire by type - Values can refer to singleton beans by auto 
wiring by setting the value to #autowired</li>
@@ -639,7 +642,8 @@ public final class PropertyBindingSupport {
     private static Object resolveValue(CamelContext context, Object target, 
String name, Object value,
                                        boolean ignoreCase, boolean 
fluentBuilder, boolean allowPrivateSetter) throws Exception {
         if (value instanceof String) {
-            if (value.toString().equals("#autowired")) {
+            String str = value.toString();
+            if (str.equals("#autowired")) {
                 // we should get the type from the setter
                 Method method = findBestSetterMethod(context, 
target.getClass(), name, fluentBuilder, allowPrivateSetter, ignoreCase);
                 if (method != null) {
@@ -655,6 +659,16 @@ public final class PropertyBindingSupport {
                 } else {
                     throw new IllegalStateException("Cannot find setter method 
with name: " + name + " on class: " + target.getClass().getName() + " to use 
for autowiring");
                 }
+            } else if (str.startsWith("#property:")) {
+                String key = str.substring(10);
+                // the key may have property placeholder so resolve those first
+                key = context.resolvePropertyPlaceholders(key);
+                Optional<String> resolved = 
context.getPropertiesComponent().resolveProperty(key);
+                if (resolved.isPresent()) {
+                    value = resolved.get();
+                } else {
+                    throw new IllegalArgumentException("Property with key " + 
key + " not found by properties component");
+                }
             } else {
                 value = resolveBean(context, name, value);
             }
@@ -856,7 +870,25 @@ public final class PropertyBindingSupport {
      * @return <tt>true</tt> if its a reference parameter
      */
     private static boolean isReferenceParameter(String parameter) {
-        return parameter != null && parameter.trim().startsWith("#");
+        if (parameter == null) {
+            return false;
+        }
+        parameter = parameter.trim();
+        if (!parameter.startsWith("#")) {
+            return false;
+        }
+
+        // non reference parameters are
+        // #bean: #class: #type: #property: #autowired
+        if (parameter.equals("#autowired")
+                || parameter.startsWith("#bean:")
+                || parameter.startsWith("#class:")
+                || parameter.startsWith("#type")
+                || parameter.startsWith("#property")) {
+            return false;
+        }
+
+        return true;
     }
 
     private static Object newInstanceConstructorParameters(CamelContext 
camelContext, Class<?> type, String parameters) throws Exception {

Reply via email to